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 ***********************************************************/
14 #include "libgame/libgame.h"
23 #if defined(PLATFORM_MSDOS)
24 extern boolean wait_for_vsync;
27 /* tool button identifiers */
28 #define TOOL_CTRL_ID_YES 0
29 #define TOOL_CTRL_ID_NO 1
30 #define TOOL_CTRL_ID_CONFIRM 2
31 #define TOOL_CTRL_ID_PLAYER_1 3
32 #define TOOL_CTRL_ID_PLAYER_2 4
33 #define TOOL_CTRL_ID_PLAYER_3 5
34 #define TOOL_CTRL_ID_PLAYER_4 6
36 #define NUM_TOOL_BUTTONS 7
38 /* forward declaration for internal use */
39 static int getGraphicAnimationPhase(int, int, int);
40 static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
42 static void UnmapToolButtons();
43 static void HandleToolButtons(struct GadgetInfo *);
45 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
46 static int request_gadget_id = -1;
48 void SetDrawtoField(int mode)
50 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
61 drawto_field = fieldbuffer;
63 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
74 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
78 void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
80 if (game_status == PLAYING)
86 width = gfx.sxsize + 2 * TILEX;
87 height = gfx.sysize + 2 * TILEY;
90 if (force_redraw || setup.direct_draw)
93 int x1 = (x - SX) / TILEX, y1 = (y - SY) / TILEY;
94 int x2 = (x - SX + width) / TILEX, y2 = (y - SY + height) / TILEY;
96 if (setup.direct_draw)
97 SetDrawtoField(DRAW_BACKBUFFER);
99 for(xx=BX1; xx<=BX2; xx++)
100 for(yy=BY1; yy<=BY2; yy++)
101 if (xx >= x1 && xx <= x2 && yy >= y1 && yy <= y2)
102 DrawScreenField(xx, yy);
105 if (setup.direct_draw)
106 SetDrawtoField(DRAW_DIRECT);
109 if (setup.soft_scrolling)
111 int fx = FX, fy = FY;
113 fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
114 fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0);
116 BlitBitmap(fieldbuffer, backbuffer, fx,fy, SXSIZE,SYSIZE, SX,SY);
120 BlitBitmap(drawto, window, x, y, width, height, x, y);
126 DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
128 if (setup.direct_draw && game_status == PLAYING)
129 redraw_mask &= ~REDRAW_MAIN;
131 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
132 redraw_mask |= REDRAW_FIELD;
134 if (redraw_mask & REDRAW_FIELD)
135 redraw_mask &= ~REDRAW_TILES;
137 if (redraw_mask == REDRAW_NONE)
140 if (global.fps_slowdown && game_status == PLAYING)
142 static boolean last_frame_skipped = FALSE;
143 boolean skip_even_when_not_scrolling = TRUE;
144 boolean just_scrolling = (ScreenMovDir != 0);
145 boolean verbose = FALSE;
147 if (global.fps_slowdown_factor > 1 &&
148 (FrameCounter % global.fps_slowdown_factor) &&
149 (just_scrolling || skip_even_when_not_scrolling))
151 redraw_mask &= ~REDRAW_MAIN;
153 last_frame_skipped = TRUE;
156 printf("FRAME SKIPPED\n");
160 if (last_frame_skipped)
161 redraw_mask |= REDRAW_FIELD;
163 last_frame_skipped = FALSE;
166 printf("frame not skipped\n");
170 /* synchronize X11 graphics at this point; if we would synchronize the
171 display immediately after the buffer switching (after the XFlush),
172 this could mean that we have to wait for the graphics to complete,
173 although we could go on doing calculations for the next frame */
177 if (redraw_mask & REDRAW_ALL)
179 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
183 if (redraw_mask & REDRAW_FIELD)
185 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
187 BlitBitmap(backbuffer, window,
188 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
192 int fx = FX, fy = FY;
194 if (setup.soft_scrolling)
196 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
197 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
200 if (setup.soft_scrolling ||
201 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
202 ABS(ScreenMovPos) == ScrollStepSize ||
203 redraw_tiles > REDRAWTILES_THRESHOLD)
205 BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
209 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
211 (setup.soft_scrolling ?
212 "setup.soft_scrolling" :
213 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
214 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
215 ABS(ScreenGfxPos) == ScrollStepSize ?
216 "ABS(ScreenGfxPos) == ScrollStepSize" :
217 "redraw_tiles > REDRAWTILES_THRESHOLD"));
223 redraw_mask &= ~REDRAW_MAIN;
226 if (redraw_mask & REDRAW_DOORS)
228 if (redraw_mask & REDRAW_DOOR_1)
229 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
230 if (redraw_mask & REDRAW_DOOR_2)
232 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
233 BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
236 if (redraw_mask & REDRAW_VIDEO_1)
237 BlitBitmap(backbuffer, window,
238 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
239 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
240 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
241 if (redraw_mask & REDRAW_VIDEO_2)
242 BlitBitmap(backbuffer, window,
243 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
244 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
245 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
246 if (redraw_mask & REDRAW_VIDEO_3)
247 BlitBitmap(backbuffer, window,
248 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
249 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
250 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
253 if (redraw_mask & REDRAW_DOOR_3)
254 BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
255 redraw_mask &= ~REDRAW_DOORS;
258 if (redraw_mask & REDRAW_MICROLEVEL)
260 BlitBitmap(backbuffer, window,
261 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
262 MICROLEV_XPOS, MICROLEV_YPOS);
263 BlitBitmap(backbuffer, window,
264 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
265 SX, MICROLABEL_YPOS);
266 redraw_mask &= ~REDRAW_MICROLEVEL;
269 if (redraw_mask & REDRAW_TILES)
271 for(x=0; x<SCR_FIELDX; x++)
272 for(y=0; y<SCR_FIELDY; y++)
273 if (redraw[redraw_x1 + x][redraw_y1 + y])
274 BlitBitmap(buffer, window,
275 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
276 SX + x * TILEX, SY + y * TILEY);
279 if (redraw_mask & REDRAW_FPS) /* display frames per second */
284 sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
285 if (!global.fps_slowdown)
288 sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
289 DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
294 for(x=0; x<MAX_BUF_XSIZE; x++)
295 for(y=0; y<MAX_BUF_YSIZE; y++)
298 redraw_mask = REDRAW_NONE;
304 long fading_delay = 300;
306 if (setup.fading && (redraw_mask & REDRAW_FIELD))
313 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
316 for(i=0;i<2*FULL_SYSIZE;i++)
318 for(y=0;y<FULL_SYSIZE;y++)
320 BlitBitmap(backbuffer, window,
321 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
329 for(i=1;i<FULL_SYSIZE;i+=2)
330 BlitBitmap(backbuffer, window,
331 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
337 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
338 BlitBitmapMasked(backbuffer, window,
339 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
344 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
345 BlitBitmapMasked(backbuffer, window,
346 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
351 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
352 BlitBitmapMasked(backbuffer, window,
353 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
358 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
359 BlitBitmapMasked(backbuffer, window,
360 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
365 redraw_mask &= ~REDRAW_MAIN;
374 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
376 if (setup.soft_scrolling && game_status == PLAYING)
378 ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
379 SetDrawtoField(DRAW_BUFFERED);
382 SetDrawtoField(DRAW_BACKBUFFER);
384 if (setup.direct_draw && game_status == PLAYING)
386 ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
387 SetDrawtoField(DRAW_DIRECT);
390 redraw_mask |= REDRAW_FIELD;
393 void MarkTileDirty(int x, int y)
395 int xx = redraw_x1 + x;
396 int yy = redraw_y1 + y;
401 redraw[xx][yy] = TRUE;
402 redraw_mask |= REDRAW_TILES;
405 void SetBorderElement()
409 BorderElement = EL_LEERRAUM;
411 for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
413 for(x=0; x<lev_fieldx; x++)
415 if (!IS_MASSIVE(Feld[x][y]))
416 BorderElement = EL_BETON;
418 if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
424 void DrawAllPlayers()
428 for(i=0; i<MAX_PLAYERS; i++)
429 if (stored_player[i].active)
430 DrawPlayer(&stored_player[i]);
433 void DrawPlayerField(int x, int y)
435 if (!IS_PLAYER(x, y))
438 DrawPlayer(PLAYERINFO(x, y));
441 void DrawPlayer(struct PlayerInfo *player)
443 int jx = player->jx, jy = player->jy;
444 int last_jx = player->last_jx, last_jy = player->last_jy;
445 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
446 int sx = SCREENX(jx), sy = SCREENY(jy);
447 int sxx = 0, syy = 0;
448 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
450 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
452 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
456 if (!IN_LEV_FIELD(jx,jy))
458 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
459 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
460 printf("DrawPlayerField(): This should never happen!\n");
465 if (element == EL_EXPLODING)
468 /* draw things in the field the player is leaving, if needed */
470 if (player_is_moving)
472 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
474 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
475 if (last_element == EL_DYNAMITE_ACTIVE)
476 DrawDynamite(last_jx, last_jy);
478 DrawLevelFieldThruMask(last_jx, last_jy);
480 else if (last_element == EL_DYNAMITE_ACTIVE)
481 DrawDynamite(last_jx, last_jy);
483 DrawLevelField(last_jx, last_jy);
485 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
489 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
490 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
492 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
495 DrawLevelField(next_jx, next_jy);
499 if (!IN_SCR_FIELD(sx, sy))
502 if (setup.direct_draw)
503 SetDrawtoField(DRAW_BUFFERED);
505 /* draw things behind the player, if needed */
508 DrawLevelElement(jx, jy, Store[jx][jy]);
509 else if (!IS_ACTIVE_BOMB(element))
510 DrawLevelField(jx, jy);
512 DrawLevelElement(jx, jy, EL_LEERRAUM);
514 /* draw player himself */
516 if (game.emulation == EMU_SUPAPLEX)
518 static int last_dir = MV_LEFT;
519 int action = (player->programmed_action ? player->programmed_action :
521 boolean action_moving =
523 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
524 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
526 graphic = GFX_SP_MURPHY;
530 if (player->MovDir == MV_LEFT)
531 graphic = GFX_MURPHY_PUSH_LEFT;
532 else if (player->MovDir == MV_RIGHT)
533 graphic = GFX_MURPHY_PUSH_RIGHT;
534 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
535 graphic = GFX_MURPHY_PUSH_LEFT;
536 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
537 graphic = GFX_MURPHY_PUSH_RIGHT;
539 else if (player->snapped)
541 if (player->MovDir == MV_LEFT)
542 graphic = GFX_MURPHY_SNAP_LEFT;
543 else if (player->MovDir == MV_RIGHT)
544 graphic = GFX_MURPHY_SNAP_RIGHT;
545 else if (player->MovDir == MV_UP)
546 graphic = GFX_MURPHY_SNAP_UP;
547 else if (player->MovDir == MV_DOWN)
548 graphic = GFX_MURPHY_SNAP_DOWN;
550 else if (action_moving)
552 if (player->MovDir == MV_LEFT)
553 graphic = GFX_MURPHY_GO_LEFT;
554 else if (player->MovDir == MV_RIGHT)
555 graphic = GFX_MURPHY_GO_RIGHT;
556 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
557 graphic = GFX_MURPHY_GO_LEFT;
558 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
559 graphic = GFX_MURPHY_GO_RIGHT;
561 graphic = GFX_MURPHY_GO_LEFT;
563 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
566 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
567 last_dir = player->MovDir;
571 if (player->MovDir == MV_LEFT)
573 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
574 else if (player->MovDir == MV_RIGHT)
576 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
577 else if (player->MovDir == MV_UP)
578 graphic = GFX_SPIELER1_UP;
579 else /* MV_DOWN || MV_NO_MOVING */
580 graphic = GFX_SPIELER1_DOWN;
582 graphic += player->index_nr * 3 * HEROES_PER_LINE;
583 graphic += player->Frame;
588 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
589 sxx = player->GfxPos;
591 syy = player->GfxPos;
594 if (!setup.soft_scrolling && ScreenMovPos)
597 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
599 if (SHIELD_ON(player))
601 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
602 GFX2_SHIELD_PASSIVE);
604 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
605 3, 8, ANIM_OSCILLATE);
608 if (player->Pushing && player->GfxPos)
610 int px = SCREENX(next_jx), py = SCREENY(next_jy);
612 if (element == EL_SOKOBAN_FELD_LEER ||
613 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
614 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
618 int element = Feld[next_jx][next_jy];
619 int graphic = el2gfx(element);
621 if ((element == EL_FELSBROCKEN ||
622 element == EL_SP_ZONK ||
623 element == EL_BD_ROCK) && sxx)
625 int phase = (player->GfxPos / (TILEX / 4));
627 if (player->MovDir == MV_LEFT)
630 graphic += (phase + 4) % 4;
633 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
637 /* draw things in front of player (active dynamite or dynabombs) */
639 if (IS_ACTIVE_BOMB(element))
641 graphic = el2gfx(element);
643 if (element == EL_DYNAMITE_ACTIVE)
645 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
650 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
654 if (game.emulation == EMU_SUPAPLEX)
655 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
657 DrawGraphicThruMask(sx, sy, graphic + phase);
660 if (player_is_moving && last_element == EL_EXPLODING)
662 int phase = Frame[last_jx][last_jy];
666 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
667 GFX_EXPLOSION + ((phase - 1) / delay - 1));
670 /* draw elements that stay over the player */
671 /* handle the field the player is leaving ... */
672 if (player_is_moving && IS_OVER_PLAYER(last_element))
673 DrawLevelField(last_jx, last_jy);
674 /* ... and the field the player is entering */
675 if (IS_OVER_PLAYER(element))
676 DrawLevelField(jx, jy);
678 if (setup.direct_draw)
680 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
681 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
682 int x_size = TILEX * (1 + ABS(jx - last_jx));
683 int y_size = TILEY * (1 + ABS(jy - last_jy));
685 BlitBitmap(drawto_field, window,
686 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
687 SetDrawtoField(DRAW_DIRECT);
690 MarkTileDirty(sx,sy);
693 static int getGraphicAnimationPhase(int frames, int delay, int mode)
697 if (mode == ANIM_OSCILLATE)
699 int max_anim_frames = 2 * frames - 2;
700 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
701 phase = (phase < frames ? phase : max_anim_frames - phase);
704 phase = (FrameCounter % (delay * frames)) / delay;
706 if (mode == ANIM_REVERSE)
712 void DrawGraphicAnimationExt(int x, int y, int graphic,
713 int frames, int delay, int mode, int mask_mode)
715 int phase = getGraphicAnimationPhase(frames, delay, mode);
717 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
719 if (mask_mode == USE_MASKING)
720 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
722 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
726 void DrawGraphicAnimation(int x, int y, int graphic,
727 int frames, int delay, int mode)
729 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
732 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
733 int frames, int delay, int mode)
735 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
738 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
741 int frames, int delay,
744 int phase = getGraphicAnimationPhase(frames, delay, mode);
746 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
749 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
751 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
753 graphic -= GFX_START_ROCKSSCREEN;
754 *bitmap_nr = PIX_BACK;
755 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
756 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
758 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
760 graphic -= GFX_START_ROCKSHEROES;
761 *bitmap_nr = PIX_HEROES;
762 *x = (graphic % HEROES_PER_LINE) * TILEX;
763 *y = (graphic / HEROES_PER_LINE) * TILEY;
765 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
767 graphic -= GFX_START_ROCKSSP;
769 *x = (graphic % SP_PER_LINE) * TILEX;
770 *y = (graphic / SP_PER_LINE) * TILEY;
772 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
774 graphic -= GFX_START_ROCKSDC;
776 *x = (graphic % DC_PER_LINE) * TILEX;
777 *y = (graphic / DC_PER_LINE) * TILEY;
779 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
781 graphic -= GFX_START_ROCKSMORE;
782 *bitmap_nr = PIX_MORE;
783 *x = (graphic % MORE_PER_LINE) * TILEX;
784 *y = (graphic / MORE_PER_LINE) * TILEY;
786 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
788 graphic -= GFX_START_ROCKSFONT;
789 *bitmap_nr = PIX_BIGFONT;
790 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
791 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
792 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
802 void DrawGraphic(int x, int y, int graphic)
805 if (!IN_SCR_FIELD(x,y))
807 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
808 printf("DrawGraphic(): This should never happen!\n");
813 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
817 void DrawGraphicExt(DrawBuffer *bitmap, int x, int y, int graphic)
822 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
823 BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
826 void DrawGraphicThruMask(int x, int y, int graphic)
829 if (!IN_SCR_FIELD(x,y))
831 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
832 printf("DrawGraphicThruMask(): This should never happen!\n");
837 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
841 void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
849 if (graphic == GFX_LEERRAUM)
852 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
853 src_bitmap = pix[bitmap_nr];
854 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
856 if (tile_clipmask[tile] != None)
858 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
859 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
860 BlitBitmapMasked(src_bitmap, d,
861 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
867 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
871 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
872 BlitBitmapMasked(src_bitmap, d,
873 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
877 void DrawMiniGraphic(int x, int y, int graphic)
879 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
880 MarkTileDirty(x/2, y/2);
883 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
885 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
887 graphic -= GFX_START_ROCKSSCREEN;
888 *bitmap = pix[PIX_BACK];
889 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
890 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
892 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
894 graphic -= GFX_START_ROCKSSP;
895 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
896 *bitmap = pix[PIX_SP];
897 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
898 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
900 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
902 graphic -= GFX_START_ROCKSDC;
903 *bitmap = pix[PIX_DC];
904 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
905 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
907 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
909 graphic -= GFX_START_ROCKSMORE;
910 *bitmap = pix[PIX_MORE];
911 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
912 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
914 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
916 graphic -= GFX_START_ROCKSFONT;
917 *bitmap = pix[PIX_SMALLFONT];
918 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
919 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
920 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
924 *bitmap = pix[PIX_SP];
930 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
935 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
936 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
939 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
940 int cut_mode, int mask_mode)
942 int width = TILEX, height = TILEY;
944 int src_x, src_y, dest_x, dest_y;
952 DrawGraphic(x, y, graphic);
956 if (dx || dy) /* Verschiebung der Grafik? */
958 if (x < BX1) /* Element kommt von links ins Bild */
965 else if (x > BX2) /* Element kommt von rechts ins Bild */
971 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
977 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
979 else if (dx) /* allg. Bewegung in x-Richtung */
980 MarkTileDirty(x + SIGN(dx), y);
982 if (y < BY1) /* Element kommt von oben ins Bild */
984 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
992 else if (y > BY2) /* Element kommt von unten ins Bild */
998 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1004 else if (dy > 0 && cut_mode == CUT_ABOVE)
1006 if (y == BY2) /* Element unterhalb des Bildes */
1012 MarkTileDirty(x, y + 1);
1013 } /* Element verläßt unten das Bild */
1014 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1016 else if (dy) /* allg. Bewegung in y-Richtung */
1017 MarkTileDirty(x, y + SIGN(dy));
1020 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1021 src_bitmap = pix[bitmap_nr];
1022 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
1027 dest_x = FX + x * TILEX + dx;
1028 dest_y = FY + y * TILEY + dy;
1031 if (!IN_SCR_FIELD(x,y))
1033 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1034 printf("DrawGraphicShifted(): This should never happen!\n");
1039 if (mask_mode == USE_MASKING)
1041 if (tile_clipmask[tile] != None)
1043 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1044 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1045 BlitBitmapMasked(src_bitmap, drawto_field,
1046 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1052 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1056 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1057 BlitBitmapMasked(src_bitmap, drawto_field,
1058 src_x, src_y, width, height, dest_x, dest_y);
1062 BlitBitmap(pix[bitmap_nr], drawto_field,
1063 src_x, src_y, width, height, dest_x, dest_y);
1068 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1071 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1074 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1075 int cut_mode, int mask_mode)
1077 int ux = LEVELX(x), uy = LEVELY(y);
1078 int graphic = el2gfx(element);
1079 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1080 int phase4 = phase8 / 2;
1081 int phase2 = phase8 / 4;
1082 int dir = MovDir[ux][uy];
1084 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1086 graphic += 4 * !phase2;
1090 else if (dir == MV_LEFT)
1092 else if (dir == MV_DOWN)
1095 else if (element == EL_SP_SNIKSNAK)
1098 graphic = GFX_SP_SNIKSNAK_LEFT;
1099 else if (dir == MV_RIGHT)
1100 graphic = GFX_SP_SNIKSNAK_RIGHT;
1101 else if (dir == MV_UP)
1102 graphic = GFX_SP_SNIKSNAK_UP;
1104 graphic = GFX_SP_SNIKSNAK_DOWN;
1106 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1108 else if (element == EL_SP_ELECTRON)
1110 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1112 else if (element == EL_MOLE || element == EL_PINGUIN ||
1113 element == EL_SCHWEIN || element == EL_DRACHE)
1116 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1117 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1118 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1119 else if (dir == MV_RIGHT)
1120 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1121 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1122 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1123 else if (dir == MV_UP)
1124 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1125 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1126 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1128 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1129 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1130 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1134 else if (element == EL_SONDE)
1136 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1138 else if (element == EL_SALZSAEURE)
1140 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1142 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1146 else if (element == EL_BALLOON)
1150 else if ((element == EL_FELSBROCKEN ||
1151 element == EL_SP_ZONK ||
1152 element == EL_BD_ROCK ||
1153 element == EL_SP_INFOTRON ||
1157 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1159 if (element == EL_FELSBROCKEN ||
1160 element == EL_SP_ZONK ||
1161 element == EL_BD_ROCK)
1164 graphic += (4 - phase4) % 4;
1165 else if (dir == MV_RIGHT)
1168 graphic += phase2 * 2;
1170 else if (element != EL_SP_INFOTRON)
1174 else if (element == EL_MAGIC_WALL_EMPTY ||
1175 element == EL_MAGIC_WALL_EMPTYING ||
1176 element == EL_MAGIC_WALL_BD_EMPTY ||
1177 element == EL_MAGIC_WALL_BD_EMPTYING ||
1178 element == EL_MAGIC_WALL_FULL ||
1179 element == EL_MAGIC_WALL_BD_FULL)
1181 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1183 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1185 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1186 graphic += (x + 2 * y + 4) % 4;
1188 else if (element == EL_MAUER_LEBT)
1190 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1192 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1193 links_massiv = TRUE;
1194 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1195 rechts_massiv = TRUE;
1197 if (links_massiv && rechts_massiv)
1198 graphic = GFX_MAUERWERK;
1199 else if (links_massiv)
1200 graphic = GFX_MAUER_R;
1201 else if (rechts_massiv)
1202 graphic = GFX_MAUER_L;
1204 else if ((element == EL_INVISIBLE_STEEL ||
1205 element == EL_UNSICHTBAR ||
1206 element == EL_SAND_INVISIBLE) && game.light_time_left)
1208 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1209 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1210 GFX_SAND_INVISIBLE_ON);
1214 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1215 else if (mask_mode == USE_MASKING)
1216 DrawGraphicThruMask(x, y, graphic);
1218 DrawGraphic(x, y, graphic);
1221 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1222 int cut_mode, int mask_mode)
1224 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1225 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1226 cut_mode, mask_mode);
1229 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1232 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1235 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1238 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1241 void DrawScreenElementThruMask(int x, int y, int element)
1243 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1246 void DrawLevelElementThruMask(int x, int y, int element)
1248 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1251 void DrawLevelFieldThruMask(int x, int y)
1253 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1256 void ErdreichAnbroeckeln(int x, int y)
1258 int i, width, height, cx,cy;
1259 int ux = LEVELX(x), uy = LEVELY(y);
1260 int element, graphic;
1262 static int xy[4][2] =
1270 if (!IN_LEV_FIELD(ux, uy))
1273 element = Feld[ux][uy];
1275 if (element == EL_ERDREICH ||
1276 element == EL_LANDMINE ||
1277 element == EL_TRAP_INACTIVE ||
1278 element == EL_TRAP_ACTIVE)
1280 if (!IN_SCR_FIELD(x, y))
1283 graphic = GFX_ERDENRAND;
1289 uxx = ux + xy[i][0];
1290 uyy = uy + xy[i][1];
1291 if (!IN_LEV_FIELD(uxx, uyy))
1294 element = Feld[uxx][uyy];
1296 if (element == EL_ERDREICH ||
1297 element == EL_LANDMINE ||
1298 element == EL_TRAP_INACTIVE ||
1299 element == EL_TRAP_ACTIVE)
1302 if (i == 1 || i == 2)
1306 cx = (i == 2 ? TILEX - snip : 0);
1314 cy = (i == 3 ? TILEY - snip : 0);
1317 BlitBitmap(pix[PIX_BACK], drawto_field,
1318 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1319 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1320 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1323 MarkTileDirty(x, y);
1327 graphic = GFX_ERDENRAND;
1331 int xx, yy, uxx, uyy;
1335 uxx = ux + xy[i][0];
1336 uyy = uy + xy[i][1];
1338 if (!IN_LEV_FIELD(uxx, uyy) ||
1339 (Feld[uxx][uyy] != EL_ERDREICH &&
1340 Feld[uxx][uyy] != EL_LANDMINE &&
1341 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1342 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1343 !IN_SCR_FIELD(xx, yy))
1346 if (i == 1 || i == 2)
1350 cx = (i == 1 ? TILEX - snip : 0);
1358 cy = (i==0 ? TILEY-snip : 0);
1361 BlitBitmap(pix[PIX_BACK], drawto_field,
1362 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1363 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1364 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1366 MarkTileDirty(xx, yy);
1371 void DrawScreenElement(int x, int y, int element)
1373 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1374 ErdreichAnbroeckeln(x, y);
1377 void DrawLevelElement(int x, int y, int element)
1379 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1380 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1383 void DrawScreenField(int x, int y)
1385 int ux = LEVELX(x), uy = LEVELY(y);
1386 int element, content;
1388 if (!IN_LEV_FIELD(ux, uy))
1390 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1391 element = EL_LEERRAUM;
1393 element = BorderElement;
1395 DrawScreenElement(x, y, element);
1399 element = Feld[ux][uy];
1400 content = Store[ux][uy];
1402 if (IS_MOVING(ux, uy))
1404 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1405 boolean cut_mode = NO_CUTTING;
1407 if (element == EL_QUICKSAND_EMPTYING ||
1408 element == EL_MAGIC_WALL_EMPTYING ||
1409 element == EL_MAGIC_WALL_BD_EMPTYING ||
1410 element == EL_AMOEBA_DRIPPING)
1411 cut_mode = CUT_ABOVE;
1412 else if (element == EL_QUICKSAND_FILLING ||
1413 element == EL_MAGIC_WALL_FILLING ||
1414 element == EL_MAGIC_WALL_BD_FILLING)
1415 cut_mode = CUT_BELOW;
1417 if (cut_mode == CUT_ABOVE)
1418 DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1420 DrawScreenElement(x, y, EL_LEERRAUM);
1423 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1424 else if (cut_mode == NO_CUTTING)
1425 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1427 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1429 if (content == EL_SALZSAEURE)
1430 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1432 else if (IS_BLOCKED(ux, uy))
1437 boolean cut_mode = NO_CUTTING;
1438 int element_old, content_old;
1440 Blocked2Moving(ux, uy, &oldx, &oldy);
1443 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1444 MovDir[oldx][oldy] == MV_RIGHT);
1446 element_old = Feld[oldx][oldy];
1447 content_old = Store[oldx][oldy];
1449 if (element_old == EL_QUICKSAND_EMPTYING ||
1450 element_old == EL_MAGIC_WALL_EMPTYING ||
1451 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1452 element_old == EL_AMOEBA_DRIPPING)
1453 cut_mode = CUT_ABOVE;
1455 DrawScreenElement(x, y, EL_LEERRAUM);
1458 DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1460 else if (cut_mode == NO_CUTTING)
1461 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1464 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
1467 else if (IS_DRAWABLE(element))
1468 DrawScreenElement(x, y, element);
1470 DrawScreenElement(x, y, EL_LEERRAUM);
1473 void DrawLevelField(int x, int y)
1475 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1476 DrawScreenField(SCREENX(x), SCREENY(y));
1477 else if (IS_MOVING(x, y))
1481 Moving2Blocked(x, y, &newx, &newy);
1482 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1483 DrawScreenField(SCREENX(newx), SCREENY(newy));
1485 else if (IS_BLOCKED(x, y))
1489 Blocked2Moving(x, y, &oldx, &oldy);
1490 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1491 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1495 void DrawMiniElement(int x, int y, int element)
1501 DrawMiniGraphic(x, y, -1);
1505 graphic = el2gfx(element);
1506 DrawMiniGraphic(x, y, graphic);
1509 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1511 int x = sx + scroll_x, y = sy + scroll_y;
1513 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1514 DrawMiniElement(sx, sy, EL_LEERRAUM);
1515 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1516 DrawMiniElement(sx, sy, Feld[x][y]);
1519 int steel_type, steel_position;
1522 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1523 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1524 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1525 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1526 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1527 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1530 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1531 steel_position = (x == -1 && y == -1 ? 0 :
1532 x == lev_fieldx && y == -1 ? 1 :
1533 x == -1 && y == lev_fieldy ? 2 :
1534 x == lev_fieldx && y == lev_fieldy ? 3 :
1535 x == -1 || x == lev_fieldx ? 4 :
1536 y == -1 || y == lev_fieldy ? 5 : -1);
1538 if (steel_position != -1)
1539 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1543 void DrawMicroElement(int xpos, int ypos, int element)
1547 if (element == EL_LEERRAUM)
1550 graphic = el2gfx(element);
1552 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1554 graphic -= GFX_START_ROCKSSP;
1555 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1556 BlitBitmap(pix[PIX_SP], drawto,
1557 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1558 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1559 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1561 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1563 graphic -= GFX_START_ROCKSDC;
1564 BlitBitmap(pix[PIX_DC], drawto,
1565 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1566 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1567 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1569 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1571 graphic -= GFX_START_ROCKSMORE;
1572 BlitBitmap(pix[PIX_MORE], drawto,
1573 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1574 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1575 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1578 BlitBitmap(pix[PIX_BACK], drawto,
1579 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1580 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1581 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1590 for(x=BX1; x<=BX2; x++)
1591 for(y=BY1; y<=BY2; y++)
1592 DrawScreenField(x, y);
1594 redraw_mask |= REDRAW_FIELD;
1597 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1601 for(x=0; x<size_x; x++)
1602 for(y=0; y<size_y; y++)
1603 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1605 redraw_mask |= REDRAW_FIELD;
1608 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1612 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1614 if (lev_fieldx < STD_LEV_FIELDX)
1615 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1616 if (lev_fieldy < STD_LEV_FIELDY)
1617 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1619 xpos += MICRO_TILEX;
1620 ypos += MICRO_TILEY;
1622 for(x=-1; x<=STD_LEV_FIELDX; x++)
1624 for(y=-1; y<=STD_LEV_FIELDY; y++)
1626 int lx = from_x + x, ly = from_y + y;
1628 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1629 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1631 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1632 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1637 redraw_mask |= REDRAW_MICROLEVEL;
1640 #define MICROLABEL_EMPTY 0
1641 #define MICROLABEL_LEVEL_NAME 1
1642 #define MICROLABEL_CREATED_BY 2
1643 #define MICROLABEL_LEVEL_AUTHOR 3
1644 #define MICROLABEL_IMPORTED_FROM 4
1645 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1647 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1649 static void DrawMicroLevelLabelExt(int mode)
1651 char label_text[MAX_MICROLABEL_SIZE + 1];
1653 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1655 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1656 mode == MICROLABEL_CREATED_BY ? "created by" :
1657 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1658 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1659 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1660 leveldir_current->imported_from : ""),
1661 MAX_MICROLABEL_SIZE);
1662 label_text[MAX_MICROLABEL_SIZE] = '\0';
1664 if (strlen(label_text) > 0)
1666 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1667 int lypos = MICROLABEL_YPOS;
1669 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1672 redraw_mask |= REDRAW_MICROLEVEL;
1675 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1677 static unsigned long scroll_delay = 0;
1678 static unsigned long label_delay = 0;
1679 static int from_x, from_y, scroll_direction;
1680 static int label_state, label_counter;
1684 from_x = from_y = 0;
1685 scroll_direction = MV_RIGHT;
1689 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1690 DrawMicroLevelLabelExt(label_state);
1692 /* initialize delay counters */
1693 DelayReached(&scroll_delay, 0);
1694 DelayReached(&label_delay, 0);
1699 /* scroll micro level, if needed */
1700 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1701 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1703 switch (scroll_direction)
1709 scroll_direction = MV_UP;
1713 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1716 scroll_direction = MV_DOWN;
1723 scroll_direction = MV_RIGHT;
1727 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1730 scroll_direction = MV_LEFT;
1737 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1740 /* redraw micro level label, if needed */
1741 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1742 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1743 strcmp(level.author, leveldir_current->name) != 0 &&
1744 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1746 int max_label_counter = 23;
1748 if (leveldir_current->imported_from != NULL)
1749 max_label_counter += 14;
1751 label_counter = (label_counter + 1) % max_label_counter;
1752 label_state = (label_counter >= 0 && label_counter <= 7 ?
1753 MICROLABEL_LEVEL_NAME :
1754 label_counter >= 9 && label_counter <= 12 ?
1755 MICROLABEL_CREATED_BY :
1756 label_counter >= 14 && label_counter <= 21 ?
1757 MICROLABEL_LEVEL_AUTHOR :
1758 label_counter >= 23 && label_counter <= 26 ?
1759 MICROLABEL_IMPORTED_FROM :
1760 label_counter >= 28 && label_counter <= 35 ?
1761 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1762 DrawMicroLevelLabelExt(label_state);
1766 int REQ_in_range(int x, int y)
1768 if (y > DY+249 && y < DY+278)
1770 if (x > DX+1 && x < DX+48)
1772 else if (x > DX+51 && x < DX+98)
1778 #define MAX_REQUEST_LINES 13
1779 #define MAX_REQUEST_LINE_LEN 7
1781 boolean Request(char *text, unsigned int req_state)
1783 int mx, my, ty, result = -1;
1784 unsigned int old_door_state;
1786 #if defined(PLATFORM_UNIX)
1787 /* pause network game while waiting for request to answer */
1788 if (options.network &&
1789 game_status == PLAYING &&
1790 req_state & REQUEST_WAIT_FOR)
1791 SendToServer_PausePlaying();
1794 old_door_state = GetDoorState();
1798 CloseDoor(DOOR_CLOSE_1);
1800 /* save old door content */
1801 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1802 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1803 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1805 /* clear door drawing field */
1806 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1808 /* write text for request */
1809 for(ty=0; ty < MAX_REQUEST_LINES; ty++)
1811 char text_line[MAX_REQUEST_LINE_LEN + 1];
1817 for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
1820 if (!tc || tc == ' ')
1831 strncpy(text_line, text, tl);
1834 DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
1835 text_line, FS_SMALL, FC_YELLOW);
1837 text += tl + (tc == ' ' ? 1 : 0);
1840 if (req_state & REQ_ASK)
1842 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1843 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1845 else if (req_state & REQ_CONFIRM)
1847 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1849 else if (req_state & REQ_PLAYER)
1851 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1852 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1853 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1854 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1857 /* copy request gadgets to door backbuffer */
1858 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1859 DX, DY, DXSIZE, DYSIZE,
1860 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1862 OpenDoor(DOOR_OPEN_1);
1868 if (!(req_state & REQUEST_WAIT_FOR))
1871 if (game_status != MAINMENU)
1874 button_status = MB_RELEASED;
1876 request_gadget_id = -1;
1888 case EVENT_BUTTONPRESS:
1889 case EVENT_BUTTONRELEASE:
1890 case EVENT_MOTIONNOTIFY:
1892 if (event.type == EVENT_MOTIONNOTIFY)
1894 if (!PointerInWindow(window))
1895 continue; /* window and pointer are on different screens */
1900 motion_status = TRUE;
1901 mx = ((MotionEvent *) &event)->x;
1902 my = ((MotionEvent *) &event)->y;
1906 motion_status = FALSE;
1907 mx = ((ButtonEvent *) &event)->x;
1908 my = ((ButtonEvent *) &event)->y;
1909 if (event.type == EVENT_BUTTONPRESS)
1910 button_status = ((ButtonEvent *) &event)->button;
1912 button_status = MB_RELEASED;
1915 /* this sets 'request_gadget_id' */
1916 HandleGadgets(mx, my, button_status);
1918 switch(request_gadget_id)
1920 case TOOL_CTRL_ID_YES:
1923 case TOOL_CTRL_ID_NO:
1926 case TOOL_CTRL_ID_CONFIRM:
1927 result = TRUE | FALSE;
1930 case TOOL_CTRL_ID_PLAYER_1:
1933 case TOOL_CTRL_ID_PLAYER_2:
1936 case TOOL_CTRL_ID_PLAYER_3:
1939 case TOOL_CTRL_ID_PLAYER_4:
1950 case EVENT_KEYPRESS:
1951 switch(GetEventKey((KeyEvent *)&event, TRUE))
1964 if (req_state & REQ_PLAYER)
1968 case EVENT_KEYRELEASE:
1969 ClearPlayerAction();
1973 HandleOtherEvents(&event);
1977 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1979 int joy = AnyJoystick();
1981 if (joy & JOY_BUTTON_1)
1983 else if (joy & JOY_BUTTON_2)
1989 /* don't eat all CPU time */
1993 if (game_status != MAINMENU)
1998 if (!(req_state & REQ_STAY_OPEN))
2000 CloseDoor(DOOR_CLOSE_1);
2002 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2004 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2005 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2006 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2007 OpenDoor(DOOR_OPEN_1);
2013 #if defined(PLATFORM_UNIX)
2014 /* continue network game after request */
2015 if (options.network &&
2016 game_status == PLAYING &&
2017 req_state & REQUEST_WAIT_FOR)
2018 SendToServer_ContinuePlaying();
2024 unsigned int OpenDoor(unsigned int door_state)
2026 unsigned int new_door_state;
2028 if (door_state & DOOR_COPY_BACK)
2030 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2031 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2032 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2033 door_state &= ~DOOR_COPY_BACK;
2036 new_door_state = MoveDoor(door_state);
2038 return(new_door_state);
2041 unsigned int CloseDoor(unsigned int door_state)
2043 unsigned int new_door_state;
2045 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2046 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2047 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2048 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2050 new_door_state = MoveDoor(door_state);
2052 return(new_door_state);
2055 unsigned int GetDoorState()
2057 return MoveDoor(DOOR_GET_STATE);
2060 unsigned int SetDoorState(unsigned int door_state)
2062 return MoveDoor(door_state | DOOR_SET_STATE);
2065 unsigned int MoveDoor(unsigned int door_state)
2067 static int door1 = DOOR_OPEN_1;
2068 static int door2 = DOOR_CLOSE_2;
2069 static unsigned long door_delay = 0;
2070 int x, start, stepsize = 2;
2071 unsigned long door_delay_value = stepsize * 5;
2073 if (door_state == DOOR_GET_STATE)
2074 return(door1 | door2);
2076 if (door_state & DOOR_SET_STATE)
2078 if (door_state & DOOR_ACTION_1)
2079 door1 = door_state & DOOR_ACTION_1;
2080 if (door_state & DOOR_ACTION_2)
2081 door2 = door_state & DOOR_ACTION_2;
2083 return(door1 | door2);
2086 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2087 door_state &= ~DOOR_OPEN_1;
2088 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2089 door_state &= ~DOOR_CLOSE_1;
2090 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2091 door_state &= ~DOOR_OPEN_2;
2092 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2093 door_state &= ~DOOR_CLOSE_2;
2095 if (setup.quick_doors)
2098 door_delay_value = 0;
2099 StopSound(SND_OEFFNEN);
2102 if (door_state & DOOR_ACTION)
2104 if (!(door_state & DOOR_NO_DELAY))
2105 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2107 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2109 for(x=start; x<=DXSIZE; x+=stepsize)
2111 Bitmap *bitmap = pix[PIX_DOOR];
2112 GC gc = bitmap->stored_clip_gc;
2114 WaitUntilDelayReached(&door_delay, door_delay_value);
2116 if (door_state & DOOR_ACTION_1)
2118 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2119 int j = (DXSIZE - i) / 3;
2121 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2122 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2123 DXSIZE,DYSIZE - i/2, DX, DY);
2125 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2127 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2128 BlitBitmapMasked(bitmap, drawto,
2129 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2130 DX + DXSIZE - i, DY + j);
2131 BlitBitmapMasked(bitmap, drawto,
2132 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2133 DX + DXSIZE - i, DY + 140 + j);
2134 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2135 BlitBitmapMasked(bitmap, drawto,
2136 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2138 BlitBitmapMasked(bitmap, drawto,
2139 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2142 BlitBitmapMasked(bitmap, drawto,
2143 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2145 BlitBitmapMasked(bitmap, drawto,
2146 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2148 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2149 BlitBitmapMasked(bitmap, drawto,
2150 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2151 DX + DXSIZE - i, DY + 77 + j);
2152 BlitBitmapMasked(bitmap, drawto,
2153 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2154 DX + DXSIZE - i, DY + 203 + j);
2156 redraw_mask |= REDRAW_DOOR_1;
2159 if (door_state & DOOR_ACTION_2)
2161 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2162 int j = (VXSIZE - i) / 3;
2164 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2165 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2166 VXSIZE, VYSIZE - i/2, VX, VY);
2168 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2170 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2171 BlitBitmapMasked(bitmap, drawto,
2172 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2173 VX + VXSIZE-i, VY+j);
2174 SetClipOrigin(bitmap, gc,
2175 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2176 BlitBitmapMasked(bitmap, drawto,
2177 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2180 BlitBitmapMasked(bitmap, drawto,
2181 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2182 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2183 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2184 BlitBitmapMasked(bitmap, drawto,
2185 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2187 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2189 redraw_mask |= REDRAW_DOOR_2;
2194 if (game_status == MAINMENU)
2199 if (setup.quick_doors)
2200 StopSound(SND_OEFFNEN);
2202 if (door_state & DOOR_ACTION_1)
2203 door1 = door_state & DOOR_ACTION_1;
2204 if (door_state & DOOR_ACTION_2)
2205 door2 = door_state & DOOR_ACTION_2;
2207 return (door1 | door2);
2210 void DrawSpecialEditorDoor()
2212 /* draw bigger toolbox window */
2213 BlitBitmap(pix[PIX_DOOR], drawto,
2214 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2216 redraw_mask |= REDRAW_ALL;
2219 void UndrawSpecialEditorDoor()
2221 /* draw normal tape recorder window */
2222 BlitBitmap(pix[PIX_BACK], drawto,
2223 562, 344, 108, 56, EX - 4, EY - 12);
2225 redraw_mask |= REDRAW_ALL;
2229 int ReadPixel(DrawBuffer *bitmap, int x, int y)
2231 XImage *pixel_image;
2232 unsigned long pixel_value;
2234 pixel_image = XGetImage(display, bitmap->drawable,
2235 x, y, 1, 1, AllPlanes, ZPixmap);
2236 pixel_value = XGetPixel(pixel_image, 0, 0);
2238 XDestroyImage(pixel_image);
2244 /* ---------- new tool button stuff ---------------------------------------- */
2246 /* graphic position values for tool buttons */
2247 #define TOOL_BUTTON_YES_XPOS 2
2248 #define TOOL_BUTTON_YES_YPOS 250
2249 #define TOOL_BUTTON_YES_GFX_YPOS 0
2250 #define TOOL_BUTTON_YES_XSIZE 46
2251 #define TOOL_BUTTON_YES_YSIZE 28
2252 #define TOOL_BUTTON_NO_XPOS 52
2253 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2254 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2255 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2256 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2257 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2258 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2259 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2260 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2261 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2262 #define TOOL_BUTTON_PLAYER_XSIZE 30
2263 #define TOOL_BUTTON_PLAYER_YSIZE 30
2264 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2265 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2266 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2267 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2268 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2269 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2270 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2271 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2272 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2273 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2274 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2275 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2276 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2277 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2278 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2279 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2280 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2281 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2282 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2283 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2292 } toolbutton_info[NUM_TOOL_BUTTONS] =
2295 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2296 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2297 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2302 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2303 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2304 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2309 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2310 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2311 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2312 TOOL_CTRL_ID_CONFIRM,
2316 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2317 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2318 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2319 TOOL_CTRL_ID_PLAYER_1,
2323 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2324 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2325 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2326 TOOL_CTRL_ID_PLAYER_2,
2330 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2331 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2332 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2333 TOOL_CTRL_ID_PLAYER_3,
2337 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2338 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2339 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2340 TOOL_CTRL_ID_PLAYER_4,
2345 void CreateToolButtons()
2349 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2351 Bitmap *gd_bitmap = pix[PIX_DOOR];
2352 Bitmap *deco_bitmap = None;
2353 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2354 struct GadgetInfo *gi;
2355 unsigned long event_mask;
2356 int gd_xoffset, gd_yoffset;
2357 int gd_x1, gd_x2, gd_y;
2360 event_mask = GD_EVENT_RELEASED;
2362 gd_xoffset = toolbutton_info[i].xpos;
2363 gd_yoffset = toolbutton_info[i].ypos;
2364 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2365 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2366 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2368 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2370 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2371 &deco_bitmap, &deco_x, &deco_y);
2372 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2373 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2376 gi = CreateGadget(GDI_CUSTOM_ID, id,
2377 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2378 GDI_X, DX + toolbutton_info[i].x,
2379 GDI_Y, DY + toolbutton_info[i].y,
2380 GDI_WIDTH, toolbutton_info[i].width,
2381 GDI_HEIGHT, toolbutton_info[i].height,
2382 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2383 GDI_STATE, GD_BUTTON_UNPRESSED,
2384 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2385 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2386 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2387 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2388 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2389 GDI_DECORATION_SHIFTING, 1, 1,
2390 GDI_EVENT_MASK, event_mask,
2391 GDI_CALLBACK_ACTION, HandleToolButtons,
2395 Error(ERR_EXIT, "cannot create gadget");
2397 tool_gadget[id] = gi;
2401 static void UnmapToolButtons()
2405 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2406 UnmapGadget(tool_gadget[i]);
2409 static void HandleToolButtons(struct GadgetInfo *gi)
2411 request_gadget_id = gi->custom_id;
2414 int get_next_element(int element)
2418 case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
2419 case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
2420 case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
2421 case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
2422 case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
2423 case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
2424 case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
2426 default: return element;
2430 int el2gfx(int element)
2434 case EL_LEERRAUM: return -1;
2435 case EL_ERDREICH: return GFX_ERDREICH;
2436 case EL_MAUERWERK: return GFX_MAUERWERK;
2437 case EL_FELSBODEN: return GFX_FELSBODEN;
2438 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2439 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2440 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2441 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2442 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2443 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2444 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2445 case EL_SPIELER1: return GFX_SPIELER1;
2446 case EL_SPIELER2: return GFX_SPIELER2;
2447 case EL_SPIELER3: return GFX_SPIELER3;
2448 case EL_SPIELER4: return GFX_SPIELER4;
2449 case EL_KAEFER: return GFX_KAEFER;
2450 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2451 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2452 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2453 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2454 case EL_FLIEGER: return GFX_FLIEGER;
2455 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2456 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2457 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2458 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2459 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2460 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2461 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2462 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2463 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2464 case EL_FIREFLY: return GFX_FIREFLY;
2465 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2466 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2467 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2468 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2469 case EL_MAMPFER: return GFX_MAMPFER;
2470 case EL_ROBOT: return GFX_ROBOT;
2471 case EL_BETON: return GFX_BETON;
2472 case EL_DIAMANT: return GFX_DIAMANT;
2473 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2474 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2475 case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
2476 case EL_TROPFEN: return GFX_TROPFEN;
2477 case EL_BOMBE: return GFX_BOMBE;
2478 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2479 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2480 case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
2481 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2482 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2483 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2484 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2485 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2486 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2487 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2488 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2489 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2490 case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
2491 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2492 case EL_LIFE: return GFX_LIFE;
2493 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2494 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2495 case EL_BADEWANNE: return GFX_BADEWANNE;
2496 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2497 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2498 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2499 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2500 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2501 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2502 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2503 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2504 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2505 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2506 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2507 case EL_PFORTE1: return GFX_PFORTE1;
2508 case EL_PFORTE2: return GFX_PFORTE2;
2509 case EL_PFORTE3: return GFX_PFORTE3;
2510 case EL_PFORTE4: return GFX_PFORTE4;
2511 case EL_PFORTE1X: return GFX_PFORTE1X;
2512 case EL_PFORTE2X: return GFX_PFORTE2X;
2513 case EL_PFORTE3X: return GFX_PFORTE3X;
2514 case EL_PFORTE4X: return GFX_PFORTE4X;
2515 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2516 case EL_PACMAN: return GFX_PACMAN;
2517 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2518 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2519 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2520 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2521 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2522 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2523 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2524 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2525 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2526 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2527 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2528 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2529 case EL_MAUER_X: return GFX_MAUER_X;
2530 case EL_MAUER_Y: return GFX_MAUER_Y;
2531 case EL_MAUER_XY: return GFX_MAUER_XY;
2532 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2533 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2534 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2535 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2536 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2537 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2538 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2539 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2540 case EL_MAMPFER2: return GFX_MAMPFER2;
2541 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2542 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2543 case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
2544 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2545 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2546 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2547 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2548 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2549 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2550 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2551 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2552 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2553 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2554 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2555 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2556 case EL_MOLE: return GFX_MOLE;
2557 case EL_PINGUIN: return GFX_PINGUIN;
2558 case EL_SCHWEIN: return GFX_SCHWEIN;
2559 case EL_DRACHE: return GFX_DRACHE;
2560 case EL_SONDE: return GFX_SONDE;
2561 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2562 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2563 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2564 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2565 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2566 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2567 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2568 case EL_SP_ZONK: return GFX_SP_ZONK;
2569 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2570 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2571 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2572 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2573 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2574 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2575 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2576 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2577 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2578 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2579 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2580 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2581 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2582 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2583 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2584 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2585 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2586 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2587 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2588 case EL_PEARL: return GFX_PEARL;
2589 case EL_CRYSTAL: return GFX_CRYSTAL;
2590 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2591 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2592 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2593 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2594 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2595 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2596 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2597 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2598 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2599 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2600 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2601 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2602 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2603 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2604 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2605 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2606 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2607 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2608 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2609 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2610 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2611 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2612 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2613 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2614 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2615 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2616 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2617 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2618 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2619 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2620 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2621 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2622 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2623 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2624 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2625 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2626 case EL_LANDMINE: return GFX_LANDMINE;
2627 case EL_ENVELOPE: return GFX_ENVELOPE;
2628 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2629 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2630 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2631 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2632 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2633 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2634 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2635 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2636 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2637 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2638 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2639 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2640 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2641 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2642 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2643 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2644 case EL_MOLE_UP: return GFX_MOLE_UP;
2645 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2646 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2647 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2648 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2649 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2650 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2651 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2652 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2653 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2654 case EL_BALLOON: return GFX_BALLOON;
2655 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2656 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2657 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2658 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2659 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2660 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2661 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2662 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2663 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2664 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2665 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2666 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2667 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2668 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2669 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2670 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2671 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2672 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2673 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2674 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2675 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2676 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2677 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2678 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2679 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2680 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2681 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2682 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2683 case EL_SPRING: return GFX_SPRING;
2684 case EL_SPRING_MOVING: return GFX_SPRING;
2685 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2686 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2687 case EL_BD_WALL: return GFX_BD_WALL;
2688 case EL_BD_ROCK: return GFX_BD_ROCK;
2689 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2690 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2694 if (IS_CHAR(element))
2695 return GFX_CHAR_START + (element - EL_CHAR_START);
2696 else if (element >= EL_SP_START && element <= EL_SP_END)
2698 int nr_element = element - EL_SP_START;
2699 int gfx_per_line = 8;
2701 (nr_element / gfx_per_line) * SP_PER_LINE +
2702 (nr_element % gfx_per_line);
2704 return GFX_START_ROCKSSP + nr_graphic;