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 if (last_element == EL_DYNAMITE_ACTIVE)
438 DrawDynamite(last_jx, last_jy);
440 DrawLevelFieldThruMask(last_jx, last_jy);
442 else if (last_element == EL_DYNAMITE_ACTIVE)
443 DrawDynamite(last_jx, last_jy);
445 DrawLevelField(last_jx, last_jy);
447 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
451 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
452 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
454 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
457 DrawLevelField(next_jx, next_jy);
461 if (!IN_SCR_FIELD(sx, sy))
464 if (setup.direct_draw)
465 SetDrawtoField(DRAW_BUFFERED);
467 /* draw things behind the player, if needed */
470 DrawLevelElement(jx, jy, Store[jx][jy]);
471 else if (!IS_ACTIVE_BOMB(element))
472 DrawLevelField(jx, jy);
474 DrawLevelElement(jx, jy, EL_LEERRAUM);
476 /* draw player himself */
478 if (game.emulation == EMU_SUPAPLEX)
480 static int last_dir = MV_LEFT;
481 int action = (player->programmed_action ? player->programmed_action :
483 boolean action_moving =
485 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
486 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
488 graphic = GFX_SP_MURPHY;
492 if (player->MovDir == MV_LEFT)
493 graphic = GFX_MURPHY_PUSH_LEFT;
494 else if (player->MovDir == MV_RIGHT)
495 graphic = GFX_MURPHY_PUSH_RIGHT;
496 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
497 graphic = GFX_MURPHY_PUSH_LEFT;
498 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
499 graphic = GFX_MURPHY_PUSH_RIGHT;
501 else if (player->snapped)
503 if (player->MovDir == MV_LEFT)
504 graphic = GFX_MURPHY_SNAP_LEFT;
505 else if (player->MovDir == MV_RIGHT)
506 graphic = GFX_MURPHY_SNAP_RIGHT;
507 else if (player->MovDir == MV_UP)
508 graphic = GFX_MURPHY_SNAP_UP;
509 else if (player->MovDir == MV_DOWN)
510 graphic = GFX_MURPHY_SNAP_DOWN;
512 else if (action_moving)
514 if (player->MovDir == MV_LEFT)
515 graphic = GFX_MURPHY_GO_LEFT;
516 else if (player->MovDir == MV_RIGHT)
517 graphic = GFX_MURPHY_GO_RIGHT;
518 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
519 graphic = GFX_MURPHY_GO_LEFT;
520 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
521 graphic = GFX_MURPHY_GO_RIGHT;
523 graphic = GFX_MURPHY_GO_LEFT;
525 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
528 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
529 last_dir = player->MovDir;
533 if (player->MovDir == MV_LEFT)
535 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
536 else if (player->MovDir == MV_RIGHT)
538 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
539 else if (player->MovDir == MV_UP)
540 graphic = GFX_SPIELER1_UP;
541 else /* MV_DOWN || MV_NO_MOVING */
542 graphic = GFX_SPIELER1_DOWN;
544 graphic += player->index_nr * 3 * HEROES_PER_LINE;
545 graphic += player->Frame;
550 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
551 sxx = player->GfxPos;
553 syy = player->GfxPos;
556 if (!setup.soft_scrolling && ScreenMovPos)
559 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
561 if (SHIELD_ON(player))
563 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
564 GFX2_SHIELD_PASSIVE);
566 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
567 3, 8, ANIM_OSCILLATE);
570 if (player->Pushing && player->GfxPos)
572 int px = SCREENX(next_jx), py = SCREENY(next_jy);
574 if (element == EL_SOKOBAN_FELD_LEER ||
575 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
576 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
580 int element = Feld[next_jx][next_jy];
581 int graphic = el2gfx(element);
583 if ((element == EL_FELSBROCKEN ||
584 element == EL_SP_ZONK ||
585 element == EL_BD_ROCK) && sxx)
587 int phase = (player->GfxPos / (TILEX / 4));
589 if (player->MovDir == MV_LEFT)
592 graphic += (phase + 4) % 4;
595 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
599 /* draw things in front of player (active dynamite or dynabombs) */
601 if (IS_ACTIVE_BOMB(element))
603 graphic = el2gfx(element);
605 if (element == EL_DYNAMITE_ACTIVE)
607 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
612 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
616 if (game.emulation == EMU_SUPAPLEX)
617 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
619 DrawGraphicThruMask(sx, sy, graphic + phase);
622 if (player_is_moving && last_element == EL_EXPLODING)
624 int phase = Frame[last_jx][last_jy];
628 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
629 GFX_EXPLOSION + ((phase - 1) / delay - 1));
632 /* draw elements that stay over the player */
633 /* handle the field the player is leaving ... */
634 if (player_is_moving && IS_OVER_PLAYER(last_element))
635 DrawLevelField(last_jx, last_jy);
636 /* ... and the field the player is entering */
637 if (IS_OVER_PLAYER(element))
638 DrawLevelField(jx, jy);
640 if (setup.direct_draw)
642 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
643 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
644 int x_size = TILEX * (1 + ABS(jx - last_jx));
645 int y_size = TILEY * (1 + ABS(jy - last_jy));
647 BlitBitmap(drawto_field, window,
648 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
649 SetDrawtoField(DRAW_DIRECT);
652 MarkTileDirty(sx,sy);
655 static int getGraphicAnimationPhase(int frames, int delay, int mode)
659 if (mode == ANIM_OSCILLATE)
661 int max_anim_frames = 2 * frames - 2;
662 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
663 phase = (phase < frames ? phase : max_anim_frames - phase);
666 phase = (FrameCounter % (delay * frames)) / delay;
668 if (mode == ANIM_REVERSE)
674 void DrawGraphicAnimationExt(int x, int y, int graphic,
675 int frames, int delay, int mode, int mask_mode)
677 int phase = getGraphicAnimationPhase(frames, delay, mode);
679 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
681 if (mask_mode == USE_MASKING)
682 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
684 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
688 void DrawGraphicAnimation(int x, int y, int graphic,
689 int frames, int delay, int mode)
691 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
694 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
695 int frames, int delay, int mode)
697 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
700 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
703 int frames, int delay,
706 int phase = getGraphicAnimationPhase(frames, delay, mode);
708 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
711 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
713 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
715 graphic -= GFX_START_ROCKSSCREEN;
716 *bitmap_nr = PIX_BACK;
717 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
718 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
720 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
722 graphic -= GFX_START_ROCKSHEROES;
723 *bitmap_nr = PIX_HEROES;
724 *x = (graphic % HEROES_PER_LINE) * TILEX;
725 *y = (graphic / HEROES_PER_LINE) * TILEY;
727 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
729 graphic -= GFX_START_ROCKSSP;
731 *x = (graphic % SP_PER_LINE) * TILEX;
732 *y = (graphic / SP_PER_LINE) * TILEY;
734 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
736 graphic -= GFX_START_ROCKSDC;
738 *x = (graphic % DC_PER_LINE) * TILEX;
739 *y = (graphic / DC_PER_LINE) * TILEY;
741 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
743 graphic -= GFX_START_ROCKSMORE;
744 *bitmap_nr = PIX_MORE;
745 *x = (graphic % MORE_PER_LINE) * TILEX;
746 *y = (graphic / MORE_PER_LINE) * TILEY;
748 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
750 graphic -= GFX_START_ROCKSFONT;
751 *bitmap_nr = PIX_BIGFONT;
752 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
753 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
754 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
764 void DrawGraphic(int x, int y, int graphic)
767 if (!IN_SCR_FIELD(x,y))
769 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
770 printf("DrawGraphic(): This should never happen!\n");
775 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
779 void DrawGraphicExt(DrawBuffer *bitmap, int x, int y, int graphic)
784 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
785 BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
788 void DrawGraphicThruMask(int x, int y, int graphic)
791 if (!IN_SCR_FIELD(x,y))
793 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
794 printf("DrawGraphicThruMask(): This should never happen!\n");
799 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
803 void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
811 if (graphic == GFX_LEERRAUM)
814 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
815 src_bitmap = pix[bitmap_nr];
816 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
818 if (tile_clipmask[tile] != None)
820 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
821 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
822 BlitBitmapMasked(src_bitmap, d,
823 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
829 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
833 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
834 BlitBitmapMasked(src_bitmap, d,
835 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
839 void DrawMiniGraphic(int x, int y, int graphic)
841 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
842 MarkTileDirty(x/2, y/2);
845 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
847 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
849 graphic -= GFX_START_ROCKSSCREEN;
850 *bitmap = pix[PIX_BACK];
851 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
852 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
854 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
856 graphic -= GFX_START_ROCKSSP;
857 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
858 *bitmap = pix[PIX_SP];
859 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
860 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
862 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
864 graphic -= GFX_START_ROCKSDC;
865 *bitmap = pix[PIX_DC];
866 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
867 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
869 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
871 graphic -= GFX_START_ROCKSMORE;
872 *bitmap = pix[PIX_MORE];
873 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
874 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
876 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
878 graphic -= GFX_START_ROCKSFONT;
879 *bitmap = pix[PIX_SMALLFONT];
880 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
881 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
882 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
886 *bitmap = pix[PIX_SP];
892 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
897 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
898 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
901 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
902 int cut_mode, int mask_mode)
904 int width = TILEX, height = TILEY;
906 int src_x, src_y, dest_x, dest_y;
914 DrawGraphic(x, y, graphic);
918 if (dx || dy) /* Verschiebung der Grafik? */
920 if (x < BX1) /* Element kommt von links ins Bild */
927 else if (x > BX2) /* Element kommt von rechts ins Bild */
933 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
939 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
941 else if (dx) /* allg. Bewegung in x-Richtung */
942 MarkTileDirty(x + SIGN(dx), y);
944 if (y < BY1) /* Element kommt von oben ins Bild */
946 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
954 else if (y > BY2) /* Element kommt von unten ins Bild */
960 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
966 else if (dy > 0 && cut_mode == CUT_ABOVE)
968 if (y == BY2) /* Element unterhalb des Bildes */
974 MarkTileDirty(x, y + 1);
975 } /* Element verläßt unten das Bild */
976 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
978 else if (dy) /* allg. Bewegung in y-Richtung */
979 MarkTileDirty(x, y + SIGN(dy));
982 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
983 src_bitmap = pix[bitmap_nr];
984 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
989 dest_x = FX + x * TILEX + dx;
990 dest_y = FY + y * TILEY + dy;
993 if (!IN_SCR_FIELD(x,y))
995 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
996 printf("DrawGraphicShifted(): This should never happen!\n");
1001 if (mask_mode == USE_MASKING)
1003 if (tile_clipmask[tile] != None)
1005 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1006 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1007 BlitBitmapMasked(src_bitmap, drawto_field,
1008 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1014 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1018 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1019 BlitBitmapMasked(src_bitmap, drawto_field,
1020 src_x, src_y, width, height, dest_x, dest_y);
1024 BlitBitmap(pix[bitmap_nr], drawto_field,
1025 src_x, src_y, width, height, dest_x, dest_y);
1030 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1033 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1036 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1037 int cut_mode, int mask_mode)
1039 int ux = LEVELX(x), uy = LEVELY(y);
1040 int graphic = el2gfx(element);
1041 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1042 int phase4 = phase8 / 2;
1043 int phase2 = phase8 / 4;
1044 int dir = MovDir[ux][uy];
1046 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1048 graphic += 4 * !phase2;
1052 else if (dir == MV_LEFT)
1054 else if (dir == MV_DOWN)
1057 else if (element == EL_SP_SNIKSNAK)
1060 graphic = GFX_SP_SNIKSNAK_LEFT;
1061 else if (dir == MV_RIGHT)
1062 graphic = GFX_SP_SNIKSNAK_RIGHT;
1063 else if (dir == MV_UP)
1064 graphic = GFX_SP_SNIKSNAK_UP;
1066 graphic = GFX_SP_SNIKSNAK_DOWN;
1068 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1070 else if (element == EL_SP_ELECTRON)
1072 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1074 else if (element == EL_MOLE || element == EL_PINGUIN ||
1075 element == EL_SCHWEIN || element == EL_DRACHE)
1078 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1079 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1080 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1081 else if (dir == MV_RIGHT)
1082 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1083 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1084 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1085 else if (dir == MV_UP)
1086 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1087 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1088 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1090 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1091 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1092 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1096 else if (element == EL_SONDE)
1098 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1100 else if (element == EL_SALZSAEURE)
1102 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1104 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1108 else if (element == EL_BALLOON)
1112 else if ((element == EL_FELSBROCKEN ||
1113 element == EL_SP_ZONK ||
1114 element == EL_BD_ROCK ||
1115 element == EL_SP_INFOTRON ||
1119 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1121 if (element == EL_FELSBROCKEN ||
1122 element == EL_SP_ZONK ||
1123 element == EL_BD_ROCK)
1126 graphic += (4 - phase4) % 4;
1127 else if (dir == MV_RIGHT)
1130 graphic += phase2 * 2;
1132 else if (element != EL_SP_INFOTRON)
1136 else if (element == EL_MAGIC_WALL_EMPTY ||
1137 element == EL_MAGIC_WALL_EMPTYING ||
1138 element == EL_MAGIC_WALL_BD_EMPTY ||
1139 element == EL_MAGIC_WALL_BD_EMPTYING ||
1140 element == EL_MAGIC_WALL_FULL ||
1141 element == EL_MAGIC_WALL_BD_FULL)
1143 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1145 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1147 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1148 graphic += (x + 2 * y + 4) % 4;
1150 else if (element == EL_MAUER_LEBT)
1152 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1154 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1155 links_massiv = TRUE;
1156 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1157 rechts_massiv = TRUE;
1159 if (links_massiv && rechts_massiv)
1160 graphic = GFX_MAUERWERK;
1161 else if (links_massiv)
1162 graphic = GFX_MAUER_R;
1163 else if (rechts_massiv)
1164 graphic = GFX_MAUER_L;
1166 else if ((element == EL_INVISIBLE_STEEL ||
1167 element == EL_UNSICHTBAR ||
1168 element == EL_SAND_INVISIBLE) && game.light_time_left)
1170 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1171 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1172 GFX_SAND_INVISIBLE_ON);
1176 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1177 else if (mask_mode == USE_MASKING)
1178 DrawGraphicThruMask(x, y, graphic);
1180 DrawGraphic(x, y, graphic);
1183 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1184 int cut_mode, int mask_mode)
1186 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1187 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1188 cut_mode, mask_mode);
1191 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1194 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1197 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1200 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1203 void DrawScreenElementThruMask(int x, int y, int element)
1205 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1208 void DrawLevelElementThruMask(int x, int y, int element)
1210 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1213 void DrawLevelFieldThruMask(int x, int y)
1215 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1218 void ErdreichAnbroeckeln(int x, int y)
1220 int i, width, height, cx,cy;
1221 int ux = LEVELX(x), uy = LEVELY(y);
1222 int element, graphic;
1224 static int xy[4][2] =
1232 if (!IN_LEV_FIELD(ux, uy))
1235 element = Feld[ux][uy];
1237 if (element == EL_ERDREICH ||
1238 element == EL_LANDMINE ||
1239 element == EL_TRAP_INACTIVE ||
1240 element == EL_TRAP_ACTIVE)
1242 if (!IN_SCR_FIELD(x, y))
1245 graphic = GFX_ERDENRAND;
1251 uxx = ux + xy[i][0];
1252 uyy = uy + xy[i][1];
1253 if (!IN_LEV_FIELD(uxx, uyy))
1256 element = Feld[uxx][uyy];
1258 if (element == EL_ERDREICH ||
1259 element == EL_LANDMINE ||
1260 element == EL_TRAP_INACTIVE ||
1261 element == EL_TRAP_ACTIVE)
1264 if (i == 1 || i == 2)
1268 cx = (i == 2 ? TILEX - snip : 0);
1276 cy = (i == 3 ? TILEY - snip : 0);
1279 BlitBitmap(pix[PIX_BACK], drawto_field,
1280 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1281 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1282 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1285 MarkTileDirty(x, y);
1289 graphic = GFX_ERDENRAND;
1293 int xx, yy, uxx, uyy;
1297 uxx = ux + xy[i][0];
1298 uyy = uy + xy[i][1];
1300 if (!IN_LEV_FIELD(uxx, uyy) ||
1301 (Feld[uxx][uyy] != EL_ERDREICH &&
1302 Feld[uxx][uyy] != EL_LANDMINE &&
1303 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1304 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1305 !IN_SCR_FIELD(xx, yy))
1308 if (i == 1 || i == 2)
1312 cx = (i == 1 ? TILEX - snip : 0);
1320 cy = (i==0 ? TILEY-snip : 0);
1323 BlitBitmap(pix[PIX_BACK], drawto_field,
1324 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1325 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1326 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1328 MarkTileDirty(xx, yy);
1333 void DrawScreenElement(int x, int y, int element)
1335 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1336 ErdreichAnbroeckeln(x, y);
1339 void DrawLevelElement(int x, int y, int element)
1341 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1342 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1345 void DrawScreenField(int x, int y)
1347 int ux = LEVELX(x), uy = LEVELY(y);
1348 int element, content;
1350 if (!IN_LEV_FIELD(ux, uy))
1352 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1353 element = EL_LEERRAUM;
1355 element = BorderElement;
1357 DrawScreenElement(x, y, element);
1361 element = Feld[ux][uy];
1362 content = Store[ux][uy];
1364 if (IS_MOVING(ux, uy))
1366 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1367 boolean cut_mode = NO_CUTTING;
1369 if (element == EL_QUICKSAND_EMPTYING ||
1370 element == EL_MAGIC_WALL_EMPTYING ||
1371 element == EL_MAGIC_WALL_BD_EMPTYING ||
1372 element == EL_AMOEBA_DRIPPING)
1373 cut_mode = CUT_ABOVE;
1374 else if (element == EL_QUICKSAND_FILLING ||
1375 element == EL_MAGIC_WALL_FILLING ||
1376 element == EL_MAGIC_WALL_BD_FILLING)
1377 cut_mode = CUT_BELOW;
1379 if (cut_mode == CUT_ABOVE)
1380 DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1382 DrawScreenElement(x, y, EL_LEERRAUM);
1385 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1386 else if (cut_mode == NO_CUTTING)
1387 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1389 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1391 if (content == EL_SALZSAEURE)
1392 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1394 else if (IS_BLOCKED(ux, uy))
1399 boolean cut_mode = NO_CUTTING;
1400 int element_old, content_old;
1402 Blocked2Moving(ux, uy, &oldx, &oldy);
1405 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1406 MovDir[oldx][oldy] == MV_RIGHT);
1408 element_old = Feld[oldx][oldy];
1409 content_old = Store[oldx][oldy];
1411 if (element_old == EL_QUICKSAND_EMPTYING ||
1412 element_old == EL_MAGIC_WALL_EMPTYING ||
1413 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1414 element_old == EL_AMOEBA_DRIPPING)
1415 cut_mode = CUT_ABOVE;
1417 DrawScreenElement(x, y, EL_LEERRAUM);
1420 DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1422 else if (cut_mode == NO_CUTTING)
1423 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1426 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
1429 else if (IS_DRAWABLE(element))
1430 DrawScreenElement(x, y, element);
1432 DrawScreenElement(x, y, EL_LEERRAUM);
1435 void DrawLevelField(int x, int y)
1437 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1438 DrawScreenField(SCREENX(x), SCREENY(y));
1439 else if (IS_MOVING(x, y))
1443 Moving2Blocked(x, y, &newx, &newy);
1444 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1445 DrawScreenField(SCREENX(newx), SCREENY(newy));
1447 else if (IS_BLOCKED(x, y))
1451 Blocked2Moving(x, y, &oldx, &oldy);
1452 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1453 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1457 void DrawMiniElement(int x, int y, int element)
1463 DrawMiniGraphic(x, y, -1);
1467 graphic = el2gfx(element);
1468 DrawMiniGraphic(x, y, graphic);
1471 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1473 int x = sx + scroll_x, y = sy + scroll_y;
1475 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1476 DrawMiniElement(sx, sy, EL_LEERRAUM);
1477 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1478 DrawMiniElement(sx, sy, Feld[x][y]);
1481 int steel_type, steel_position;
1484 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1485 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1486 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1487 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1488 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1489 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1492 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1493 steel_position = (x == -1 && y == -1 ? 0 :
1494 x == lev_fieldx && y == -1 ? 1 :
1495 x == -1 && y == lev_fieldy ? 2 :
1496 x == lev_fieldx && y == lev_fieldy ? 3 :
1497 x == -1 || x == lev_fieldx ? 4 :
1498 y == -1 || y == lev_fieldy ? 5 : -1);
1500 if (steel_position != -1)
1501 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1505 void DrawMicroElement(int xpos, int ypos, int element)
1509 if (element == EL_LEERRAUM)
1512 graphic = el2gfx(element);
1514 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1516 graphic -= GFX_START_ROCKSSP;
1517 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1518 BlitBitmap(pix[PIX_SP], drawto,
1519 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1520 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1521 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1523 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1525 graphic -= GFX_START_ROCKSDC;
1526 BlitBitmap(pix[PIX_DC], drawto,
1527 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1528 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1529 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1531 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1533 graphic -= GFX_START_ROCKSMORE;
1534 BlitBitmap(pix[PIX_MORE], drawto,
1535 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1536 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1537 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1540 BlitBitmap(pix[PIX_BACK], drawto,
1541 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1542 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1543 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1552 for(x=BX1; x<=BX2; x++)
1553 for(y=BY1; y<=BY2; y++)
1554 DrawScreenField(x, y);
1556 redraw_mask |= REDRAW_FIELD;
1559 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1563 for(x=0; x<size_x; x++)
1564 for(y=0; y<size_y; y++)
1565 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1567 redraw_mask |= REDRAW_FIELD;
1570 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1574 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1576 if (lev_fieldx < STD_LEV_FIELDX)
1577 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1578 if (lev_fieldy < STD_LEV_FIELDY)
1579 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1581 xpos += MICRO_TILEX;
1582 ypos += MICRO_TILEY;
1584 for(x=-1; x<=STD_LEV_FIELDX; x++)
1586 for(y=-1; y<=STD_LEV_FIELDY; y++)
1588 int lx = from_x + x, ly = from_y + y;
1590 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1591 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1593 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1594 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1599 redraw_mask |= REDRAW_MICROLEVEL;
1602 #define MICROLABEL_EMPTY 0
1603 #define MICROLABEL_LEVEL_NAME 1
1604 #define MICROLABEL_CREATED_BY 2
1605 #define MICROLABEL_LEVEL_AUTHOR 3
1606 #define MICROLABEL_IMPORTED_FROM 4
1607 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1609 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1611 static void DrawMicroLevelLabelExt(int mode)
1613 char label_text[MAX_MICROLABEL_SIZE + 1];
1615 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1617 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1618 mode == MICROLABEL_CREATED_BY ? "created by" :
1619 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1620 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1621 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1622 leveldir_current->imported_from : ""),
1623 MAX_MICROLABEL_SIZE);
1624 label_text[MAX_MICROLABEL_SIZE] = '\0';
1626 if (strlen(label_text) > 0)
1628 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1629 int lypos = MICROLABEL_YPOS;
1631 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1634 redraw_mask |= REDRAW_MICROLEVEL;
1637 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1639 static unsigned long scroll_delay = 0;
1640 static unsigned long label_delay = 0;
1641 static int from_x, from_y, scroll_direction;
1642 static int label_state, label_counter;
1646 from_x = from_y = 0;
1647 scroll_direction = MV_RIGHT;
1651 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1652 DrawMicroLevelLabelExt(label_state);
1654 /* initialize delay counters */
1655 DelayReached(&scroll_delay, 0);
1656 DelayReached(&label_delay, 0);
1661 /* scroll micro level, if needed */
1662 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1663 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1665 switch (scroll_direction)
1671 scroll_direction = MV_UP;
1675 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1678 scroll_direction = MV_DOWN;
1685 scroll_direction = MV_RIGHT;
1689 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1692 scroll_direction = MV_LEFT;
1699 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1702 /* redraw micro level label, if needed */
1703 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1704 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1705 strcmp(level.author, leveldir_current->name) != 0 &&
1706 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1708 int max_label_counter = 23;
1710 if (leveldir_current->imported_from != NULL)
1711 max_label_counter += 14;
1713 label_counter = (label_counter + 1) % max_label_counter;
1714 label_state = (label_counter >= 0 && label_counter <= 7 ?
1715 MICROLABEL_LEVEL_NAME :
1716 label_counter >= 9 && label_counter <= 12 ?
1717 MICROLABEL_CREATED_BY :
1718 label_counter >= 14 && label_counter <= 21 ?
1719 MICROLABEL_LEVEL_AUTHOR :
1720 label_counter >= 23 && label_counter <= 26 ?
1721 MICROLABEL_IMPORTED_FROM :
1722 label_counter >= 28 && label_counter <= 35 ?
1723 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1724 DrawMicroLevelLabelExt(label_state);
1728 int REQ_in_range(int x, int y)
1730 if (y > DY+249 && y < DY+278)
1732 if (x > DX+1 && x < DX+48)
1734 else if (x > DX+51 && x < DX+98)
1740 boolean Request(char *text, unsigned int req_state)
1742 int mx, my, ty, result = -1;
1743 unsigned int old_door_state;
1745 #if defined(PLATFORM_UNIX)
1746 /* pause network game while waiting for request to answer */
1747 if (options.network &&
1748 game_status == PLAYING &&
1749 req_state & REQUEST_WAIT_FOR)
1750 SendToServer_PausePlaying();
1753 old_door_state = GetDoorState();
1757 CloseDoor(DOOR_CLOSE_1);
1759 /* save old door content */
1760 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1761 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1762 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1764 /* clear door drawing field */
1765 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1767 /* write text for request */
1768 for(ty=0; ty<13; ty++)
1776 for(tl=0,tx=0; tx<7; tl++,tx++)
1779 if (!tc || tc == 32)
1790 DrawTextExt(drawto, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1791 txt, FS_SMALL, FC_YELLOW);
1792 text += tl + (tc == 32 ? 1 : 0);
1795 if (req_state & REQ_ASK)
1797 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1798 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1800 else if (req_state & REQ_CONFIRM)
1802 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1804 else if (req_state & REQ_PLAYER)
1806 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1807 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1808 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1809 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1812 /* copy request gadgets to door backbuffer */
1813 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1814 DX, DY, DXSIZE, DYSIZE,
1815 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1817 OpenDoor(DOOR_OPEN_1);
1823 if (!(req_state & REQUEST_WAIT_FOR))
1826 if (game_status != MAINMENU)
1829 button_status = MB_RELEASED;
1831 request_gadget_id = -1;
1843 case EVENT_BUTTONPRESS:
1844 case EVENT_BUTTONRELEASE:
1845 case EVENT_MOTIONNOTIFY:
1847 if (event.type == EVENT_MOTIONNOTIFY)
1849 if (!PointerInWindow(window))
1850 continue; /* window and pointer are on different screens */
1855 motion_status = TRUE;
1856 mx = ((MotionEvent *) &event)->x;
1857 my = ((MotionEvent *) &event)->y;
1861 motion_status = FALSE;
1862 mx = ((ButtonEvent *) &event)->x;
1863 my = ((ButtonEvent *) &event)->y;
1864 if (event.type == EVENT_BUTTONPRESS)
1865 button_status = ((ButtonEvent *) &event)->button;
1867 button_status = MB_RELEASED;
1870 /* this sets 'request_gadget_id' */
1871 HandleGadgets(mx, my, button_status);
1873 switch(request_gadget_id)
1875 case TOOL_CTRL_ID_YES:
1878 case TOOL_CTRL_ID_NO:
1881 case TOOL_CTRL_ID_CONFIRM:
1882 result = TRUE | FALSE;
1885 case TOOL_CTRL_ID_PLAYER_1:
1888 case TOOL_CTRL_ID_PLAYER_2:
1891 case TOOL_CTRL_ID_PLAYER_3:
1894 case TOOL_CTRL_ID_PLAYER_4:
1905 case EVENT_KEYPRESS:
1906 switch(GetEventKey((KeyEvent *)&event, TRUE))
1919 if (req_state & REQ_PLAYER)
1923 case EVENT_KEYRELEASE:
1924 key_joystick_mapping = 0;
1928 HandleOtherEvents(&event);
1932 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1934 int joy = AnyJoystick();
1936 if (joy & JOY_BUTTON_1)
1938 else if (joy & JOY_BUTTON_2)
1944 /* don't eat all CPU time */
1948 if (game_status != MAINMENU)
1953 if (!(req_state & REQ_STAY_OPEN))
1955 CloseDoor(DOOR_CLOSE_1);
1957 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1959 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1960 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1961 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1962 OpenDoor(DOOR_OPEN_1);
1968 #if defined(PLATFORM_UNIX)
1969 /* continue network game after request */
1970 if (options.network &&
1971 game_status == PLAYING &&
1972 req_state & REQUEST_WAIT_FOR)
1973 SendToServer_ContinuePlaying();
1979 unsigned int OpenDoor(unsigned int door_state)
1981 unsigned int new_door_state;
1983 if (door_state & DOOR_COPY_BACK)
1985 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1986 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
1987 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1988 door_state &= ~DOOR_COPY_BACK;
1991 new_door_state = MoveDoor(door_state);
1993 return(new_door_state);
1996 unsigned int CloseDoor(unsigned int door_state)
1998 unsigned int new_door_state;
2000 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2001 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2002 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2003 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2005 new_door_state = MoveDoor(door_state);
2007 return(new_door_state);
2010 unsigned int GetDoorState()
2012 return(MoveDoor(DOOR_GET_STATE));
2015 unsigned int MoveDoor(unsigned int door_state)
2017 static int door1 = DOOR_OPEN_1;
2018 static int door2 = DOOR_CLOSE_2;
2019 static unsigned long door_delay = 0;
2020 int x, start, stepsize = 2;
2021 unsigned long door_delay_value = stepsize * 5;
2023 if (door_state == DOOR_GET_STATE)
2024 return(door1 | door2);
2026 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2027 door_state &= ~DOOR_OPEN_1;
2028 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2029 door_state &= ~DOOR_CLOSE_1;
2030 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2031 door_state &= ~DOOR_OPEN_2;
2032 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2033 door_state &= ~DOOR_CLOSE_2;
2035 if (setup.quick_doors)
2038 door_delay_value = 0;
2039 StopSound(SND_OEFFNEN);
2042 if (door_state & DOOR_ACTION)
2044 if (!(door_state & DOOR_NO_DELAY))
2045 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2047 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2049 for(x=start; x<=DXSIZE; x+=stepsize)
2051 Bitmap *bitmap = pix[PIX_DOOR];
2052 GC gc = bitmap->stored_clip_gc;
2054 WaitUntilDelayReached(&door_delay, door_delay_value);
2056 if (door_state & DOOR_ACTION_1)
2058 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2059 int j = (DXSIZE - i) / 3;
2061 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2062 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2063 DXSIZE,DYSIZE - i/2, DX, DY);
2065 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2067 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2068 BlitBitmapMasked(bitmap, drawto,
2069 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2070 DX + DXSIZE - i, DY + j);
2071 BlitBitmapMasked(bitmap, drawto,
2072 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2073 DX + DXSIZE - i, DY + 140 + j);
2074 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2075 BlitBitmapMasked(bitmap, drawto,
2076 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2078 BlitBitmapMasked(bitmap, drawto,
2079 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2082 BlitBitmapMasked(bitmap, drawto,
2083 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2085 BlitBitmapMasked(bitmap, drawto,
2086 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2088 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2089 BlitBitmapMasked(bitmap, drawto,
2090 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2091 DX + DXSIZE - i, DY + 77 + j);
2092 BlitBitmapMasked(bitmap, drawto,
2093 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2094 DX + DXSIZE - i, DY + 203 + j);
2096 redraw_mask |= REDRAW_DOOR_1;
2099 if (door_state & DOOR_ACTION_2)
2101 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2102 int j = (VXSIZE - i) / 3;
2104 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2105 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2106 VXSIZE, VYSIZE - i/2, VX, VY);
2108 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2110 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2111 BlitBitmapMasked(bitmap, drawto,
2112 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2113 VX + VXSIZE-i, VY+j);
2114 SetClipOrigin(bitmap, gc,
2115 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2116 BlitBitmapMasked(bitmap, drawto,
2117 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2120 BlitBitmapMasked(bitmap, drawto,
2121 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2122 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2123 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2124 BlitBitmapMasked(bitmap, drawto,
2125 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2127 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2129 redraw_mask |= REDRAW_DOOR_2;
2134 if (game_status == MAINMENU)
2139 if (setup.quick_doors)
2140 StopSound(SND_OEFFNEN);
2142 if (door_state & DOOR_ACTION_1)
2143 door1 = door_state & DOOR_ACTION_1;
2144 if (door_state & DOOR_ACTION_2)
2145 door2 = door_state & DOOR_ACTION_2;
2147 return (door1 | door2);
2150 void DrawSpecialEditorDoor()
2152 /* draw bigger toolbox window */
2153 BlitBitmap(pix[PIX_DOOR], drawto,
2154 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2156 redraw_mask |= REDRAW_ALL;
2159 void UndrawSpecialEditorDoor()
2161 /* draw normal tape recorder window */
2162 BlitBitmap(pix[PIX_BACK], drawto,
2163 562, 344, 108, 56, EX - 4, EY - 12);
2165 redraw_mask |= REDRAW_ALL;
2169 int ReadPixel(DrawBuffer *bitmap, int x, int y)
2171 XImage *pixel_image;
2172 unsigned long pixel_value;
2174 pixel_image = XGetImage(display, bitmap->drawable,
2175 x, y, 1, 1, AllPlanes, ZPixmap);
2176 pixel_value = XGetPixel(pixel_image, 0, 0);
2178 XDestroyImage(pixel_image);
2184 /* ---------- new tool button stuff ---------------------------------------- */
2186 /* graphic position values for tool buttons */
2187 #define TOOL_BUTTON_YES_XPOS 2
2188 #define TOOL_BUTTON_YES_YPOS 250
2189 #define TOOL_BUTTON_YES_GFX_YPOS 0
2190 #define TOOL_BUTTON_YES_XSIZE 46
2191 #define TOOL_BUTTON_YES_YSIZE 28
2192 #define TOOL_BUTTON_NO_XPOS 52
2193 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2194 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2195 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2196 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2197 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2198 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2199 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2200 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2201 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2202 #define TOOL_BUTTON_PLAYER_XSIZE 30
2203 #define TOOL_BUTTON_PLAYER_YSIZE 30
2204 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2205 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2206 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2207 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2208 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2209 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2210 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2211 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2212 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2213 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2214 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2215 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2216 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2217 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2218 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2219 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2220 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2221 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2222 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2223 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2232 } toolbutton_info[NUM_TOOL_BUTTONS] =
2235 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2236 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2237 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2242 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2243 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2244 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2249 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2250 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2251 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2252 TOOL_CTRL_ID_CONFIRM,
2256 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2257 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2258 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2259 TOOL_CTRL_ID_PLAYER_1,
2263 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2264 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2265 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2266 TOOL_CTRL_ID_PLAYER_2,
2270 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2271 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2272 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2273 TOOL_CTRL_ID_PLAYER_3,
2277 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2278 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2279 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2280 TOOL_CTRL_ID_PLAYER_4,
2286 static void DoNotDisplayInfoText(void *ptr)
2292 void CreateToolButtons()
2296 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2298 Bitmap *gd_bitmap = pix[PIX_DOOR];
2299 Bitmap *deco_bitmap = None;
2300 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2301 struct GadgetInfo *gi;
2302 unsigned long event_mask;
2303 int gd_xoffset, gd_yoffset;
2304 int gd_x1, gd_x2, gd_y;
2307 event_mask = GD_EVENT_RELEASED;
2309 gd_xoffset = toolbutton_info[i].xpos;
2310 gd_yoffset = toolbutton_info[i].ypos;
2311 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2312 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2313 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2315 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2317 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2318 &deco_bitmap, &deco_x, &deco_y);
2319 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2320 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2323 gi = CreateGadget(GDI_CUSTOM_ID, id,
2324 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2325 GDI_X, DX + toolbutton_info[i].x,
2326 GDI_Y, DY + toolbutton_info[i].y,
2327 GDI_WIDTH, toolbutton_info[i].width,
2328 GDI_HEIGHT, toolbutton_info[i].height,
2329 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2330 GDI_STATE, GD_BUTTON_UNPRESSED,
2331 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2332 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2333 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2334 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2335 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2336 GDI_DECORATION_SHIFTING, 1, 1,
2337 GDI_EVENT_MASK, event_mask,
2340 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2343 GDI_CALLBACK_ACTION, HandleToolButtons,
2347 Error(ERR_EXIT, "cannot create gadget");
2349 tool_gadget[id] = gi;
2353 static void UnmapToolButtons()
2357 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2358 UnmapGadget(tool_gadget[i]);
2361 static void HandleToolButtons(struct GadgetInfo *gi)
2363 request_gadget_id = gi->custom_id;
2366 int get_next_element(int element)
2370 case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
2371 case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
2372 case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
2373 case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
2374 case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
2375 case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
2376 case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
2378 default: return element;
2382 int el2gfx(int element)
2386 case EL_LEERRAUM: return -1;
2387 case EL_ERDREICH: return GFX_ERDREICH;
2388 case EL_MAUERWERK: return GFX_MAUERWERK;
2389 case EL_FELSBODEN: return GFX_FELSBODEN;
2390 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2391 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2392 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2393 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2394 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2395 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2396 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2397 case EL_SPIELER1: return GFX_SPIELER1;
2398 case EL_SPIELER2: return GFX_SPIELER2;
2399 case EL_SPIELER3: return GFX_SPIELER3;
2400 case EL_SPIELER4: return GFX_SPIELER4;
2401 case EL_KAEFER: return GFX_KAEFER;
2402 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2403 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2404 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2405 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2406 case EL_FLIEGER: return GFX_FLIEGER;
2407 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2408 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2409 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2410 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2411 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2412 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2413 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2414 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2415 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2416 case EL_FIREFLY: return GFX_FIREFLY;
2417 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2418 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2419 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2420 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2421 case EL_MAMPFER: return GFX_MAMPFER;
2422 case EL_ROBOT: return GFX_ROBOT;
2423 case EL_BETON: return GFX_BETON;
2424 case EL_DIAMANT: return GFX_DIAMANT;
2425 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2426 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2427 case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
2428 case EL_TROPFEN: return GFX_TROPFEN;
2429 case EL_BOMBE: return GFX_BOMBE;
2430 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2431 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2432 case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
2433 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2434 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2435 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2436 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2437 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2438 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2439 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2440 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2441 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2442 case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
2443 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2444 case EL_LIFE: return GFX_LIFE;
2445 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2446 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2447 case EL_BADEWANNE: return GFX_BADEWANNE;
2448 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2449 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2450 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2451 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2452 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2453 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2454 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2455 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2456 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2457 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2458 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2459 case EL_PFORTE1: return GFX_PFORTE1;
2460 case EL_PFORTE2: return GFX_PFORTE2;
2461 case EL_PFORTE3: return GFX_PFORTE3;
2462 case EL_PFORTE4: return GFX_PFORTE4;
2463 case EL_PFORTE1X: return GFX_PFORTE1X;
2464 case EL_PFORTE2X: return GFX_PFORTE2X;
2465 case EL_PFORTE3X: return GFX_PFORTE3X;
2466 case EL_PFORTE4X: return GFX_PFORTE4X;
2467 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2468 case EL_PACMAN: return GFX_PACMAN;
2469 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2470 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2471 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2472 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2473 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2474 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2475 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2476 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2477 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2478 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2479 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2480 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2481 case EL_MAUER_X: return GFX_MAUER_X;
2482 case EL_MAUER_Y: return GFX_MAUER_Y;
2483 case EL_MAUER_XY: return GFX_MAUER_XY;
2484 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2485 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2486 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2487 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2488 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2489 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2490 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2491 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2492 case EL_MAMPFER2: return GFX_MAMPFER2;
2493 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2494 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2495 case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
2496 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2497 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2498 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2499 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2500 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2501 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2502 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2503 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2504 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2505 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2506 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2507 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2508 case EL_MOLE: return GFX_MOLE;
2509 case EL_PINGUIN: return GFX_PINGUIN;
2510 case EL_SCHWEIN: return GFX_SCHWEIN;
2511 case EL_DRACHE: return GFX_DRACHE;
2512 case EL_SONDE: return GFX_SONDE;
2513 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2514 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2515 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2516 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2517 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2518 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2519 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2520 case EL_SP_ZONK: return GFX_SP_ZONK;
2521 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2522 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2523 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2524 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2525 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2526 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2527 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2528 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2529 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2530 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2531 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2532 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2533 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2534 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2535 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2536 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2537 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2538 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2539 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2540 case EL_PEARL: return GFX_PEARL;
2541 case EL_CRYSTAL: return GFX_CRYSTAL;
2542 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2543 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2544 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2545 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2546 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2547 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2548 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2549 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2550 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2551 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2552 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2553 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2554 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2555 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2556 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2557 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2558 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2559 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2560 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2561 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2562 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2563 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2564 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2565 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2566 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2567 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2568 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2569 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2570 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2571 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2572 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2573 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2574 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2575 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2576 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2577 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2578 case EL_LANDMINE: return GFX_LANDMINE;
2579 case EL_ENVELOPE: return GFX_ENVELOPE;
2580 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2581 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2582 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2583 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2584 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2585 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2586 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2587 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2588 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2589 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2590 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2591 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2592 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2593 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2594 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2595 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2596 case EL_MOLE_UP: return GFX_MOLE_UP;
2597 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2598 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2599 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2600 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2601 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2602 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2603 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2604 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2605 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2606 case EL_BALLOON: return GFX_BALLOON;
2607 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2608 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2609 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2610 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2611 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2612 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2613 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2614 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2615 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2616 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2617 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2618 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2619 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2620 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2621 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2622 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2623 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2624 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2625 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2626 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2627 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2628 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2629 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2630 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2631 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2632 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2633 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2634 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2635 case EL_SPRING: return GFX_SPRING;
2636 case EL_SPRING_MOVING: return GFX_SPRING;
2637 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2638 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2639 case EL_BD_WALL: return GFX_BD_WALL;
2640 case EL_BD_ROCK: return GFX_BD_ROCK;
2641 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2642 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2646 if (IS_CHAR(element))
2647 return GFX_CHAR_START + (element - EL_CHAR_START);
2648 else if (element >= EL_SP_START && element <= EL_SP_END)
2650 int nr_element = element - EL_SP_START;
2651 int gfx_per_line = 8;
2653 (nr_element / gfx_per_line) * SP_PER_LINE +
2654 (nr_element % gfx_per_line);
2656 return GFX_START_ROCKSSP + nr_graphic;