1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-2001 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
17 #if defined(PLATFORM_FREEBSD)
18 #include <machine/joystick.h>
22 #include "libgame/libgame.h"
31 #if defined(PLATFORM_MSDOS)
32 extern boolean wait_for_vsync;
35 /* tool button identifiers */
36 #define TOOL_CTRL_ID_YES 0
37 #define TOOL_CTRL_ID_NO 1
38 #define TOOL_CTRL_ID_CONFIRM 2
39 #define TOOL_CTRL_ID_PLAYER_1 3
40 #define TOOL_CTRL_ID_PLAYER_2 4
41 #define TOOL_CTRL_ID_PLAYER_3 5
42 #define TOOL_CTRL_ID_PLAYER_4 6
44 #define NUM_TOOL_BUTTONS 7
46 /* forward declaration for internal use */
47 static int getGraphicAnimationPhase(int, int, int);
48 static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
50 static void UnmapToolButtons();
51 static void HandleToolButtons(struct GadgetInfo *);
53 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
54 static int request_gadget_id = -1;
56 void SetDrawtoField(int mode)
58 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
69 drawto_field = fieldbuffer;
71 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
82 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
89 DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
91 if (setup.direct_draw && game_status == PLAYING)
92 redraw_mask &= ~REDRAW_MAIN;
94 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
95 redraw_mask |= REDRAW_FIELD;
97 if (redraw_mask & REDRAW_FIELD)
98 redraw_mask &= ~REDRAW_TILES;
103 if (global.fps_slowdown && game_status == PLAYING)
105 static boolean last_frame_skipped = FALSE;
106 boolean skip_even_when_not_scrolling = TRUE;
107 boolean just_scrolling = (ScreenMovDir != 0);
108 boolean verbose = FALSE;
110 if (global.fps_slowdown_factor > 1 &&
111 (FrameCounter % global.fps_slowdown_factor) &&
112 (just_scrolling || skip_even_when_not_scrolling))
114 redraw_mask &= ~REDRAW_MAIN;
116 last_frame_skipped = TRUE;
119 printf("FRAME SKIPPED\n");
123 if (last_frame_skipped)
124 redraw_mask |= REDRAW_FIELD;
126 last_frame_skipped = FALSE;
129 printf("frame not skipped\n");
133 /* synchronize X11 graphics at this point; if we would synchronize the
134 display immediately after the buffer switching (after the XFlush),
135 this could mean that we have to wait for the graphics to complete,
136 although we could go on doing calculations for the next frame */
140 if (redraw_mask & REDRAW_ALL)
142 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
146 if (redraw_mask & REDRAW_FIELD)
148 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
150 BlitBitmap(backbuffer, window,
151 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
155 int fx = FX, fy = FY;
157 if (setup.soft_scrolling)
159 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
160 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
163 if (setup.soft_scrolling ||
164 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
165 ABS(ScreenMovPos) == ScrollStepSize ||
166 redraw_tiles > REDRAWTILES_THRESHOLD)
168 BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
172 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
174 (setup.soft_scrolling ?
175 "setup.soft_scrolling" :
176 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
177 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
178 ABS(ScreenGfxPos) == ScrollStepSize ?
179 "ABS(ScreenGfxPos) == ScrollStepSize" :
180 "redraw_tiles > REDRAWTILES_THRESHOLD"));
186 redraw_mask &= ~REDRAW_MAIN;
189 if (redraw_mask & REDRAW_DOORS)
191 if (redraw_mask & REDRAW_DOOR_1)
192 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
193 if (redraw_mask & REDRAW_DOOR_2)
195 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
196 BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
199 if (redraw_mask & REDRAW_VIDEO_1)
200 BlitBitmap(backbuffer, window,
201 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
202 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
203 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
204 if (redraw_mask & REDRAW_VIDEO_2)
205 BlitBitmap(backbuffer, window,
206 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
207 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
208 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
209 if (redraw_mask & REDRAW_VIDEO_3)
210 BlitBitmap(backbuffer, window,
211 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
212 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
213 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
216 if (redraw_mask & REDRAW_DOOR_3)
217 BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
218 redraw_mask &= ~REDRAW_DOORS;
221 if (redraw_mask & REDRAW_MICROLEVEL)
223 BlitBitmap(backbuffer, window,
224 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
225 MICROLEV_XPOS, MICROLEV_YPOS);
226 BlitBitmap(backbuffer, window,
227 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
228 SX, MICROLABEL_YPOS);
229 redraw_mask &= ~REDRAW_MICROLEVEL;
232 if (redraw_mask & REDRAW_TILES)
234 for(x=0; x<SCR_FIELDX; x++)
235 for(y=0; y<SCR_FIELDY; y++)
236 if (redraw[redraw_x1 + x][redraw_y1 + y])
237 BlitBitmap(buffer, window,
238 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
239 SX + x * TILEX, SY + y * TILEY);
242 if (redraw_mask & REDRAW_FPS) /* display frames per second */
247 sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
248 if (!global.fps_slowdown)
251 sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
252 DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
257 for(x=0; x<MAX_BUF_XSIZE; x++)
258 for(y=0; y<MAX_BUF_YSIZE; y++)
267 long fading_delay = 300;
269 if (setup.fading && (redraw_mask & REDRAW_FIELD))
276 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
279 for(i=0;i<2*FULL_SYSIZE;i++)
281 for(y=0;y<FULL_SYSIZE;y++)
283 BlitBitmap(backbuffer, window,
284 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
292 for(i=1;i<FULL_SYSIZE;i+=2)
293 BlitBitmap(backbuffer, window,
294 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
300 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
301 BlitBitmapMasked(backbuffer, window,
302 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
307 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
308 BlitBitmapMasked(backbuffer, window,
309 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
314 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
315 BlitBitmapMasked(backbuffer, window,
316 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
321 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
322 BlitBitmapMasked(backbuffer, window,
323 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
328 redraw_mask &= ~REDRAW_MAIN;
337 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
339 if (setup.soft_scrolling && game_status == PLAYING)
341 ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
342 SetDrawtoField(DRAW_BUFFERED);
345 SetDrawtoField(DRAW_BACKBUFFER);
347 if (setup.direct_draw && game_status == PLAYING)
349 ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
350 SetDrawtoField(DRAW_DIRECT);
353 redraw_mask |= REDRAW_FIELD;
356 void MarkTileDirty(int x, int y)
358 int xx = redraw_x1 + x;
359 int yy = redraw_y1 + y;
364 redraw[xx][yy] = TRUE;
365 redraw_mask |= REDRAW_TILES;
368 void SetBorderElement()
372 BorderElement = EL_LEERRAUM;
374 for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
376 for(x=0; x<lev_fieldx; x++)
378 if (!IS_MASSIVE(Feld[x][y]))
379 BorderElement = EL_BETON;
381 if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
387 void DrawAllPlayers()
391 for(i=0; i<MAX_PLAYERS; i++)
392 if (stored_player[i].active)
393 DrawPlayer(&stored_player[i]);
396 void DrawPlayerField(int x, int y)
398 if (!IS_PLAYER(x, y))
401 DrawPlayer(PLAYERINFO(x, y));
404 void DrawPlayer(struct PlayerInfo *player)
406 int jx = player->jx, jy = player->jy;
407 int last_jx = player->last_jx, last_jy = player->last_jy;
408 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
409 int sx = SCREENX(jx), sy = SCREENY(jy);
410 int sxx = 0, syy = 0;
411 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
413 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
415 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
419 if (!IN_LEV_FIELD(jx,jy))
421 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
422 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
423 printf("DrawPlayerField(): This should never happen!\n");
428 if (element == EL_EXPLODING)
431 /* draw things in the field the player is leaving, if needed */
433 if (player_is_moving)
435 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
437 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
438 if (last_element == EL_DYNAMITE_ACTIVE)
439 DrawDynamite(last_jx, last_jy);
441 DrawLevelFieldThruMask(last_jx, last_jy);
443 else if (last_element == EL_DYNAMITE_ACTIVE)
444 DrawDynamite(last_jx, last_jy);
446 DrawLevelField(last_jx, last_jy);
448 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
452 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
453 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
455 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
458 DrawLevelField(next_jx, next_jy);
462 if (!IN_SCR_FIELD(sx, sy))
465 if (setup.direct_draw)
466 SetDrawtoField(DRAW_BUFFERED);
468 /* draw things behind the player, if needed */
471 DrawLevelElement(jx, jy, Store[jx][jy]);
472 else if (!IS_ACTIVE_BOMB(element))
473 DrawLevelField(jx, jy);
475 DrawLevelElement(jx, jy, EL_LEERRAUM);
477 /* draw player himself */
479 if (game.emulation == EMU_SUPAPLEX)
481 static int last_dir = MV_LEFT;
482 int action = (player->programmed_action ? player->programmed_action :
484 boolean action_moving =
486 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
487 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
489 graphic = GFX_SP_MURPHY;
493 if (player->MovDir == MV_LEFT)
494 graphic = GFX_MURPHY_PUSH_LEFT;
495 else if (player->MovDir == MV_RIGHT)
496 graphic = GFX_MURPHY_PUSH_RIGHT;
497 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
498 graphic = GFX_MURPHY_PUSH_LEFT;
499 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
500 graphic = GFX_MURPHY_PUSH_RIGHT;
502 else if (player->snapped)
504 if (player->MovDir == MV_LEFT)
505 graphic = GFX_MURPHY_SNAP_LEFT;
506 else if (player->MovDir == MV_RIGHT)
507 graphic = GFX_MURPHY_SNAP_RIGHT;
508 else if (player->MovDir == MV_UP)
509 graphic = GFX_MURPHY_SNAP_UP;
510 else if (player->MovDir == MV_DOWN)
511 graphic = GFX_MURPHY_SNAP_DOWN;
513 else if (action_moving)
515 if (player->MovDir == MV_LEFT)
516 graphic = GFX_MURPHY_GO_LEFT;
517 else if (player->MovDir == MV_RIGHT)
518 graphic = GFX_MURPHY_GO_RIGHT;
519 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
520 graphic = GFX_MURPHY_GO_LEFT;
521 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
522 graphic = GFX_MURPHY_GO_RIGHT;
524 graphic = GFX_MURPHY_GO_LEFT;
526 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
529 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
530 last_dir = player->MovDir;
534 if (player->MovDir == MV_LEFT)
536 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
537 else if (player->MovDir == MV_RIGHT)
539 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
540 else if (player->MovDir == MV_UP)
541 graphic = GFX_SPIELER1_UP;
542 else /* MV_DOWN || MV_NO_MOVING */
543 graphic = GFX_SPIELER1_DOWN;
545 graphic += player->index_nr * 3 * HEROES_PER_LINE;
546 graphic += player->Frame;
551 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
552 sxx = player->GfxPos;
554 syy = player->GfxPos;
557 if (!setup.soft_scrolling && ScreenMovPos)
560 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
562 if (SHIELD_ON(player))
564 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
565 GFX2_SHIELD_PASSIVE);
567 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
568 3, 8, ANIM_OSCILLATE);
571 if (player->Pushing && player->GfxPos)
573 int px = SCREENX(next_jx), py = SCREENY(next_jy);
575 if (element == EL_SOKOBAN_FELD_LEER ||
576 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
577 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
581 int element = Feld[next_jx][next_jy];
582 int graphic = el2gfx(element);
584 if ((element == EL_FELSBROCKEN ||
585 element == EL_SP_ZONK ||
586 element == EL_BD_ROCK) && sxx)
588 int phase = (player->GfxPos / (TILEX / 4));
590 if (player->MovDir == MV_LEFT)
593 graphic += (phase + 4) % 4;
596 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
600 /* draw things in front of player (active dynamite or dynabombs) */
602 if (IS_ACTIVE_BOMB(element))
604 graphic = el2gfx(element);
606 if (element == EL_DYNAMITE_ACTIVE)
608 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
613 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
617 if (game.emulation == EMU_SUPAPLEX)
618 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
620 DrawGraphicThruMask(sx, sy, graphic + phase);
623 if (player_is_moving && last_element == EL_EXPLODING)
625 int phase = Frame[last_jx][last_jy];
629 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
630 GFX_EXPLOSION + ((phase - 1) / delay - 1));
633 /* draw elements that stay over the player */
634 /* handle the field the player is leaving ... */
635 if (player_is_moving && IS_OVER_PLAYER(last_element))
636 DrawLevelField(last_jx, last_jy);
637 /* ... and the field the player is entering */
638 if (IS_OVER_PLAYER(element))
639 DrawLevelField(jx, jy);
641 if (setup.direct_draw)
643 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
644 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
645 int x_size = TILEX * (1 + ABS(jx - last_jx));
646 int y_size = TILEY * (1 + ABS(jy - last_jy));
648 BlitBitmap(drawto_field, window,
649 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
650 SetDrawtoField(DRAW_DIRECT);
653 MarkTileDirty(sx,sy);
656 static int getGraphicAnimationPhase(int frames, int delay, int mode)
660 if (mode == ANIM_OSCILLATE)
662 int max_anim_frames = 2 * frames - 2;
663 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
664 phase = (phase < frames ? phase : max_anim_frames - phase);
667 phase = (FrameCounter % (delay * frames)) / delay;
669 if (mode == ANIM_REVERSE)
675 void DrawGraphicAnimationExt(int x, int y, int graphic,
676 int frames, int delay, int mode, int mask_mode)
678 int phase = getGraphicAnimationPhase(frames, delay, mode);
680 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
682 if (mask_mode == USE_MASKING)
683 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
685 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
689 void DrawGraphicAnimation(int x, int y, int graphic,
690 int frames, int delay, int mode)
692 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
695 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
696 int frames, int delay, int mode)
698 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
701 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
704 int frames, int delay,
707 int phase = getGraphicAnimationPhase(frames, delay, mode);
709 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
712 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
714 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
716 graphic -= GFX_START_ROCKSSCREEN;
717 *bitmap_nr = PIX_BACK;
718 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
719 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
721 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
723 graphic -= GFX_START_ROCKSHEROES;
724 *bitmap_nr = PIX_HEROES;
725 *x = (graphic % HEROES_PER_LINE) * TILEX;
726 *y = (graphic / HEROES_PER_LINE) * TILEY;
728 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
730 graphic -= GFX_START_ROCKSSP;
732 *x = (graphic % SP_PER_LINE) * TILEX;
733 *y = (graphic / SP_PER_LINE) * TILEY;
735 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
737 graphic -= GFX_START_ROCKSDC;
739 *x = (graphic % DC_PER_LINE) * TILEX;
740 *y = (graphic / DC_PER_LINE) * TILEY;
742 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
744 graphic -= GFX_START_ROCKSMORE;
745 *bitmap_nr = PIX_MORE;
746 *x = (graphic % MORE_PER_LINE) * TILEX;
747 *y = (graphic / MORE_PER_LINE) * TILEY;
749 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
751 graphic -= GFX_START_ROCKSFONT;
752 *bitmap_nr = PIX_BIGFONT;
753 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
754 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
755 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
765 void DrawGraphic(int x, int y, int graphic)
768 if (!IN_SCR_FIELD(x,y))
770 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
771 printf("DrawGraphic(): This should never happen!\n");
776 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
780 void DrawGraphicExt(DrawBuffer *bitmap, int x, int y, int graphic)
785 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
786 BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
789 void DrawGraphicThruMask(int x, int y, int graphic)
792 if (!IN_SCR_FIELD(x,y))
794 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
795 printf("DrawGraphicThruMask(): This should never happen!\n");
800 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
804 void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
812 if (graphic == GFX_LEERRAUM)
815 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
816 src_bitmap = pix[bitmap_nr];
817 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
819 if (tile_clipmask[tile] != None)
821 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
822 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
823 BlitBitmapMasked(src_bitmap, d,
824 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
830 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
834 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
835 BlitBitmapMasked(src_bitmap, d,
836 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
840 void DrawMiniGraphic(int x, int y, int graphic)
842 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
843 MarkTileDirty(x/2, y/2);
846 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
848 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
850 graphic -= GFX_START_ROCKSSCREEN;
851 *bitmap = pix[PIX_BACK];
852 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
853 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
855 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
857 graphic -= GFX_START_ROCKSSP;
858 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
859 *bitmap = pix[PIX_SP];
860 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
861 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
863 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
865 graphic -= GFX_START_ROCKSDC;
866 *bitmap = pix[PIX_DC];
867 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
868 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
870 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
872 graphic -= GFX_START_ROCKSMORE;
873 *bitmap = pix[PIX_MORE];
874 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
875 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
877 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
879 graphic -= GFX_START_ROCKSFONT;
880 *bitmap = pix[PIX_SMALLFONT];
881 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
882 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
883 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
887 *bitmap = pix[PIX_SP];
893 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
898 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
899 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
902 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
903 int cut_mode, int mask_mode)
905 int width = TILEX, height = TILEY;
907 int src_x, src_y, dest_x, dest_y;
915 DrawGraphic(x, y, graphic);
919 if (dx || dy) /* Verschiebung der Grafik? */
921 if (x < BX1) /* Element kommt von links ins Bild */
928 else if (x > BX2) /* Element kommt von rechts ins Bild */
934 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
940 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
942 else if (dx) /* allg. Bewegung in x-Richtung */
943 MarkTileDirty(x + SIGN(dx), y);
945 if (y < BY1) /* Element kommt von oben ins Bild */
947 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
955 else if (y > BY2) /* Element kommt von unten ins Bild */
961 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
967 else if (dy > 0 && cut_mode == CUT_ABOVE)
969 if (y == BY2) /* Element unterhalb des Bildes */
975 MarkTileDirty(x, y + 1);
976 } /* Element verläßt unten das Bild */
977 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
979 else if (dy) /* allg. Bewegung in y-Richtung */
980 MarkTileDirty(x, y + SIGN(dy));
983 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
984 src_bitmap = pix[bitmap_nr];
985 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
990 dest_x = FX + x * TILEX + dx;
991 dest_y = FY + y * TILEY + dy;
994 if (!IN_SCR_FIELD(x,y))
996 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
997 printf("DrawGraphicShifted(): This should never happen!\n");
1002 if (mask_mode == USE_MASKING)
1004 if (tile_clipmask[tile] != None)
1006 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1007 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1008 BlitBitmapMasked(src_bitmap, drawto_field,
1009 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1015 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1019 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1020 BlitBitmapMasked(src_bitmap, drawto_field,
1021 src_x, src_y, width, height, dest_x, dest_y);
1025 BlitBitmap(pix[bitmap_nr], drawto_field,
1026 src_x, src_y, width, height, dest_x, dest_y);
1031 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1034 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1037 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1038 int cut_mode, int mask_mode)
1040 int ux = LEVELX(x), uy = LEVELY(y);
1041 int graphic = el2gfx(element);
1042 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1043 int phase4 = phase8 / 2;
1044 int phase2 = phase8 / 4;
1045 int dir = MovDir[ux][uy];
1047 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1049 graphic += 4 * !phase2;
1053 else if (dir == MV_LEFT)
1055 else if (dir == MV_DOWN)
1058 else if (element == EL_SP_SNIKSNAK)
1061 graphic = GFX_SP_SNIKSNAK_LEFT;
1062 else if (dir == MV_RIGHT)
1063 graphic = GFX_SP_SNIKSNAK_RIGHT;
1064 else if (dir == MV_UP)
1065 graphic = GFX_SP_SNIKSNAK_UP;
1067 graphic = GFX_SP_SNIKSNAK_DOWN;
1069 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1071 else if (element == EL_SP_ELECTRON)
1073 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1075 else if (element == EL_MOLE || element == EL_PINGUIN ||
1076 element == EL_SCHWEIN || element == EL_DRACHE)
1079 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1080 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1081 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1082 else if (dir == MV_RIGHT)
1083 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1084 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1085 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1086 else if (dir == MV_UP)
1087 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1088 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1089 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1091 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1092 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1093 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1097 else if (element == EL_SONDE)
1099 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1101 else if (element == EL_SALZSAEURE)
1103 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1105 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1109 else if (element == EL_BALLOON)
1113 else if ((element == EL_FELSBROCKEN ||
1114 element == EL_SP_ZONK ||
1115 element == EL_BD_ROCK ||
1116 element == EL_SP_INFOTRON ||
1120 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1122 if (element == EL_FELSBROCKEN ||
1123 element == EL_SP_ZONK ||
1124 element == EL_BD_ROCK)
1127 graphic += (4 - phase4) % 4;
1128 else if (dir == MV_RIGHT)
1131 graphic += phase2 * 2;
1133 else if (element != EL_SP_INFOTRON)
1137 else if (element == EL_MAGIC_WALL_EMPTY ||
1138 element == EL_MAGIC_WALL_EMPTYING ||
1139 element == EL_MAGIC_WALL_BD_EMPTY ||
1140 element == EL_MAGIC_WALL_BD_EMPTYING ||
1141 element == EL_MAGIC_WALL_FULL ||
1142 element == EL_MAGIC_WALL_BD_FULL)
1144 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1146 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1148 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1149 graphic += (x + 2 * y + 4) % 4;
1151 else if (element == EL_MAUER_LEBT)
1153 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1155 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1156 links_massiv = TRUE;
1157 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1158 rechts_massiv = TRUE;
1160 if (links_massiv && rechts_massiv)
1161 graphic = GFX_MAUERWERK;
1162 else if (links_massiv)
1163 graphic = GFX_MAUER_R;
1164 else if (rechts_massiv)
1165 graphic = GFX_MAUER_L;
1167 else if ((element == EL_INVISIBLE_STEEL ||
1168 element == EL_UNSICHTBAR ||
1169 element == EL_SAND_INVISIBLE) && game.light_time_left)
1171 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1172 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1173 GFX_SAND_INVISIBLE_ON);
1177 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1178 else if (mask_mode == USE_MASKING)
1179 DrawGraphicThruMask(x, y, graphic);
1181 DrawGraphic(x, y, graphic);
1184 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1185 int cut_mode, int mask_mode)
1187 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1188 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1189 cut_mode, mask_mode);
1192 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1195 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1198 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1201 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1204 void DrawScreenElementThruMask(int x, int y, int element)
1206 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1209 void DrawLevelElementThruMask(int x, int y, int element)
1211 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1214 void DrawLevelFieldThruMask(int x, int y)
1216 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1219 void ErdreichAnbroeckeln(int x, int y)
1221 int i, width, height, cx,cy;
1222 int ux = LEVELX(x), uy = LEVELY(y);
1223 int element, graphic;
1225 static int xy[4][2] =
1233 if (!IN_LEV_FIELD(ux, uy))
1236 element = Feld[ux][uy];
1238 if (element == EL_ERDREICH ||
1239 element == EL_LANDMINE ||
1240 element == EL_TRAP_INACTIVE ||
1241 element == EL_TRAP_ACTIVE)
1243 if (!IN_SCR_FIELD(x, y))
1246 graphic = GFX_ERDENRAND;
1252 uxx = ux + xy[i][0];
1253 uyy = uy + xy[i][1];
1254 if (!IN_LEV_FIELD(uxx, uyy))
1257 element = Feld[uxx][uyy];
1259 if (element == EL_ERDREICH ||
1260 element == EL_LANDMINE ||
1261 element == EL_TRAP_INACTIVE ||
1262 element == EL_TRAP_ACTIVE)
1265 if (i == 1 || i == 2)
1269 cx = (i == 2 ? TILEX - snip : 0);
1277 cy = (i == 3 ? TILEY - snip : 0);
1280 BlitBitmap(pix[PIX_BACK], drawto_field,
1281 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1282 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1283 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1286 MarkTileDirty(x, y);
1290 graphic = GFX_ERDENRAND;
1294 int xx, yy, uxx, uyy;
1298 uxx = ux + xy[i][0];
1299 uyy = uy + xy[i][1];
1301 if (!IN_LEV_FIELD(uxx, uyy) ||
1302 (Feld[uxx][uyy] != EL_ERDREICH &&
1303 Feld[uxx][uyy] != EL_LANDMINE &&
1304 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1305 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1306 !IN_SCR_FIELD(xx, yy))
1309 if (i == 1 || i == 2)
1313 cx = (i == 1 ? TILEX - snip : 0);
1321 cy = (i==0 ? TILEY-snip : 0);
1324 BlitBitmap(pix[PIX_BACK], drawto_field,
1325 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1326 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1327 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1329 MarkTileDirty(xx, yy);
1334 void DrawScreenElement(int x, int y, int element)
1336 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1337 ErdreichAnbroeckeln(x, y);
1340 void DrawLevelElement(int x, int y, int element)
1342 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1343 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1346 void DrawScreenField(int x, int y)
1348 int ux = LEVELX(x), uy = LEVELY(y);
1349 int element, content;
1351 if (!IN_LEV_FIELD(ux, uy))
1353 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1354 element = EL_LEERRAUM;
1356 element = BorderElement;
1358 DrawScreenElement(x, y, element);
1362 element = Feld[ux][uy];
1363 content = Store[ux][uy];
1365 if (IS_MOVING(ux, uy))
1367 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1368 boolean cut_mode = NO_CUTTING;
1370 if (element == EL_QUICKSAND_EMPTYING ||
1371 element == EL_MAGIC_WALL_EMPTYING ||
1372 element == EL_MAGIC_WALL_BD_EMPTYING ||
1373 element == EL_AMOEBA_DRIPPING)
1374 cut_mode = CUT_ABOVE;
1375 else if (element == EL_QUICKSAND_FILLING ||
1376 element == EL_MAGIC_WALL_FILLING ||
1377 element == EL_MAGIC_WALL_BD_FILLING)
1378 cut_mode = CUT_BELOW;
1380 if (cut_mode == CUT_ABOVE)
1381 DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1383 DrawScreenElement(x, y, EL_LEERRAUM);
1386 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1387 else if (cut_mode == NO_CUTTING)
1388 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1390 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1392 if (content == EL_SALZSAEURE)
1393 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1395 else if (IS_BLOCKED(ux, uy))
1400 boolean cut_mode = NO_CUTTING;
1401 int element_old, content_old;
1403 Blocked2Moving(ux, uy, &oldx, &oldy);
1406 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1407 MovDir[oldx][oldy] == MV_RIGHT);
1409 element_old = Feld[oldx][oldy];
1410 content_old = Store[oldx][oldy];
1412 if (element_old == EL_QUICKSAND_EMPTYING ||
1413 element_old == EL_MAGIC_WALL_EMPTYING ||
1414 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1415 element_old == EL_AMOEBA_DRIPPING)
1416 cut_mode = CUT_ABOVE;
1418 DrawScreenElement(x, y, EL_LEERRAUM);
1421 DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1423 else if (cut_mode == NO_CUTTING)
1424 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1427 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
1430 else if (IS_DRAWABLE(element))
1431 DrawScreenElement(x, y, element);
1433 DrawScreenElement(x, y, EL_LEERRAUM);
1436 void DrawLevelField(int x, int y)
1438 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1439 DrawScreenField(SCREENX(x), SCREENY(y));
1440 else if (IS_MOVING(x, y))
1444 Moving2Blocked(x, y, &newx, &newy);
1445 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1446 DrawScreenField(SCREENX(newx), SCREENY(newy));
1448 else if (IS_BLOCKED(x, y))
1452 Blocked2Moving(x, y, &oldx, &oldy);
1453 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1454 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1458 void DrawMiniElement(int x, int y, int element)
1464 DrawMiniGraphic(x, y, -1);
1468 graphic = el2gfx(element);
1469 DrawMiniGraphic(x, y, graphic);
1472 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1474 int x = sx + scroll_x, y = sy + scroll_y;
1476 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1477 DrawMiniElement(sx, sy, EL_LEERRAUM);
1478 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1479 DrawMiniElement(sx, sy, Feld[x][y]);
1482 int steel_type, steel_position;
1485 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1486 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1487 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1488 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1489 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1490 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1493 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1494 steel_position = (x == -1 && y == -1 ? 0 :
1495 x == lev_fieldx && y == -1 ? 1 :
1496 x == -1 && y == lev_fieldy ? 2 :
1497 x == lev_fieldx && y == lev_fieldy ? 3 :
1498 x == -1 || x == lev_fieldx ? 4 :
1499 y == -1 || y == lev_fieldy ? 5 : -1);
1501 if (steel_position != -1)
1502 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1506 void DrawMicroElement(int xpos, int ypos, int element)
1510 if (element == EL_LEERRAUM)
1513 graphic = el2gfx(element);
1515 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1517 graphic -= GFX_START_ROCKSSP;
1518 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1519 BlitBitmap(pix[PIX_SP], drawto,
1520 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1521 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1522 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1524 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1526 graphic -= GFX_START_ROCKSDC;
1527 BlitBitmap(pix[PIX_DC], drawto,
1528 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1529 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1530 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1532 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1534 graphic -= GFX_START_ROCKSMORE;
1535 BlitBitmap(pix[PIX_MORE], drawto,
1536 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1537 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1538 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1541 BlitBitmap(pix[PIX_BACK], drawto,
1542 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1543 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1544 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1553 for(x=BX1; x<=BX2; x++)
1554 for(y=BY1; y<=BY2; y++)
1555 DrawScreenField(x, y);
1557 redraw_mask |= REDRAW_FIELD;
1560 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1564 for(x=0; x<size_x; x++)
1565 for(y=0; y<size_y; y++)
1566 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1568 redraw_mask |= REDRAW_FIELD;
1571 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1575 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1577 if (lev_fieldx < STD_LEV_FIELDX)
1578 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1579 if (lev_fieldy < STD_LEV_FIELDY)
1580 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1582 xpos += MICRO_TILEX;
1583 ypos += MICRO_TILEY;
1585 for(x=-1; x<=STD_LEV_FIELDX; x++)
1587 for(y=-1; y<=STD_LEV_FIELDY; y++)
1589 int lx = from_x + x, ly = from_y + y;
1591 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1592 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1594 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1595 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1600 redraw_mask |= REDRAW_MICROLEVEL;
1603 #define MICROLABEL_EMPTY 0
1604 #define MICROLABEL_LEVEL_NAME 1
1605 #define MICROLABEL_CREATED_BY 2
1606 #define MICROLABEL_LEVEL_AUTHOR 3
1607 #define MICROLABEL_IMPORTED_FROM 4
1608 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1610 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1612 static void DrawMicroLevelLabelExt(int mode)
1614 char label_text[MAX_MICROLABEL_SIZE + 1];
1616 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1618 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1619 mode == MICROLABEL_CREATED_BY ? "created by" :
1620 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1621 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1622 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1623 leveldir_current->imported_from : ""),
1624 MAX_MICROLABEL_SIZE);
1625 label_text[MAX_MICROLABEL_SIZE] = '\0';
1627 if (strlen(label_text) > 0)
1629 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1630 int lypos = MICROLABEL_YPOS;
1632 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1635 redraw_mask |= REDRAW_MICROLEVEL;
1638 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1640 static unsigned long scroll_delay = 0;
1641 static unsigned long label_delay = 0;
1642 static int from_x, from_y, scroll_direction;
1643 static int label_state, label_counter;
1647 from_x = from_y = 0;
1648 scroll_direction = MV_RIGHT;
1652 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1653 DrawMicroLevelLabelExt(label_state);
1655 /* initialize delay counters */
1656 DelayReached(&scroll_delay, 0);
1657 DelayReached(&label_delay, 0);
1662 /* scroll micro level, if needed */
1663 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1664 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1666 switch (scroll_direction)
1672 scroll_direction = MV_UP;
1676 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1679 scroll_direction = MV_DOWN;
1686 scroll_direction = MV_RIGHT;
1690 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1693 scroll_direction = MV_LEFT;
1700 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1703 /* redraw micro level label, if needed */
1704 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1705 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1706 strcmp(level.author, leveldir_current->name) != 0 &&
1707 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1709 int max_label_counter = 23;
1711 if (leveldir_current->imported_from != NULL)
1712 max_label_counter += 14;
1714 label_counter = (label_counter + 1) % max_label_counter;
1715 label_state = (label_counter >= 0 && label_counter <= 7 ?
1716 MICROLABEL_LEVEL_NAME :
1717 label_counter >= 9 && label_counter <= 12 ?
1718 MICROLABEL_CREATED_BY :
1719 label_counter >= 14 && label_counter <= 21 ?
1720 MICROLABEL_LEVEL_AUTHOR :
1721 label_counter >= 23 && label_counter <= 26 ?
1722 MICROLABEL_IMPORTED_FROM :
1723 label_counter >= 28 && label_counter <= 35 ?
1724 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1725 DrawMicroLevelLabelExt(label_state);
1729 int REQ_in_range(int x, int y)
1731 if (y > DY+249 && y < DY+278)
1733 if (x > DX+1 && x < DX+48)
1735 else if (x > DX+51 && x < DX+98)
1741 boolean Request(char *text, unsigned int req_state)
1743 int mx, my, ty, result = -1;
1744 unsigned int old_door_state;
1746 #if defined(PLATFORM_UNIX)
1747 /* pause network game while waiting for request to answer */
1748 if (options.network &&
1749 game_status == PLAYING &&
1750 req_state & REQUEST_WAIT_FOR)
1751 SendToServer_PausePlaying();
1754 old_door_state = GetDoorState();
1758 CloseDoor(DOOR_CLOSE_1);
1760 /* save old door content */
1761 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1762 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1763 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1765 /* clear door drawing field */
1766 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1768 /* write text for request */
1769 for(ty=0; ty<13; ty++)
1777 for(tl=0,tx=0; tx<7; tl++,tx++)
1780 if (!tc || tc == 32)
1791 DrawTextExt(drawto, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1792 txt, FS_SMALL, FC_YELLOW);
1793 text += tl + (tc == 32 ? 1 : 0);
1796 if (req_state & REQ_ASK)
1798 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1799 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1801 else if (req_state & REQ_CONFIRM)
1803 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1805 else if (req_state & REQ_PLAYER)
1807 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1808 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1809 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1810 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1813 /* copy request gadgets to door backbuffer */
1814 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1815 DX, DY, DXSIZE, DYSIZE,
1816 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1818 OpenDoor(DOOR_OPEN_1);
1824 if (!(req_state & REQUEST_WAIT_FOR))
1827 if (game_status != MAINMENU)
1830 button_status = MB_RELEASED;
1832 request_gadget_id = -1;
1844 case EVENT_BUTTONPRESS:
1845 case EVENT_BUTTONRELEASE:
1846 case EVENT_MOTIONNOTIFY:
1848 if (event.type == EVENT_MOTIONNOTIFY)
1850 if (!PointerInWindow(window))
1851 continue; /* window and pointer are on different screens */
1856 motion_status = TRUE;
1857 mx = ((MotionEvent *) &event)->x;
1858 my = ((MotionEvent *) &event)->y;
1862 motion_status = FALSE;
1863 mx = ((ButtonEvent *) &event)->x;
1864 my = ((ButtonEvent *) &event)->y;
1865 if (event.type == EVENT_BUTTONPRESS)
1866 button_status = ((ButtonEvent *) &event)->button;
1868 button_status = MB_RELEASED;
1871 /* this sets 'request_gadget_id' */
1872 HandleGadgets(mx, my, button_status);
1874 switch(request_gadget_id)
1876 case TOOL_CTRL_ID_YES:
1879 case TOOL_CTRL_ID_NO:
1882 case TOOL_CTRL_ID_CONFIRM:
1883 result = TRUE | FALSE;
1886 case TOOL_CTRL_ID_PLAYER_1:
1889 case TOOL_CTRL_ID_PLAYER_2:
1892 case TOOL_CTRL_ID_PLAYER_3:
1895 case TOOL_CTRL_ID_PLAYER_4:
1906 case EVENT_KEYPRESS:
1907 switch(GetEventKey((KeyEvent *)&event, TRUE))
1920 if (req_state & REQ_PLAYER)
1924 case EVENT_KEYRELEASE:
1925 key_joystick_mapping = 0;
1929 HandleOtherEvents(&event);
1933 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1935 int joy = AnyJoystick();
1937 if (joy & JOY_BUTTON_1)
1939 else if (joy & JOY_BUTTON_2)
1945 /* don't eat all CPU time */
1949 if (game_status != MAINMENU)
1954 if (!(req_state & REQ_STAY_OPEN))
1956 CloseDoor(DOOR_CLOSE_1);
1958 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1960 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1961 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1962 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1963 OpenDoor(DOOR_OPEN_1);
1969 #if defined(PLATFORM_UNIX)
1970 /* continue network game after request */
1971 if (options.network &&
1972 game_status == PLAYING &&
1973 req_state & REQUEST_WAIT_FOR)
1974 SendToServer_ContinuePlaying();
1980 unsigned int OpenDoor(unsigned int door_state)
1982 unsigned int new_door_state;
1984 if (door_state & DOOR_COPY_BACK)
1986 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1987 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
1988 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1989 door_state &= ~DOOR_COPY_BACK;
1992 new_door_state = MoveDoor(door_state);
1994 return(new_door_state);
1997 unsigned int CloseDoor(unsigned int door_state)
1999 unsigned int new_door_state;
2001 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2002 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2003 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2004 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2006 new_door_state = MoveDoor(door_state);
2008 return(new_door_state);
2011 unsigned int GetDoorState()
2013 return(MoveDoor(DOOR_GET_STATE));
2016 unsigned int MoveDoor(unsigned int door_state)
2018 static int door1 = DOOR_OPEN_1;
2019 static int door2 = DOOR_CLOSE_2;
2020 static unsigned long door_delay = 0;
2021 int x, start, stepsize = 2;
2022 unsigned long door_delay_value = stepsize * 5;
2024 if (door_state == DOOR_GET_STATE)
2025 return(door1 | door2);
2027 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2028 door_state &= ~DOOR_OPEN_1;
2029 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2030 door_state &= ~DOOR_CLOSE_1;
2031 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2032 door_state &= ~DOOR_OPEN_2;
2033 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2034 door_state &= ~DOOR_CLOSE_2;
2036 if (setup.quick_doors)
2039 door_delay_value = 0;
2040 StopSound(SND_OEFFNEN);
2043 if (door_state & DOOR_ACTION)
2045 if (!(door_state & DOOR_NO_DELAY))
2046 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2048 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2050 for(x=start; x<=DXSIZE; x+=stepsize)
2052 Bitmap *bitmap = pix[PIX_DOOR];
2053 GC gc = bitmap->stored_clip_gc;
2055 WaitUntilDelayReached(&door_delay, door_delay_value);
2057 if (door_state & DOOR_ACTION_1)
2059 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2060 int j = (DXSIZE - i) / 3;
2062 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2063 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2064 DXSIZE,DYSIZE - i/2, DX, DY);
2066 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2068 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2069 BlitBitmapMasked(bitmap, drawto,
2070 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2071 DX + DXSIZE - i, DY + j);
2072 BlitBitmapMasked(bitmap, drawto,
2073 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2074 DX + DXSIZE - i, DY + 140 + j);
2075 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2076 BlitBitmapMasked(bitmap, drawto,
2077 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2079 BlitBitmapMasked(bitmap, drawto,
2080 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2083 BlitBitmapMasked(bitmap, drawto,
2084 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2086 BlitBitmapMasked(bitmap, drawto,
2087 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2089 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2090 BlitBitmapMasked(bitmap, drawto,
2091 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2092 DX + DXSIZE - i, DY + 77 + j);
2093 BlitBitmapMasked(bitmap, drawto,
2094 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2095 DX + DXSIZE - i, DY + 203 + j);
2097 redraw_mask |= REDRAW_DOOR_1;
2100 if (door_state & DOOR_ACTION_2)
2102 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2103 int j = (VXSIZE - i) / 3;
2105 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2106 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2107 VXSIZE, VYSIZE - i/2, VX, VY);
2109 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2111 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2112 BlitBitmapMasked(bitmap, drawto,
2113 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2114 VX + VXSIZE-i, VY+j);
2115 SetClipOrigin(bitmap, gc,
2116 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2117 BlitBitmapMasked(bitmap, drawto,
2118 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2121 BlitBitmapMasked(bitmap, drawto,
2122 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2123 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2124 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2125 BlitBitmapMasked(bitmap, drawto,
2126 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2128 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2130 redraw_mask |= REDRAW_DOOR_2;
2135 if (game_status == MAINMENU)
2140 if (setup.quick_doors)
2141 StopSound(SND_OEFFNEN);
2143 if (door_state & DOOR_ACTION_1)
2144 door1 = door_state & DOOR_ACTION_1;
2145 if (door_state & DOOR_ACTION_2)
2146 door2 = door_state & DOOR_ACTION_2;
2148 return (door1 | door2);
2151 void DrawSpecialEditorDoor()
2153 /* draw bigger toolbox window */
2154 BlitBitmap(pix[PIX_DOOR], drawto,
2155 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2157 redraw_mask |= REDRAW_ALL;
2160 void UndrawSpecialEditorDoor()
2162 /* draw normal tape recorder window */
2163 BlitBitmap(pix[PIX_BACK], drawto,
2164 562, 344, 108, 56, EX - 4, EY - 12);
2166 redraw_mask |= REDRAW_ALL;
2170 int ReadPixel(DrawBuffer *bitmap, int x, int y)
2172 XImage *pixel_image;
2173 unsigned long pixel_value;
2175 pixel_image = XGetImage(display, bitmap->drawable,
2176 x, y, 1, 1, AllPlanes, ZPixmap);
2177 pixel_value = XGetPixel(pixel_image, 0, 0);
2179 XDestroyImage(pixel_image);
2185 /* ---------- new tool button stuff ---------------------------------------- */
2187 /* graphic position values for tool buttons */
2188 #define TOOL_BUTTON_YES_XPOS 2
2189 #define TOOL_BUTTON_YES_YPOS 250
2190 #define TOOL_BUTTON_YES_GFX_YPOS 0
2191 #define TOOL_BUTTON_YES_XSIZE 46
2192 #define TOOL_BUTTON_YES_YSIZE 28
2193 #define TOOL_BUTTON_NO_XPOS 52
2194 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2195 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2196 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2197 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2198 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2199 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2200 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2201 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2202 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2203 #define TOOL_BUTTON_PLAYER_XSIZE 30
2204 #define TOOL_BUTTON_PLAYER_YSIZE 30
2205 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2206 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2207 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2208 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2209 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2210 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2211 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2212 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2213 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2214 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2215 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2216 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2217 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2218 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2219 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2220 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2221 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2222 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2223 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2224 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2233 } toolbutton_info[NUM_TOOL_BUTTONS] =
2236 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2237 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2238 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2243 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2244 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2245 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2250 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2251 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2252 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2253 TOOL_CTRL_ID_CONFIRM,
2257 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2258 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2259 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2260 TOOL_CTRL_ID_PLAYER_1,
2264 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2265 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2266 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2267 TOOL_CTRL_ID_PLAYER_2,
2271 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2272 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2273 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2274 TOOL_CTRL_ID_PLAYER_3,
2278 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2279 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2280 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2281 TOOL_CTRL_ID_PLAYER_4,
2286 void CreateToolButtons()
2290 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2292 Bitmap *gd_bitmap = pix[PIX_DOOR];
2293 Bitmap *deco_bitmap = None;
2294 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2295 struct GadgetInfo *gi;
2296 unsigned long event_mask;
2297 int gd_xoffset, gd_yoffset;
2298 int gd_x1, gd_x2, gd_y;
2301 event_mask = GD_EVENT_RELEASED;
2303 gd_xoffset = toolbutton_info[i].xpos;
2304 gd_yoffset = toolbutton_info[i].ypos;
2305 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2306 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2307 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2309 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2311 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2312 &deco_bitmap, &deco_x, &deco_y);
2313 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2314 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2317 gi = CreateGadget(GDI_CUSTOM_ID, id,
2318 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2319 GDI_X, DX + toolbutton_info[i].x,
2320 GDI_Y, DY + toolbutton_info[i].y,
2321 GDI_WIDTH, toolbutton_info[i].width,
2322 GDI_HEIGHT, toolbutton_info[i].height,
2323 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2324 GDI_STATE, GD_BUTTON_UNPRESSED,
2325 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2326 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2327 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2328 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2329 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2330 GDI_DECORATION_SHIFTING, 1, 1,
2331 GDI_EVENT_MASK, event_mask,
2332 GDI_CALLBACK_ACTION, HandleToolButtons,
2336 Error(ERR_EXIT, "cannot create gadget");
2338 tool_gadget[id] = gi;
2342 static void UnmapToolButtons()
2346 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2347 UnmapGadget(tool_gadget[i]);
2350 static void HandleToolButtons(struct GadgetInfo *gi)
2352 request_gadget_id = gi->custom_id;
2355 int get_next_element(int element)
2359 case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
2360 case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
2361 case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
2362 case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
2363 case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
2364 case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
2365 case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
2367 default: return element;
2371 int el2gfx(int element)
2375 case EL_LEERRAUM: return -1;
2376 case EL_ERDREICH: return GFX_ERDREICH;
2377 case EL_MAUERWERK: return GFX_MAUERWERK;
2378 case EL_FELSBODEN: return GFX_FELSBODEN;
2379 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2380 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2381 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2382 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2383 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2384 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2385 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2386 case EL_SPIELER1: return GFX_SPIELER1;
2387 case EL_SPIELER2: return GFX_SPIELER2;
2388 case EL_SPIELER3: return GFX_SPIELER3;
2389 case EL_SPIELER4: return GFX_SPIELER4;
2390 case EL_KAEFER: return GFX_KAEFER;
2391 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2392 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2393 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2394 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2395 case EL_FLIEGER: return GFX_FLIEGER;
2396 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2397 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2398 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2399 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2400 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2401 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2402 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2403 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2404 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2405 case EL_FIREFLY: return GFX_FIREFLY;
2406 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2407 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2408 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2409 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2410 case EL_MAMPFER: return GFX_MAMPFER;
2411 case EL_ROBOT: return GFX_ROBOT;
2412 case EL_BETON: return GFX_BETON;
2413 case EL_DIAMANT: return GFX_DIAMANT;
2414 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2415 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2416 case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
2417 case EL_TROPFEN: return GFX_TROPFEN;
2418 case EL_BOMBE: return GFX_BOMBE;
2419 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2420 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2421 case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
2422 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2423 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2424 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2425 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2426 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2427 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2428 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2429 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2430 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2431 case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
2432 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2433 case EL_LIFE: return GFX_LIFE;
2434 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2435 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2436 case EL_BADEWANNE: return GFX_BADEWANNE;
2437 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2438 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2439 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2440 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2441 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2442 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2443 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2444 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2445 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2446 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2447 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2448 case EL_PFORTE1: return GFX_PFORTE1;
2449 case EL_PFORTE2: return GFX_PFORTE2;
2450 case EL_PFORTE3: return GFX_PFORTE3;
2451 case EL_PFORTE4: return GFX_PFORTE4;
2452 case EL_PFORTE1X: return GFX_PFORTE1X;
2453 case EL_PFORTE2X: return GFX_PFORTE2X;
2454 case EL_PFORTE3X: return GFX_PFORTE3X;
2455 case EL_PFORTE4X: return GFX_PFORTE4X;
2456 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2457 case EL_PACMAN: return GFX_PACMAN;
2458 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2459 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2460 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2461 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2462 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2463 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2464 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2465 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2466 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2467 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2468 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2469 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2470 case EL_MAUER_X: return GFX_MAUER_X;
2471 case EL_MAUER_Y: return GFX_MAUER_Y;
2472 case EL_MAUER_XY: return GFX_MAUER_XY;
2473 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2474 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2475 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2476 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2477 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2478 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2479 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2480 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2481 case EL_MAMPFER2: return GFX_MAMPFER2;
2482 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2483 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2484 case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
2485 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2486 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2487 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2488 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2489 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2490 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2491 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2492 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2493 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2494 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2495 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2496 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2497 case EL_MOLE: return GFX_MOLE;
2498 case EL_PINGUIN: return GFX_PINGUIN;
2499 case EL_SCHWEIN: return GFX_SCHWEIN;
2500 case EL_DRACHE: return GFX_DRACHE;
2501 case EL_SONDE: return GFX_SONDE;
2502 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2503 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2504 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2505 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2506 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2507 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2508 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2509 case EL_SP_ZONK: return GFX_SP_ZONK;
2510 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2511 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2512 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2513 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2514 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2515 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2516 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2517 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2518 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2519 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2520 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2521 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2522 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2523 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2524 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2525 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2526 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2527 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2528 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2529 case EL_PEARL: return GFX_PEARL;
2530 case EL_CRYSTAL: return GFX_CRYSTAL;
2531 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2532 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2533 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2534 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2535 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2536 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2537 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2538 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2539 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2540 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2541 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2542 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2543 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2544 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2545 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2546 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2547 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2548 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2549 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2550 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2551 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2552 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2553 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2554 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2555 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2556 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2557 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2558 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2559 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2560 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2561 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2562 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2563 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2564 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2565 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2566 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2567 case EL_LANDMINE: return GFX_LANDMINE;
2568 case EL_ENVELOPE: return GFX_ENVELOPE;
2569 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2570 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2571 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2572 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2573 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2574 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2575 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2576 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2577 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2578 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2579 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2580 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2581 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2582 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2583 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2584 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2585 case EL_MOLE_UP: return GFX_MOLE_UP;
2586 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2587 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2588 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2589 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2590 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2591 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2592 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2593 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2594 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2595 case EL_BALLOON: return GFX_BALLOON;
2596 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2597 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2598 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2599 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2600 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2601 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2602 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2603 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2604 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2605 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2606 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2607 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2608 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2609 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2610 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2611 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2612 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2613 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2614 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2615 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2616 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2617 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2618 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2619 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2620 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2621 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2622 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2623 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2624 case EL_SPRING: return GFX_SPRING;
2625 case EL_SPRING_MOVING: return GFX_SPRING;
2626 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2627 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2628 case EL_BD_WALL: return GFX_BD_WALL;
2629 case EL_BD_ROCK: return GFX_BD_ROCK;
2630 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2631 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2635 if (IS_CHAR(element))
2636 return GFX_CHAR_START + (element - EL_CHAR_START);
2637 else if (element >= EL_SP_START && element <= EL_SP_END)
2639 int nr_element = element - EL_SP_START;
2640 int gfx_per_line = 8;
2642 (nr_element / gfx_per_line) * SP_PER_LINE +
2643 (nr_element % gfx_per_line);
2645 return GFX_START_ROCKSSP + nr_graphic;