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 ***********************************************************/
16 #if defined(PLATFORM_FREEBSD)
17 #include <machine/joystick.h>
20 #include "libgame/libgame.h"
30 #if defined(PLATFORM_MSDOS)
31 extern boolean wait_for_vsync;
34 /* tool button identifiers */
35 #define TOOL_CTRL_ID_YES 0
36 #define TOOL_CTRL_ID_NO 1
37 #define TOOL_CTRL_ID_CONFIRM 2
38 #define TOOL_CTRL_ID_PLAYER_1 3
39 #define TOOL_CTRL_ID_PLAYER_2 4
40 #define TOOL_CTRL_ID_PLAYER_3 5
41 #define TOOL_CTRL_ID_PLAYER_4 6
43 #define NUM_TOOL_BUTTONS 7
45 /* forward declaration for internal use */
46 static int getGraphicAnimationPhase(int, int, int);
47 static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
49 static void UnmapToolButtons();
50 static void HandleToolButtons(struct GadgetInfo *);
52 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
53 static int request_gadget_id = -1;
55 void SetDrawtoField(int mode)
57 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
68 drawto_field = fieldbuffer;
70 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
81 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
88 DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
90 if (setup.direct_draw && game_status == PLAYING)
91 redraw_mask &= ~REDRAW_MAIN;
93 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
94 redraw_mask |= REDRAW_FIELD;
96 if (redraw_mask & REDRAW_FIELD)
97 redraw_mask &= ~REDRAW_TILES;
102 if (global.fps_slowdown && game_status == PLAYING)
104 static boolean last_frame_skipped = FALSE;
105 boolean skip_even_when_not_scrolling = TRUE;
106 boolean just_scrolling = (ScreenMovDir != 0);
107 boolean verbose = FALSE;
109 if (global.fps_slowdown_factor > 1 &&
110 (FrameCounter % global.fps_slowdown_factor) &&
111 (just_scrolling || skip_even_when_not_scrolling))
113 redraw_mask &= ~REDRAW_MAIN;
115 last_frame_skipped = TRUE;
118 printf("FRAME SKIPPED\n");
122 if (last_frame_skipped)
123 redraw_mask |= REDRAW_FIELD;
125 last_frame_skipped = FALSE;
128 printf("frame not skipped\n");
132 /* synchronize X11 graphics at this point; if we would synchronize the
133 display immediately after the buffer switching (after the XFlush),
134 this could mean that we have to wait for the graphics to complete,
135 although we could go on doing calculations for the next frame */
139 if (redraw_mask & REDRAW_ALL)
141 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
145 if (redraw_mask & REDRAW_FIELD)
147 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
149 BlitBitmap(backbuffer, window,
150 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
154 int fx = FX, fy = FY;
156 if (setup.soft_scrolling)
158 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
159 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
162 if (setup.soft_scrolling ||
163 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
164 ABS(ScreenMovPos) == ScrollStepSize ||
165 redraw_tiles > REDRAWTILES_THRESHOLD)
167 BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
171 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
173 (setup.soft_scrolling ?
174 "setup.soft_scrolling" :
175 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
176 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
177 ABS(ScreenGfxPos) == ScrollStepSize ?
178 "ABS(ScreenGfxPos) == ScrollStepSize" :
179 "redraw_tiles > REDRAWTILES_THRESHOLD"));
185 redraw_mask &= ~REDRAW_MAIN;
188 if (redraw_mask & REDRAW_DOORS)
190 if (redraw_mask & REDRAW_DOOR_1)
191 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
192 if (redraw_mask & REDRAW_DOOR_2)
194 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
195 BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
198 if (redraw_mask & REDRAW_VIDEO_1)
199 BlitBitmap(backbuffer, window,
200 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
201 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
202 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
203 if (redraw_mask & REDRAW_VIDEO_2)
204 BlitBitmap(backbuffer, window,
205 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
206 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
207 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
208 if (redraw_mask & REDRAW_VIDEO_3)
209 BlitBitmap(backbuffer, window,
210 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
211 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
212 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
215 if (redraw_mask & REDRAW_DOOR_3)
216 BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
217 redraw_mask &= ~REDRAW_DOORS;
220 if (redraw_mask & REDRAW_MICROLEVEL)
222 BlitBitmap(backbuffer, window,
223 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
224 MICROLEV_XPOS, MICROLEV_YPOS);
225 BlitBitmap(backbuffer, window,
226 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
227 SX, MICROLABEL_YPOS);
228 redraw_mask &= ~REDRAW_MICROLEVEL;
231 if (redraw_mask & REDRAW_TILES)
233 for(x=0; x<SCR_FIELDX; x++)
234 for(y=0; y<SCR_FIELDY; y++)
235 if (redraw[redraw_x1 + x][redraw_y1 + y])
236 BlitBitmap(buffer, window,
237 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
238 SX + x * TILEX, SY + y * TILEY);
241 if (redraw_mask & REDRAW_FPS) /* display frames per second */
246 sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
247 if (!global.fps_slowdown)
250 sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
251 DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
256 for(x=0; x<MAX_BUF_XSIZE; x++)
257 for(y=0; y<MAX_BUF_YSIZE; y++)
266 long fading_delay = 300;
268 if (setup.fading && (redraw_mask & REDRAW_FIELD))
275 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
278 for(i=0;i<2*FULL_SYSIZE;i++)
280 for(y=0;y<FULL_SYSIZE;y++)
282 BlitBitmap(backbuffer, window,
283 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
291 for(i=1;i<FULL_SYSIZE;i+=2)
292 BlitBitmap(backbuffer, window,
293 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
299 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
300 BlitBitmapMasked(backbuffer, window,
301 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
306 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
307 BlitBitmapMasked(backbuffer, window,
308 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
313 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
314 BlitBitmapMasked(backbuffer, window,
315 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
320 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
321 BlitBitmapMasked(backbuffer, window,
322 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
327 redraw_mask &= ~REDRAW_MAIN;
336 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
338 if (setup.soft_scrolling && game_status == PLAYING)
340 ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
341 SetDrawtoField(DRAW_BUFFERED);
344 SetDrawtoField(DRAW_BACKBUFFER);
346 if (setup.direct_draw && game_status == PLAYING)
348 ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
349 SetDrawtoField(DRAW_DIRECT);
352 redraw_mask |= REDRAW_FIELD;
355 void MarkTileDirty(int x, int y)
357 int xx = redraw_x1 + x;
358 int yy = redraw_y1 + y;
363 redraw[xx][yy] = TRUE;
364 redraw_mask |= REDRAW_TILES;
367 void SetBorderElement()
371 BorderElement = EL_LEERRAUM;
373 for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
375 for(x=0; x<lev_fieldx; x++)
377 if (!IS_MASSIVE(Feld[x][y]))
378 BorderElement = EL_BETON;
380 if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
386 void DrawAllPlayers()
390 for(i=0; i<MAX_PLAYERS; i++)
391 if (stored_player[i].active)
392 DrawPlayer(&stored_player[i]);
395 void DrawPlayerField(int x, int y)
397 if (!IS_PLAYER(x, y))
400 DrawPlayer(PLAYERINFO(x, y));
403 void DrawPlayer(struct PlayerInfo *player)
405 int jx = player->jx, jy = player->jy;
406 int last_jx = player->last_jx, last_jy = player->last_jy;
407 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
408 int sx = SCREENX(jx), sy = SCREENY(jy);
409 int sxx = 0, syy = 0;
410 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
412 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
414 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
418 if (!IN_LEV_FIELD(jx,jy))
420 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
421 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
422 printf("DrawPlayerField(): This should never happen!\n");
427 if (element == EL_EXPLODING)
430 /* draw things in the field the player is leaving, if needed */
432 if (player_is_moving)
434 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
436 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
437 DrawLevelFieldThruMask(last_jx, last_jy);
439 else if (last_element == EL_DYNAMITE_ACTIVE)
440 DrawDynamite(last_jx, last_jy);
442 DrawLevelField(last_jx, last_jy);
444 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
448 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
449 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
451 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
454 DrawLevelField(next_jx, next_jy);
458 if (!IN_SCR_FIELD(sx, sy))
461 if (setup.direct_draw)
462 SetDrawtoField(DRAW_BUFFERED);
464 /* draw things behind the player, if needed */
467 DrawLevelElement(jx, jy, Store[jx][jy]);
468 else if (!IS_ACTIVE_BOMB(element))
469 DrawLevelField(jx, jy);
471 /* draw player himself */
473 if (game.emulation == EMU_SUPAPLEX)
475 static int last_dir = MV_LEFT;
476 int action = (player->programmed_action ? player->programmed_action :
478 boolean action_moving =
480 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
481 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
483 graphic = GFX_SP_MURPHY;
487 if (player->MovDir == MV_LEFT)
488 graphic = GFX_MURPHY_PUSH_LEFT;
489 else if (player->MovDir == MV_RIGHT)
490 graphic = GFX_MURPHY_PUSH_RIGHT;
491 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
492 graphic = GFX_MURPHY_PUSH_LEFT;
493 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
494 graphic = GFX_MURPHY_PUSH_RIGHT;
496 else if (player->snapped)
498 if (player->MovDir == MV_LEFT)
499 graphic = GFX_MURPHY_SNAP_LEFT;
500 else if (player->MovDir == MV_RIGHT)
501 graphic = GFX_MURPHY_SNAP_RIGHT;
502 else if (player->MovDir == MV_UP)
503 graphic = GFX_MURPHY_SNAP_UP;
504 else if (player->MovDir == MV_DOWN)
505 graphic = GFX_MURPHY_SNAP_DOWN;
507 else if (action_moving)
509 if (player->MovDir == MV_LEFT)
510 graphic = GFX_MURPHY_GO_LEFT;
511 else if (player->MovDir == MV_RIGHT)
512 graphic = GFX_MURPHY_GO_RIGHT;
513 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
514 graphic = GFX_MURPHY_GO_LEFT;
515 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
516 graphic = GFX_MURPHY_GO_RIGHT;
518 graphic = GFX_MURPHY_GO_LEFT;
520 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
523 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
524 last_dir = player->MovDir;
528 if (player->MovDir == MV_LEFT)
530 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
531 else if (player->MovDir == MV_RIGHT)
533 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
534 else if (player->MovDir == MV_UP)
535 graphic = GFX_SPIELER1_UP;
536 else /* MV_DOWN || MV_NO_MOVING */
537 graphic = GFX_SPIELER1_DOWN;
539 graphic += player->index_nr * 3 * HEROES_PER_LINE;
540 graphic += player->Frame;
545 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
546 sxx = player->GfxPos;
548 syy = player->GfxPos;
551 if (!setup.soft_scrolling && ScreenMovPos)
554 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
556 if (SHIELD_ON(player))
558 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
559 GFX2_SHIELD_PASSIVE);
561 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
562 3, 8, ANIM_OSCILLATE);
565 if (player->Pushing && player->GfxPos)
567 int px = SCREENX(next_jx), py = SCREENY(next_jy);
569 if (element == EL_SOKOBAN_FELD_LEER ||
570 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
571 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
575 int element = Feld[next_jx][next_jy];
576 int graphic = el2gfx(element);
578 if ((element == EL_FELSBROCKEN ||
579 element == EL_SP_ZONK ||
580 element == EL_BD_ROCK) && sxx)
582 int phase = (player->GfxPos / (TILEX / 4));
584 if (player->MovDir == MV_LEFT)
587 graphic += (phase + 4) % 4;
590 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
594 /* draw things in front of player (active dynamite or dynabombs) */
596 if (IS_ACTIVE_BOMB(element))
598 graphic = el2gfx(element);
600 if (element == EL_DYNAMITE_ACTIVE)
602 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
607 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
611 if (game.emulation == EMU_SUPAPLEX)
612 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
614 DrawGraphicThruMask(sx, sy, graphic + phase);
617 if (player_is_moving && last_element == EL_EXPLODING)
619 int phase = Frame[last_jx][last_jy];
623 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
624 GFX_EXPLOSION + ((phase - 1) / delay - 1));
627 /* draw elements that stay over the player */
628 /* handle the field the player is leaving ... */
629 if (player_is_moving && IS_OVER_PLAYER(last_element))
630 DrawLevelField(last_jx, last_jy);
631 /* ... and the field the player is entering */
632 if (IS_OVER_PLAYER(element))
633 DrawLevelField(jx, jy);
635 if (setup.direct_draw)
637 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
638 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
639 int x_size = TILEX * (1 + ABS(jx - last_jx));
640 int y_size = TILEY * (1 + ABS(jy - last_jy));
642 BlitBitmap(drawto_field, window,
643 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
644 SetDrawtoField(DRAW_DIRECT);
647 MarkTileDirty(sx,sy);
650 static int getGraphicAnimationPhase(int frames, int delay, int mode)
654 if (mode == ANIM_OSCILLATE)
656 int max_anim_frames = 2 * frames - 2;
657 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
658 phase = (phase < frames ? phase : max_anim_frames - phase);
661 phase = (FrameCounter % (delay * frames)) / delay;
663 if (mode == ANIM_REVERSE)
669 void DrawGraphicAnimationExt(int x, int y, int graphic,
670 int frames, int delay, int mode, int mask_mode)
672 int phase = getGraphicAnimationPhase(frames, delay, mode);
674 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
676 if (mask_mode == USE_MASKING)
677 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
679 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
683 void DrawGraphicAnimation(int x, int y, int graphic,
684 int frames, int delay, int mode)
686 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
689 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
690 int frames, int delay, int mode)
692 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
695 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
698 int frames, int delay,
701 int phase = getGraphicAnimationPhase(frames, delay, mode);
703 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
706 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
708 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
710 graphic -= GFX_START_ROCKSSCREEN;
711 *bitmap_nr = PIX_BACK;
712 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
713 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
715 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
717 graphic -= GFX_START_ROCKSHEROES;
718 *bitmap_nr = PIX_HEROES;
719 *x = (graphic % HEROES_PER_LINE) * TILEX;
720 *y = (graphic / HEROES_PER_LINE) * TILEY;
722 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
724 graphic -= GFX_START_ROCKSSP;
726 *x = (graphic % SP_PER_LINE) * TILEX;
727 *y = (graphic / SP_PER_LINE) * TILEY;
729 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
731 graphic -= GFX_START_ROCKSDC;
733 *x = (graphic % DC_PER_LINE) * TILEX;
734 *y = (graphic / DC_PER_LINE) * TILEY;
736 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
738 graphic -= GFX_START_ROCKSMORE;
739 *bitmap_nr = PIX_MORE;
740 *x = (graphic % MORE_PER_LINE) * TILEX;
741 *y = (graphic / MORE_PER_LINE) * TILEY;
743 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
745 graphic -= GFX_START_ROCKSFONT;
746 *bitmap_nr = PIX_BIGFONT;
747 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
748 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
749 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
759 void DrawGraphic(int x, int y, int graphic)
762 if (!IN_SCR_FIELD(x,y))
764 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
765 printf("DrawGraphic(): This should never happen!\n");
770 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
774 void DrawGraphicExt(DrawBuffer *bitmap, int x, int y, int graphic)
779 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
780 BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
783 void DrawGraphicThruMask(int x, int y, int graphic)
786 if (!IN_SCR_FIELD(x,y))
788 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
789 printf("DrawGraphicThruMask(): This should never happen!\n");
794 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
798 void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
806 if (graphic == GFX_LEERRAUM)
809 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
810 src_bitmap = pix[bitmap_nr];
811 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
813 if (tile_clipmask[tile] != None)
815 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
816 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
817 BlitBitmapMasked(src_bitmap, d,
818 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
824 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
828 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
829 BlitBitmapMasked(src_bitmap, d,
830 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
834 void DrawMiniGraphic(int x, int y, int graphic)
836 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
837 MarkTileDirty(x/2, y/2);
840 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
842 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
844 graphic -= GFX_START_ROCKSSCREEN;
845 *bitmap = pix[PIX_BACK];
846 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
847 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
849 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
851 graphic -= GFX_START_ROCKSSP;
852 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
853 *bitmap = pix[PIX_SP];
854 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
855 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
857 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
859 graphic -= GFX_START_ROCKSDC;
860 *bitmap = pix[PIX_DC];
861 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
862 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
864 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
866 graphic -= GFX_START_ROCKSMORE;
867 *bitmap = pix[PIX_MORE];
868 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
869 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
871 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
873 graphic -= GFX_START_ROCKSFONT;
874 *bitmap = pix[PIX_SMALLFONT];
875 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
876 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
877 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
881 *bitmap = pix[PIX_SP];
887 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
892 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
893 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
896 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
897 int cut_mode, int mask_mode)
899 int width = TILEX, height = TILEY;
901 int src_x, src_y, dest_x, dest_y;
909 DrawGraphic(x, y, graphic);
913 if (dx || dy) /* Verschiebung der Grafik? */
915 if (x < BX1) /* Element kommt von links ins Bild */
922 else if (x > BX2) /* Element kommt von rechts ins Bild */
928 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
934 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
936 else if (dx) /* allg. Bewegung in x-Richtung */
937 MarkTileDirty(x + SIGN(dx), y);
939 if (y < BY1) /* Element kommt von oben ins Bild */
941 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
949 else if (y > BY2) /* Element kommt von unten ins Bild */
955 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
961 else if (dy > 0 && cut_mode == CUT_ABOVE)
963 if (y == BY2) /* Element unterhalb des Bildes */
969 MarkTileDirty(x, y + 1);
970 } /* Element verläßt unten das Bild */
971 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
973 else if (dy) /* allg. Bewegung in y-Richtung */
974 MarkTileDirty(x, y + SIGN(dy));
977 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
978 src_bitmap = pix[bitmap_nr];
979 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
984 dest_x = FX + x * TILEX + dx;
985 dest_y = FY + y * TILEY + dy;
988 if (!IN_SCR_FIELD(x,y))
990 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
991 printf("DrawGraphicShifted(): This should never happen!\n");
996 if (mask_mode == USE_MASKING)
998 if (tile_clipmask[tile] != None)
1000 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1001 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1002 BlitBitmapMasked(src_bitmap, drawto_field,
1003 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1009 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1013 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1014 BlitBitmapMasked(src_bitmap, drawto_field,
1015 src_x, src_y, width, height, dest_x, dest_y);
1019 BlitBitmap(pix[bitmap_nr], drawto_field,
1020 src_x, src_y, width, height, dest_x, dest_y);
1025 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1028 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1031 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1032 int cut_mode, int mask_mode)
1034 int ux = LEVELX(x), uy = LEVELY(y);
1035 int graphic = el2gfx(element);
1036 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1037 int phase4 = phase8 / 2;
1038 int phase2 = phase8 / 4;
1039 int dir = MovDir[ux][uy];
1041 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1043 graphic += 4 * !phase2;
1047 else if (dir == MV_LEFT)
1049 else if (dir == MV_DOWN)
1052 else if (element == EL_SP_SNIKSNAK)
1055 graphic = GFX_SP_SNIKSNAK_LEFT;
1056 else if (dir == MV_RIGHT)
1057 graphic = GFX_SP_SNIKSNAK_RIGHT;
1058 else if (dir == MV_UP)
1059 graphic = GFX_SP_SNIKSNAK_UP;
1061 graphic = GFX_SP_SNIKSNAK_DOWN;
1063 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1065 else if (element == EL_SP_ELECTRON)
1067 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1069 else if (element == EL_MOLE || element == EL_PINGUIN ||
1070 element == EL_SCHWEIN || element == EL_DRACHE)
1073 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1074 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1075 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1076 else if (dir == MV_RIGHT)
1077 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1078 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1079 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1080 else if (dir == MV_UP)
1081 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1082 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1083 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1085 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1086 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1087 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1091 else if (element == EL_SONDE)
1093 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1095 else if (element == EL_SALZSAEURE)
1097 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1099 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1103 else if (element == EL_BALLOON)
1107 else if ((element == EL_FELSBROCKEN ||
1108 element == EL_SP_ZONK ||
1109 element == EL_BD_ROCK ||
1110 element == EL_SP_INFOTRON ||
1114 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1116 if (element == EL_FELSBROCKEN ||
1117 element == EL_SP_ZONK ||
1118 element == EL_BD_ROCK)
1121 graphic += (4 - phase4) % 4;
1122 else if (dir == MV_RIGHT)
1125 graphic += phase2 * 2;
1127 else if (element != EL_SP_INFOTRON)
1131 else if (element == EL_MAGIC_WALL_EMPTY ||
1132 element == EL_MAGIC_WALL_EMPTYING ||
1133 element == EL_MAGIC_WALL_BD_EMPTY ||
1134 element == EL_MAGIC_WALL_BD_EMPTYING ||
1135 element == EL_MAGIC_WALL_FULL ||
1136 element == EL_MAGIC_WALL_BD_FULL)
1138 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1140 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1142 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1143 graphic += (x + 2 * y + 4) % 4;
1145 else if (element == EL_MAUER_LEBT)
1147 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1149 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1150 links_massiv = TRUE;
1151 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1152 rechts_massiv = TRUE;
1154 if (links_massiv && rechts_massiv)
1155 graphic = GFX_MAUERWERK;
1156 else if (links_massiv)
1157 graphic = GFX_MAUER_R;
1158 else if (rechts_massiv)
1159 graphic = GFX_MAUER_L;
1161 else if ((element == EL_INVISIBLE_STEEL ||
1162 element == EL_UNSICHTBAR ||
1163 element == EL_SAND_INVISIBLE) && game.light_time_left)
1165 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1166 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1167 GFX_SAND_INVISIBLE_ON);
1171 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1172 else if (mask_mode == USE_MASKING)
1173 DrawGraphicThruMask(x, y, graphic);
1175 DrawGraphic(x, y, graphic);
1178 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1179 int cut_mode, int mask_mode)
1181 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1182 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1183 cut_mode, mask_mode);
1186 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1189 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1192 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1195 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1198 void DrawScreenElementThruMask(int x, int y, int element)
1200 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1203 void DrawLevelElementThruMask(int x, int y, int element)
1205 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1208 void DrawLevelFieldThruMask(int x, int y)
1210 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1213 void ErdreichAnbroeckeln(int x, int y)
1215 int i, width, height, cx,cy;
1216 int ux = LEVELX(x), uy = LEVELY(y);
1217 int element, graphic;
1219 static int xy[4][2] =
1227 if (!IN_LEV_FIELD(ux, uy))
1230 element = Feld[ux][uy];
1232 if (element == EL_ERDREICH ||
1233 element == EL_LANDMINE ||
1234 element == EL_TRAP_INACTIVE ||
1235 element == EL_TRAP_ACTIVE)
1237 if (!IN_SCR_FIELD(x, y))
1240 graphic = GFX_ERDENRAND;
1246 uxx = ux + xy[i][0];
1247 uyy = uy + xy[i][1];
1248 if (!IN_LEV_FIELD(uxx, uyy))
1251 element = Feld[uxx][uyy];
1253 if (element == EL_ERDREICH ||
1254 element == EL_LANDMINE ||
1255 element == EL_TRAP_INACTIVE ||
1256 element == EL_TRAP_ACTIVE)
1259 if (i == 1 || i == 2)
1263 cx = (i == 2 ? TILEX - snip : 0);
1271 cy = (i == 3 ? TILEY - snip : 0);
1274 BlitBitmap(pix[PIX_BACK], drawto_field,
1275 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1276 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1277 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1280 MarkTileDirty(x, y);
1284 graphic = GFX_ERDENRAND;
1288 int xx, yy, uxx, uyy;
1292 uxx = ux + xy[i][0];
1293 uyy = uy + xy[i][1];
1295 if (!IN_LEV_FIELD(uxx, uyy) ||
1296 (Feld[uxx][uyy] != EL_ERDREICH &&
1297 Feld[uxx][uyy] != EL_LANDMINE &&
1298 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1299 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1300 !IN_SCR_FIELD(xx, yy))
1303 if (i == 1 || i == 2)
1307 cx = (i == 1 ? TILEX - snip : 0);
1315 cy = (i==0 ? TILEY-snip : 0);
1318 BlitBitmap(pix[PIX_BACK], drawto_field,
1319 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1320 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1321 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1323 MarkTileDirty(xx, yy);
1328 void DrawScreenElement(int x, int y, int element)
1330 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1331 ErdreichAnbroeckeln(x, y);
1334 void DrawLevelElement(int x, int y, int element)
1336 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1337 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1340 void DrawScreenField(int x, int y)
1342 int ux = LEVELX(x), uy = LEVELY(y);
1343 int element, content;
1345 if (!IN_LEV_FIELD(ux, uy))
1347 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1348 element = EL_LEERRAUM;
1350 element = BorderElement;
1352 DrawScreenElement(x, y, element);
1356 element = Feld[ux][uy];
1357 content = Store[ux][uy];
1359 if (IS_MOVING(ux, uy))
1361 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1362 boolean cut_mode = NO_CUTTING;
1364 if (element == EL_QUICKSAND_EMPTYING ||
1365 element == EL_MAGIC_WALL_EMPTYING ||
1366 element == EL_MAGIC_WALL_BD_EMPTYING ||
1367 element == EL_AMOEBA_DRIPPING)
1368 cut_mode = CUT_ABOVE;
1369 else if (element == EL_QUICKSAND_FILLING ||
1370 element == EL_MAGIC_WALL_FILLING ||
1371 element == EL_MAGIC_WALL_BD_FILLING)
1372 cut_mode = CUT_BELOW;
1374 if (cut_mode == CUT_ABOVE)
1375 DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1377 DrawScreenElement(x, y, EL_LEERRAUM);
1380 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1381 else if (cut_mode == NO_CUTTING)
1382 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1384 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1386 if (content == EL_SALZSAEURE)
1387 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1389 else if (IS_BLOCKED(ux, uy))
1394 boolean cut_mode = NO_CUTTING;
1395 int element_old, content_old;
1397 Blocked2Moving(ux, uy, &oldx, &oldy);
1400 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1401 MovDir[oldx][oldy] == MV_RIGHT);
1403 element_old = Feld[oldx][oldy];
1404 content_old = Store[oldx][oldy];
1406 if (element_old == EL_QUICKSAND_EMPTYING ||
1407 element_old == EL_MAGIC_WALL_EMPTYING ||
1408 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1409 element_old == EL_AMOEBA_DRIPPING)
1410 cut_mode = CUT_ABOVE;
1412 DrawScreenElement(x, y, EL_LEERRAUM);
1415 DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1417 else if (cut_mode == NO_CUTTING)
1418 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1421 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
1424 else if (IS_DRAWABLE(element))
1425 DrawScreenElement(x, y, element);
1427 DrawScreenElement(x, y, EL_LEERRAUM);
1430 void DrawLevelField(int x, int y)
1432 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1433 DrawScreenField(SCREENX(x), SCREENY(y));
1434 else if (IS_MOVING(x, y))
1438 Moving2Blocked(x, y, &newx, &newy);
1439 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1440 DrawScreenField(SCREENX(newx), SCREENY(newy));
1442 else if (IS_BLOCKED(x, y))
1446 Blocked2Moving(x, y, &oldx, &oldy);
1447 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1448 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1452 void DrawMiniElement(int x, int y, int element)
1458 DrawMiniGraphic(x, y, -1);
1462 graphic = el2gfx(element);
1463 DrawMiniGraphic(x, y, graphic);
1466 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1468 int x = sx + scroll_x, y = sy + scroll_y;
1470 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1471 DrawMiniElement(sx, sy, EL_LEERRAUM);
1472 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1473 DrawMiniElement(sx, sy, Feld[x][y]);
1476 int steel_type, steel_position;
1479 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1480 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1481 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1482 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1483 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1484 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1487 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1488 steel_position = (x == -1 && y == -1 ? 0 :
1489 x == lev_fieldx && y == -1 ? 1 :
1490 x == -1 && y == lev_fieldy ? 2 :
1491 x == lev_fieldx && y == lev_fieldy ? 3 :
1492 x == -1 || x == lev_fieldx ? 4 :
1493 y == -1 || y == lev_fieldy ? 5 : -1);
1495 if (steel_position != -1)
1496 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1500 void DrawMicroElement(int xpos, int ypos, int element)
1504 if (element == EL_LEERRAUM)
1507 graphic = el2gfx(element);
1509 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1511 graphic -= GFX_START_ROCKSSP;
1512 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1513 BlitBitmap(pix[PIX_SP], drawto,
1514 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1515 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1516 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1518 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1520 graphic -= GFX_START_ROCKSDC;
1521 BlitBitmap(pix[PIX_DC], drawto,
1522 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1523 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1524 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1526 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1528 graphic -= GFX_START_ROCKSMORE;
1529 BlitBitmap(pix[PIX_MORE], drawto,
1530 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1531 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1532 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1535 BlitBitmap(pix[PIX_BACK], drawto,
1536 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1537 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1538 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1547 for(x=BX1; x<=BX2; x++)
1548 for(y=BY1; y<=BY2; y++)
1549 DrawScreenField(x, y);
1551 redraw_mask |= REDRAW_FIELD;
1554 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1558 for(x=0; x<size_x; x++)
1559 for(y=0; y<size_y; y++)
1560 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1562 redraw_mask |= REDRAW_FIELD;
1565 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1569 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1571 if (lev_fieldx < STD_LEV_FIELDX)
1572 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1573 if (lev_fieldy < STD_LEV_FIELDY)
1574 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1576 xpos += MICRO_TILEX;
1577 ypos += MICRO_TILEY;
1579 for(x=-1; x<=STD_LEV_FIELDX; x++)
1581 for(y=-1; y<=STD_LEV_FIELDY; y++)
1583 int lx = from_x + x, ly = from_y + y;
1585 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1586 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1588 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1589 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1594 redraw_mask |= REDRAW_MICROLEVEL;
1597 #define MICROLABEL_EMPTY 0
1598 #define MICROLABEL_LEVEL_NAME 1
1599 #define MICROLABEL_CREATED_BY 2
1600 #define MICROLABEL_LEVEL_AUTHOR 3
1601 #define MICROLABEL_IMPORTED_FROM 4
1602 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1604 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1606 static void DrawMicroLevelLabelExt(int mode)
1608 char label_text[MAX_MICROLABEL_SIZE + 1];
1610 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1612 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1613 mode == MICROLABEL_CREATED_BY ? "created by" :
1614 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1615 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1616 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1617 leveldir_current->imported_from : ""),
1618 MAX_MICROLABEL_SIZE);
1619 label_text[MAX_MICROLABEL_SIZE] = '\0';
1621 if (strlen(label_text) > 0)
1623 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1624 int lypos = MICROLABEL_YPOS;
1626 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1629 redraw_mask |= REDRAW_MICROLEVEL;
1632 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1634 static unsigned long scroll_delay = 0;
1635 static unsigned long label_delay = 0;
1636 static int from_x, from_y, scroll_direction;
1637 static int label_state, label_counter;
1641 from_x = from_y = 0;
1642 scroll_direction = MV_RIGHT;
1646 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1647 DrawMicroLevelLabelExt(label_state);
1649 /* initialize delay counters */
1650 DelayReached(&scroll_delay, 0);
1651 DelayReached(&label_delay, 0);
1656 /* scroll micro level, if needed */
1657 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1658 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1660 switch (scroll_direction)
1666 scroll_direction = MV_UP;
1670 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1673 scroll_direction = MV_DOWN;
1680 scroll_direction = MV_RIGHT;
1684 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1687 scroll_direction = MV_LEFT;
1694 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1697 /* redraw micro level label, if needed */
1698 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1699 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1700 strcmp(level.author, leveldir_current->name) != 0 &&
1701 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1703 int max_label_counter = 23;
1705 if (leveldir_current->imported_from != NULL)
1706 max_label_counter += 14;
1708 label_counter = (label_counter + 1) % max_label_counter;
1709 label_state = (label_counter >= 0 && label_counter <= 7 ?
1710 MICROLABEL_LEVEL_NAME :
1711 label_counter >= 9 && label_counter <= 12 ?
1712 MICROLABEL_CREATED_BY :
1713 label_counter >= 14 && label_counter <= 21 ?
1714 MICROLABEL_LEVEL_AUTHOR :
1715 label_counter >= 23 && label_counter <= 26 ?
1716 MICROLABEL_IMPORTED_FROM :
1717 label_counter >= 28 && label_counter <= 35 ?
1718 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1719 DrawMicroLevelLabelExt(label_state);
1723 int REQ_in_range(int x, int y)
1725 if (y > DY+249 && y < DY+278)
1727 if (x > DX+1 && x < DX+48)
1729 else if (x > DX+51 && x < DX+98)
1735 boolean Request(char *text, unsigned int req_state)
1737 int mx, my, ty, result = -1;
1738 unsigned int old_door_state;
1740 #if defined(PLATFORM_UNIX)
1741 /* pause network game while waiting for request to answer */
1742 if (options.network &&
1743 game_status == PLAYING &&
1744 req_state & REQUEST_WAIT_FOR)
1745 SendToServer_PausePlaying();
1748 old_door_state = GetDoorState();
1752 CloseDoor(DOOR_CLOSE_1);
1754 /* save old door content */
1755 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1756 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1757 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1759 /* clear door drawing field */
1760 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1762 /* write text for request */
1763 for(ty=0; ty<13; ty++)
1771 for(tl=0,tx=0; tx<7; tl++,tx++)
1774 if (!tc || tc == 32)
1785 DrawTextExt(drawto, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1786 txt, FS_SMALL, FC_YELLOW);
1787 text += tl + (tc == 32 ? 1 : 0);
1790 if (req_state & REQ_ASK)
1792 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1793 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1795 else if (req_state & REQ_CONFIRM)
1797 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1799 else if (req_state & REQ_PLAYER)
1801 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1802 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1803 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1804 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1807 /* copy request gadgets to door backbuffer */
1808 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1809 DX, DY, DXSIZE, DYSIZE,
1810 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1812 OpenDoor(DOOR_OPEN_1);
1818 if (!(req_state & REQUEST_WAIT_FOR))
1821 if (game_status != MAINMENU)
1824 button_status = MB_RELEASED;
1826 request_gadget_id = -1;
1838 case EVENT_BUTTONPRESS:
1839 case EVENT_BUTTONRELEASE:
1840 case EVENT_MOTIONNOTIFY:
1842 if (event.type == EVENT_MOTIONNOTIFY)
1844 if (!PointerInWindow(window))
1845 continue; /* window and pointer are on different screens */
1850 motion_status = TRUE;
1851 mx = ((MotionEvent *) &event)->x;
1852 my = ((MotionEvent *) &event)->y;
1856 motion_status = FALSE;
1857 mx = ((ButtonEvent *) &event)->x;
1858 my = ((ButtonEvent *) &event)->y;
1859 if (event.type == EVENT_BUTTONPRESS)
1860 button_status = ((ButtonEvent *) &event)->button;
1862 button_status = MB_RELEASED;
1865 /* this sets 'request_gadget_id' */
1866 HandleGadgets(mx, my, button_status);
1868 switch(request_gadget_id)
1870 case TOOL_CTRL_ID_YES:
1873 case TOOL_CTRL_ID_NO:
1876 case TOOL_CTRL_ID_CONFIRM:
1877 result = TRUE | FALSE;
1880 case TOOL_CTRL_ID_PLAYER_1:
1883 case TOOL_CTRL_ID_PLAYER_2:
1886 case TOOL_CTRL_ID_PLAYER_3:
1889 case TOOL_CTRL_ID_PLAYER_4:
1900 case EVENT_KEYPRESS:
1901 switch(GetEventKey((KeyEvent *)&event, TRUE))
1914 if (req_state & REQ_PLAYER)
1918 case EVENT_KEYRELEASE:
1919 key_joystick_mapping = 0;
1923 HandleOtherEvents(&event);
1927 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1929 int joy = AnyJoystick();
1931 if (joy & JOY_BUTTON_1)
1933 else if (joy & JOY_BUTTON_2)
1939 /* don't eat all CPU time */
1943 if (game_status != MAINMENU)
1948 if (!(req_state & REQ_STAY_OPEN))
1950 CloseDoor(DOOR_CLOSE_1);
1952 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1954 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1955 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1956 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1957 OpenDoor(DOOR_OPEN_1);
1963 #if defined(PLATFORM_UNIX)
1964 /* continue network game after request */
1965 if (options.network &&
1966 game_status == PLAYING &&
1967 req_state & REQUEST_WAIT_FOR)
1968 SendToServer_ContinuePlaying();
1974 unsigned int OpenDoor(unsigned int door_state)
1976 unsigned int new_door_state;
1978 if (door_state & DOOR_COPY_BACK)
1980 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1981 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
1982 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1983 door_state &= ~DOOR_COPY_BACK;
1986 new_door_state = MoveDoor(door_state);
1988 return(new_door_state);
1991 unsigned int CloseDoor(unsigned int door_state)
1993 unsigned int new_door_state;
1995 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
1996 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1997 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
1998 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2000 new_door_state = MoveDoor(door_state);
2002 return(new_door_state);
2005 unsigned int GetDoorState()
2007 return(MoveDoor(DOOR_GET_STATE));
2010 unsigned int MoveDoor(unsigned int door_state)
2012 static int door1 = DOOR_OPEN_1;
2013 static int door2 = DOOR_CLOSE_2;
2014 static unsigned long door_delay = 0;
2015 int x, start, stepsize = 2;
2016 unsigned long door_delay_value = stepsize * 5;
2018 if (door_state == DOOR_GET_STATE)
2019 return(door1 | door2);
2021 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2022 door_state &= ~DOOR_OPEN_1;
2023 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2024 door_state &= ~DOOR_CLOSE_1;
2025 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2026 door_state &= ~DOOR_OPEN_2;
2027 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2028 door_state &= ~DOOR_CLOSE_2;
2030 if (setup.quick_doors)
2033 door_delay_value = 0;
2034 StopSound(SND_OEFFNEN);
2037 if (door_state & DOOR_ACTION)
2039 if (!(door_state & DOOR_NO_DELAY))
2040 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2042 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2044 for(x=start; x<=DXSIZE; x+=stepsize)
2046 Bitmap *bitmap = pix[PIX_DOOR];
2047 GC gc = bitmap->stored_clip_gc;
2049 WaitUntilDelayReached(&door_delay, door_delay_value);
2051 if (door_state & DOOR_ACTION_1)
2053 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2054 int j = (DXSIZE - i) / 3;
2056 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2057 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2058 DXSIZE,DYSIZE - i/2, DX, DY);
2060 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2062 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2063 BlitBitmapMasked(bitmap, drawto,
2064 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2065 DX + DXSIZE - i, DY + j);
2066 BlitBitmapMasked(bitmap, drawto,
2067 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2068 DX + DXSIZE - i, DY + 140 + j);
2069 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2070 BlitBitmapMasked(bitmap, drawto,
2071 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2073 BlitBitmapMasked(bitmap, drawto,
2074 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2077 BlitBitmapMasked(bitmap, drawto,
2078 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2080 BlitBitmapMasked(bitmap, drawto,
2081 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2083 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2084 BlitBitmapMasked(bitmap, drawto,
2085 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2086 DX + DXSIZE - i, DY + 77 + j);
2087 BlitBitmapMasked(bitmap, drawto,
2088 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2089 DX + DXSIZE - i, DY + 203 + j);
2091 redraw_mask |= REDRAW_DOOR_1;
2094 if (door_state & DOOR_ACTION_2)
2096 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2097 int j = (VXSIZE - i) / 3;
2099 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2100 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2101 VXSIZE, VYSIZE - i/2, VX, VY);
2103 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2105 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2106 BlitBitmapMasked(bitmap, drawto,
2107 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2108 VX + VXSIZE-i, VY+j);
2109 SetClipOrigin(bitmap, gc,
2110 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2111 BlitBitmapMasked(bitmap, drawto,
2112 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2115 BlitBitmapMasked(bitmap, drawto,
2116 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2117 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2118 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2119 BlitBitmapMasked(bitmap, drawto,
2120 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2122 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2124 redraw_mask |= REDRAW_DOOR_2;
2129 if (game_status == MAINMENU)
2134 if (setup.quick_doors)
2135 StopSound(SND_OEFFNEN);
2137 if (door_state & DOOR_ACTION_1)
2138 door1 = door_state & DOOR_ACTION_1;
2139 if (door_state & DOOR_ACTION_2)
2140 door2 = door_state & DOOR_ACTION_2;
2142 return (door1 | door2);
2145 void DrawSpecialEditorDoor()
2147 /* draw bigger toolbox window */
2148 BlitBitmap(pix[PIX_DOOR], drawto,
2149 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2151 redraw_mask |= REDRAW_ALL;
2154 void UndrawSpecialEditorDoor()
2156 /* draw normal tape recorder window */
2157 BlitBitmap(pix[PIX_BACK], drawto,
2158 562, 344, 108, 56, EX - 4, EY - 12);
2160 redraw_mask |= REDRAW_ALL;
2164 int ReadPixel(DrawBuffer *bitmap, int x, int y)
2166 XImage *pixel_image;
2167 unsigned long pixel_value;
2169 pixel_image = XGetImage(display, bitmap->drawable,
2170 x, y, 1, 1, AllPlanes, ZPixmap);
2171 pixel_value = XGetPixel(pixel_image, 0, 0);
2173 XDestroyImage(pixel_image);
2179 /* ---------- new tool button stuff ---------------------------------------- */
2181 /* graphic position values for tool buttons */
2182 #define TOOL_BUTTON_YES_XPOS 2
2183 #define TOOL_BUTTON_YES_YPOS 250
2184 #define TOOL_BUTTON_YES_GFX_YPOS 0
2185 #define TOOL_BUTTON_YES_XSIZE 46
2186 #define TOOL_BUTTON_YES_YSIZE 28
2187 #define TOOL_BUTTON_NO_XPOS 52
2188 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2189 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2190 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2191 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2192 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2193 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2194 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2195 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2196 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2197 #define TOOL_BUTTON_PLAYER_XSIZE 30
2198 #define TOOL_BUTTON_PLAYER_YSIZE 30
2199 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2200 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2201 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2202 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2203 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2204 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2205 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2206 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2207 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2208 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2209 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2210 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2211 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2212 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2213 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2214 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2215 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2216 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2217 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2218 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2227 } toolbutton_info[NUM_TOOL_BUTTONS] =
2230 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2231 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2232 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2237 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2238 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2239 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2244 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2245 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2246 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2247 TOOL_CTRL_ID_CONFIRM,
2251 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2252 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2253 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2254 TOOL_CTRL_ID_PLAYER_1,
2258 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2259 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2260 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2261 TOOL_CTRL_ID_PLAYER_2,
2265 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2266 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2267 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2268 TOOL_CTRL_ID_PLAYER_3,
2272 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2273 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2274 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2275 TOOL_CTRL_ID_PLAYER_4,
2281 static void DoNotDisplayInfoText(void *ptr)
2287 void CreateToolButtons()
2291 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2293 Bitmap *gd_bitmap = pix[PIX_DOOR];
2294 Bitmap *deco_bitmap = None;
2295 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2296 struct GadgetInfo *gi;
2297 unsigned long event_mask;
2298 int gd_xoffset, gd_yoffset;
2299 int gd_x1, gd_x2, gd_y;
2302 event_mask = GD_EVENT_RELEASED;
2304 gd_xoffset = toolbutton_info[i].xpos;
2305 gd_yoffset = toolbutton_info[i].ypos;
2306 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2307 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2308 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2310 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2312 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2313 &deco_bitmap, &deco_x, &deco_y);
2314 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2315 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2318 gi = CreateGadget(GDI_CUSTOM_ID, id,
2319 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2320 GDI_X, DX + toolbutton_info[i].x,
2321 GDI_Y, DY + toolbutton_info[i].y,
2322 GDI_WIDTH, toolbutton_info[i].width,
2323 GDI_HEIGHT, toolbutton_info[i].height,
2324 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2325 GDI_STATE, GD_BUTTON_UNPRESSED,
2326 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2327 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2328 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2329 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2330 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2331 GDI_DECORATION_SHIFTING, 1, 1,
2332 GDI_EVENT_MASK, event_mask,
2335 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2338 GDI_CALLBACK_ACTION, HandleToolButtons,
2342 Error(ERR_EXIT, "cannot create gadget");
2344 tool_gadget[id] = gi;
2348 static void UnmapToolButtons()
2352 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2353 UnmapGadget(tool_gadget[i]);
2356 static void HandleToolButtons(struct GadgetInfo *gi)
2358 request_gadget_id = gi->custom_id;
2361 int get_next_element(int element)
2365 case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
2366 case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
2367 case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
2368 case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
2369 case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
2370 case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
2371 case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
2373 default: return element;
2377 int el2gfx(int element)
2381 case EL_LEERRAUM: return -1;
2382 case EL_ERDREICH: return GFX_ERDREICH;
2383 case EL_MAUERWERK: return GFX_MAUERWERK;
2384 case EL_FELSBODEN: return GFX_FELSBODEN;
2385 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2386 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2387 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2388 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2389 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2390 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2391 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2392 case EL_SPIELER1: return GFX_SPIELER1;
2393 case EL_SPIELER2: return GFX_SPIELER2;
2394 case EL_SPIELER3: return GFX_SPIELER3;
2395 case EL_SPIELER4: return GFX_SPIELER4;
2396 case EL_KAEFER: return GFX_KAEFER;
2397 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2398 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2399 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2400 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2401 case EL_FLIEGER: return GFX_FLIEGER;
2402 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2403 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2404 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2405 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2406 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2407 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2408 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2409 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2410 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2411 case EL_FIREFLY: return GFX_FIREFLY;
2412 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2413 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2414 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2415 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2416 case EL_MAMPFER: return GFX_MAMPFER;
2417 case EL_ROBOT: return GFX_ROBOT;
2418 case EL_BETON: return GFX_BETON;
2419 case EL_DIAMANT: return GFX_DIAMANT;
2420 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2421 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2422 case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
2423 case EL_TROPFEN: return GFX_TROPFEN;
2424 case EL_BOMBE: return GFX_BOMBE;
2425 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2426 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2427 case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
2428 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2429 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2430 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2431 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2432 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2433 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2434 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2435 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2436 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2437 case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
2438 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2439 case EL_LIFE: return GFX_LIFE;
2440 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2441 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2442 case EL_BADEWANNE: return GFX_BADEWANNE;
2443 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2444 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2445 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2446 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2447 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2448 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2449 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2450 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2451 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2452 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2453 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2454 case EL_PFORTE1: return GFX_PFORTE1;
2455 case EL_PFORTE2: return GFX_PFORTE2;
2456 case EL_PFORTE3: return GFX_PFORTE3;
2457 case EL_PFORTE4: return GFX_PFORTE4;
2458 case EL_PFORTE1X: return GFX_PFORTE1X;
2459 case EL_PFORTE2X: return GFX_PFORTE2X;
2460 case EL_PFORTE3X: return GFX_PFORTE3X;
2461 case EL_PFORTE4X: return GFX_PFORTE4X;
2462 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2463 case EL_PACMAN: return GFX_PACMAN;
2464 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2465 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2466 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2467 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2468 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2469 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2470 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2471 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2472 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2473 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2474 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2475 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2476 case EL_MAUER_X: return GFX_MAUER_X;
2477 case EL_MAUER_Y: return GFX_MAUER_Y;
2478 case EL_MAUER_XY: return GFX_MAUER_XY;
2479 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2480 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2481 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2482 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2483 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2484 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2485 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2486 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2487 case EL_MAMPFER2: return GFX_MAMPFER2;
2488 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2489 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2490 case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
2491 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2492 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2493 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2494 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2495 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2496 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2497 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2498 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2499 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2500 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2501 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2502 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2503 case EL_MOLE: return GFX_MOLE;
2504 case EL_PINGUIN: return GFX_PINGUIN;
2505 case EL_SCHWEIN: return GFX_SCHWEIN;
2506 case EL_DRACHE: return GFX_DRACHE;
2507 case EL_SONDE: return GFX_SONDE;
2508 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2509 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2510 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2511 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2512 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2513 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2514 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2515 case EL_SP_ZONK: return GFX_SP_ZONK;
2516 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2517 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2518 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2519 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2520 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2521 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2522 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2523 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2524 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2525 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2526 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2527 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2528 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2529 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2530 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2531 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2532 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2533 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2534 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2535 case EL_PEARL: return GFX_PEARL;
2536 case EL_CRYSTAL: return GFX_CRYSTAL;
2537 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2538 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2539 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2540 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2541 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2542 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2543 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2544 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2545 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2546 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2547 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2548 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2549 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2550 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2551 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2552 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2553 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2554 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2555 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2556 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2557 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2558 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2559 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2560 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2561 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2562 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2563 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2564 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2565 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2566 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2567 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2568 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2569 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2570 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2571 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2572 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2573 case EL_LANDMINE: return GFX_LANDMINE;
2574 case EL_ENVELOPE: return GFX_ENVELOPE;
2575 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2576 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2577 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2578 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2579 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2580 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2581 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2582 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2583 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2584 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2585 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2586 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2587 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2588 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2589 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2590 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2591 case EL_MOLE_UP: return GFX_MOLE_UP;
2592 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2593 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2594 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2595 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2596 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2597 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2598 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2599 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2600 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2601 case EL_BALLOON: return GFX_BALLOON;
2602 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2603 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2604 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2605 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2606 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2607 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2608 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2609 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2610 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2611 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2612 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2613 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2614 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2615 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2616 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2617 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2618 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2619 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2620 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2621 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2622 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2623 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2624 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2625 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2626 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2627 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2628 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2629 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2630 case EL_SPRING: return GFX_SPRING;
2631 case EL_SPRING_MOVING: return GFX_SPRING;
2632 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2633 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2634 case EL_BD_WALL: return GFX_BD_WALL;
2635 case EL_BD_ROCK: return GFX_BD_ROCK;
2636 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2637 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2641 if (IS_CHAR(element))
2642 return GFX_CHAR_START + (element - EL_CHAR_START);
2643 else if (element >= EL_SP_START && element <= EL_SP_END)
2645 int nr_element = element - EL_SP_START;
2646 int gfx_per_line = 8;
2648 (nr_element / gfx_per_line) * SP_PER_LINE +
2649 (nr_element % gfx_per_line);
2651 return GFX_START_ROCKSSP + nr_graphic;