1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include "libgame/libgame.h"
23 /* tool button identifiers */
24 #define TOOL_CTRL_ID_YES 0
25 #define TOOL_CTRL_ID_NO 1
26 #define TOOL_CTRL_ID_CONFIRM 2
27 #define TOOL_CTRL_ID_PLAYER_1 3
28 #define TOOL_CTRL_ID_PLAYER_2 4
29 #define TOOL_CTRL_ID_PLAYER_3 5
30 #define TOOL_CTRL_ID_PLAYER_4 6
32 #define NUM_TOOL_BUTTONS 7
34 /* forward declaration for internal use */
35 static int getGraphicAnimationPhase(int, int, int);
36 static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
38 static void UnmapToolButtons();
39 static void HandleToolButtons(struct GadgetInfo *);
41 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
42 static int request_gadget_id = -1;
44 void SetDrawtoField(int mode)
46 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
57 drawto_field = fieldbuffer;
59 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
70 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
74 void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
76 if (game_status == PLAYING)
82 width = gfx.sxsize + 2 * TILEX;
83 height = gfx.sysize + 2 * TILEY;
86 if (force_redraw || setup.direct_draw)
89 int x1 = (x - SX) / TILEX, y1 = (y - SY) / TILEY;
90 int x2 = (x - SX + width) / TILEX, y2 = (y - SY + height) / TILEY;
92 if (setup.direct_draw)
93 SetDrawtoField(DRAW_BACKBUFFER);
95 for(xx=BX1; xx<=BX2; xx++)
96 for(yy=BY1; yy<=BY2; yy++)
97 if (xx >= x1 && xx <= x2 && yy >= y1 && yy <= y2)
98 DrawScreenField(xx, yy);
101 if (setup.direct_draw)
102 SetDrawtoField(DRAW_DIRECT);
105 if (setup.soft_scrolling)
107 int fx = FX, fy = FY;
109 fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
110 fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0);
112 BlitBitmap(fieldbuffer, backbuffer, fx,fy, SXSIZE,SYSIZE, SX,SY);
116 BlitBitmap(drawto, window, x, y, width, height, x, y);
122 DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
124 if (setup.direct_draw && game_status == PLAYING)
125 redraw_mask &= ~REDRAW_MAIN;
127 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
128 redraw_mask |= REDRAW_FIELD;
130 if (redraw_mask & REDRAW_FIELD)
131 redraw_mask &= ~REDRAW_TILES;
133 if (redraw_mask == REDRAW_NONE)
136 if (global.fps_slowdown && game_status == PLAYING)
138 static boolean last_frame_skipped = FALSE;
139 boolean skip_even_when_not_scrolling = TRUE;
140 boolean just_scrolling = (ScreenMovDir != 0);
141 boolean verbose = FALSE;
143 if (global.fps_slowdown_factor > 1 &&
144 (FrameCounter % global.fps_slowdown_factor) &&
145 (just_scrolling || skip_even_when_not_scrolling))
147 redraw_mask &= ~REDRAW_MAIN;
149 last_frame_skipped = TRUE;
152 printf("FRAME SKIPPED\n");
156 if (last_frame_skipped)
157 redraw_mask |= REDRAW_FIELD;
159 last_frame_skipped = FALSE;
162 printf("frame not skipped\n");
166 /* synchronize X11 graphics at this point; if we would synchronize the
167 display immediately after the buffer switching (after the XFlush),
168 this could mean that we have to wait for the graphics to complete,
169 although we could go on doing calculations for the next frame */
173 if (redraw_mask & REDRAW_ALL)
175 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
179 if (redraw_mask & REDRAW_FIELD)
181 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
183 BlitBitmap(backbuffer, window,
184 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
188 int fx = FX, fy = FY;
190 if (setup.soft_scrolling)
192 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
193 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
196 if (setup.soft_scrolling ||
197 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
198 ABS(ScreenMovPos) == ScrollStepSize ||
199 redraw_tiles > REDRAWTILES_THRESHOLD)
201 BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
205 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
207 (setup.soft_scrolling ?
208 "setup.soft_scrolling" :
209 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
210 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
211 ABS(ScreenGfxPos) == ScrollStepSize ?
212 "ABS(ScreenGfxPos) == ScrollStepSize" :
213 "redraw_tiles > REDRAWTILES_THRESHOLD"));
219 redraw_mask &= ~REDRAW_MAIN;
222 if (redraw_mask & REDRAW_DOORS)
224 if (redraw_mask & REDRAW_DOOR_1)
225 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
226 if (redraw_mask & REDRAW_DOOR_2)
228 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
229 BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
232 if (redraw_mask & REDRAW_VIDEO_1)
233 BlitBitmap(backbuffer, window,
234 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
235 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
236 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
237 if (redraw_mask & REDRAW_VIDEO_2)
238 BlitBitmap(backbuffer, window,
239 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
240 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
241 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
242 if (redraw_mask & REDRAW_VIDEO_3)
243 BlitBitmap(backbuffer, window,
244 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
245 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
246 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
249 if (redraw_mask & REDRAW_DOOR_3)
250 BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
251 redraw_mask &= ~REDRAW_DOORS;
254 if (redraw_mask & REDRAW_MICROLEVEL)
256 BlitBitmap(backbuffer, window,
257 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
258 MICROLEV_XPOS, MICROLEV_YPOS);
259 BlitBitmap(backbuffer, window,
260 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
261 SX, MICROLABEL_YPOS);
262 redraw_mask &= ~REDRAW_MICROLEVEL;
265 if (redraw_mask & REDRAW_TILES)
267 for(x=0; x<SCR_FIELDX; x++)
268 for(y=0; y<SCR_FIELDY; y++)
269 if (redraw[redraw_x1 + x][redraw_y1 + y])
270 BlitBitmap(buffer, window,
271 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
272 SX + x * TILEX, SY + y * TILEY);
275 if (redraw_mask & REDRAW_FPS) /* display frames per second */
280 sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
281 if (!global.fps_slowdown)
284 sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
285 DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
290 for(x=0; x<MAX_BUF_XSIZE; x++)
291 for(y=0; y<MAX_BUF_YSIZE; y++)
294 redraw_mask = REDRAW_NONE;
300 long fading_delay = 300;
302 if (setup.fading && (redraw_mask & REDRAW_FIELD))
309 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
312 for(i=0;i<2*FULL_SYSIZE;i++)
314 for(y=0;y<FULL_SYSIZE;y++)
316 BlitBitmap(backbuffer, window,
317 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
325 for(i=1;i<FULL_SYSIZE;i+=2)
326 BlitBitmap(backbuffer, window,
327 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
333 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
334 BlitBitmapMasked(backbuffer, window,
335 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
340 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
341 BlitBitmapMasked(backbuffer, window,
342 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
347 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
348 BlitBitmapMasked(backbuffer, window,
349 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
354 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
355 BlitBitmapMasked(backbuffer, window,
356 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
361 redraw_mask &= ~REDRAW_MAIN;
370 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
372 if (setup.soft_scrolling && game_status == PLAYING)
374 ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
375 SetDrawtoField(DRAW_BUFFERED);
378 SetDrawtoField(DRAW_BACKBUFFER);
380 if (setup.direct_draw && game_status == PLAYING)
382 ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
383 SetDrawtoField(DRAW_DIRECT);
386 redraw_mask |= REDRAW_FIELD;
389 void MarkTileDirty(int x, int y)
391 int xx = redraw_x1 + x;
392 int yy = redraw_y1 + y;
397 redraw[xx][yy] = TRUE;
398 redraw_mask |= REDRAW_TILES;
401 void SetBorderElement()
405 BorderElement = EL_LEERRAUM;
407 for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
409 for(x=0; x<lev_fieldx; x++)
411 if (!IS_MASSIVE(Feld[x][y]))
412 BorderElement = EL_BETON;
414 if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
420 void DrawAllPlayers()
424 for(i=0; i<MAX_PLAYERS; i++)
425 if (stored_player[i].active)
426 DrawPlayer(&stored_player[i]);
429 void DrawPlayerField(int x, int y)
431 if (!IS_PLAYER(x, y))
434 DrawPlayer(PLAYERINFO(x, y));
437 void DrawPlayer(struct PlayerInfo *player)
439 int jx = player->jx, jy = player->jy;
440 int last_jx = player->last_jx, last_jy = player->last_jy;
441 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
442 int sx = SCREENX(jx), sy = SCREENY(jy);
443 int sxx = 0, syy = 0;
444 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
446 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
448 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
452 if (!IN_LEV_FIELD(jx,jy))
454 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
455 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
456 printf("DrawPlayerField(): This should never happen!\n");
461 if (element == EL_EXPLODING)
464 /* draw things in the field the player is leaving, if needed */
466 if (player_is_moving)
468 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
470 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
471 if (last_element == EL_DYNAMITE_ACTIVE)
472 DrawDynamite(last_jx, last_jy);
474 DrawLevelFieldThruMask(last_jx, last_jy);
476 else if (last_element == EL_DYNAMITE_ACTIVE)
477 DrawDynamite(last_jx, last_jy);
479 DrawLevelField(last_jx, last_jy);
481 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
485 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
486 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
488 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
491 DrawLevelField(next_jx, next_jy);
495 if (!IN_SCR_FIELD(sx, sy))
498 if (setup.direct_draw)
499 SetDrawtoField(DRAW_BUFFERED);
501 /* draw things behind the player, if needed */
504 DrawLevelElement(jx, jy, Store[jx][jy]);
505 else if (!IS_ACTIVE_BOMB(element))
506 DrawLevelField(jx, jy);
508 DrawLevelElement(jx, jy, EL_LEERRAUM);
510 /* draw player himself */
512 if (game.emulation == EMU_SUPAPLEX)
514 static int last_dir = MV_LEFT;
515 int action = (player->programmed_action ? player->programmed_action :
517 boolean action_moving =
519 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
520 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
522 graphic = GFX_SP_MURPHY;
526 if (player->MovDir == MV_LEFT)
527 graphic = GFX_MURPHY_PUSH_LEFT;
528 else if (player->MovDir == MV_RIGHT)
529 graphic = GFX_MURPHY_PUSH_RIGHT;
530 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
531 graphic = GFX_MURPHY_PUSH_LEFT;
532 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
533 graphic = GFX_MURPHY_PUSH_RIGHT;
535 else if (player->snapped)
537 if (player->MovDir == MV_LEFT)
538 graphic = GFX_MURPHY_SNAP_LEFT;
539 else if (player->MovDir == MV_RIGHT)
540 graphic = GFX_MURPHY_SNAP_RIGHT;
541 else if (player->MovDir == MV_UP)
542 graphic = GFX_MURPHY_SNAP_UP;
543 else if (player->MovDir == MV_DOWN)
544 graphic = GFX_MURPHY_SNAP_DOWN;
546 else if (action_moving)
548 if (player->MovDir == MV_LEFT)
549 graphic = GFX_MURPHY_GO_LEFT;
550 else if (player->MovDir == MV_RIGHT)
551 graphic = GFX_MURPHY_GO_RIGHT;
552 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
553 graphic = GFX_MURPHY_GO_LEFT;
554 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
555 graphic = GFX_MURPHY_GO_RIGHT;
557 graphic = GFX_MURPHY_GO_LEFT;
559 graphic += getGraphicAnimationPhase(3, 2, ANIM_PINGPONG);
562 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
563 last_dir = player->MovDir;
567 if (player->MovDir == MV_LEFT)
569 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
570 else if (player->MovDir == MV_RIGHT)
572 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
573 else if (player->MovDir == MV_UP)
574 graphic = GFX_SPIELER1_UP;
575 else /* MV_DOWN || MV_NO_MOVING */
576 graphic = GFX_SPIELER1_DOWN;
578 graphic += player->index_nr * 3 * HEROES_PER_LINE;
579 graphic += player->Frame;
584 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
585 sxx = player->GfxPos;
587 syy = player->GfxPos;
590 if (!setup.soft_scrolling && ScreenMovPos)
593 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
595 if (SHIELD_ON(player))
597 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
598 GFX2_SHIELD_PASSIVE);
600 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
601 3, 8, ANIM_PINGPONG);
604 if (player->Pushing && player->GfxPos)
606 int px = SCREENX(next_jx), py = SCREENY(next_jy);
608 if (element == EL_SOKOBAN_FELD_LEER ||
609 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
610 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
614 int element = Feld[next_jx][next_jy];
615 int graphic = el2gfx(element);
617 if ((element == EL_FELSBROCKEN ||
618 element == EL_SP_ZONK ||
619 element == EL_BD_ROCK) && sxx)
621 int phase = (player->GfxPos / (TILEX / 4));
623 if (player->MovDir == MV_LEFT)
626 graphic += (phase + 4) % 4;
629 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
633 /* draw things in front of player (active dynamite or dynabombs) */
635 if (IS_ACTIVE_BOMB(element))
637 graphic = el2gfx(element);
639 if (element == EL_DYNAMITE_ACTIVE)
641 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
646 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
650 if (game.emulation == EMU_SUPAPLEX)
651 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
653 DrawGraphicThruMask(sx, sy, graphic + phase);
656 if (player_is_moving && last_element == EL_EXPLODING)
658 int phase = Frame[last_jx][last_jy];
662 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
663 GFX_EXPLOSION + ((phase - 1) / delay - 1));
666 /* draw elements that stay over the player */
667 /* handle the field the player is leaving ... */
668 if (player_is_moving && IS_OVER_PLAYER(last_element))
669 DrawLevelField(last_jx, last_jy);
670 /* ... and the field the player is entering */
671 if (IS_OVER_PLAYER(element))
672 DrawLevelField(jx, jy);
674 if (setup.direct_draw)
676 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
677 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
678 int x_size = TILEX * (1 + ABS(jx - last_jx));
679 int y_size = TILEY * (1 + ABS(jy - last_jy));
681 BlitBitmap(drawto_field, window,
682 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
683 SetDrawtoField(DRAW_DIRECT);
686 MarkTileDirty(sx,sy);
689 static int getGraphicAnimationPhase(int frames, int delay, int mode)
693 if (mode == ANIM_PINGPONG)
695 int max_anim_frames = 2 * frames - 2;
697 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
698 phase = (phase < frames ? phase : max_anim_frames - phase);
701 phase = (FrameCounter % (delay * frames)) / delay;
703 if (mode == ANIM_REVERSE)
709 static int getNewGraphicAnimationFrame(int graphic)
711 int frames = new_graphic_info[graphic].anim_frames;
712 int delay = new_graphic_info[graphic].anim_delay;
713 int mode = new_graphic_info[graphic].anim_mode;
716 if (mode == ANIM_PINGPONG)
718 int max_anim_frames = 2 * frames - 2;
720 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
721 phase = (phase < frames ? phase : max_anim_frames - phase);
724 phase = (FrameCounter % (delay * frames)) / delay;
726 if (mode == ANIM_REVERSE)
727 phase = (frames - 1) - phase;
732 void DrawGraphicAnimationExt(int x, int y, int graphic,
733 int frames, int delay, int mode, int mask_mode)
735 int phase = getGraphicAnimationPhase(frames, delay, mode);
737 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
739 if (mask_mode == USE_MASKING)
740 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
742 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
746 void DrawNewGraphicAnimationExt(int x, int y, int graphic, int mask_mode)
748 int delay = new_graphic_info[graphic].anim_delay;
750 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
752 int frame = getNewGraphicAnimationFrame(graphic);
754 if (mask_mode == USE_MASKING)
755 DrawNewGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame);
757 DrawNewGraphic(SCREENX(x), SCREENY(y), graphic, frame);
761 void DrawGraphicAnimation(int x, int y, int graphic,
762 int frames, int delay, int mode)
764 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
767 void DrawNewGraphicAnimation(int x, int y, int graphic)
769 DrawNewGraphicAnimationExt(x, y, graphic, NO_MASKING);
772 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
773 int frames, int delay, int mode)
775 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
778 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
781 int frames, int delay,
784 int phase = getGraphicAnimationPhase(frames, delay, mode);
786 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
789 void getGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
791 if (graphic >= 0 && graphic_info[graphic].bitmap != NULL)
793 *bitmap = graphic_info[graphic].bitmap;
794 *x = graphic_info[graphic].src_x;
795 *y = graphic_info[graphic].src_y;
797 else if (graphic >= GFX_START_ROCKSELEMENTS &&
798 graphic <= GFX_END_ROCKSELEMENTS)
800 graphic -= GFX_START_ROCKSELEMENTS;
801 *bitmap = pix[PIX_ELEMENTS];
802 *x = (graphic % GFX_PER_LINE) * TILEX;
803 *y = (graphic / GFX_PER_LINE) * TILEY;
805 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
807 graphic -= GFX_START_ROCKSHEROES;
808 *bitmap = pix[PIX_HEROES];
809 *x = (graphic % HEROES_PER_LINE) * TILEX;
810 *y = (graphic / HEROES_PER_LINE) * TILEY;
812 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
814 graphic -= GFX_START_ROCKSSP;
815 *bitmap = pix[PIX_SP];
816 *x = (graphic % SP_PER_LINE) * TILEX;
817 *y = (graphic / SP_PER_LINE) * TILEY;
819 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
821 graphic -= GFX_START_ROCKSDC;
822 *bitmap = pix[PIX_DC];
823 *x = (graphic % DC_PER_LINE) * TILEX;
824 *y = (graphic / DC_PER_LINE) * TILEY;
826 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
828 graphic -= GFX_START_ROCKSMORE;
829 *bitmap = pix[PIX_MORE];
830 *x = (graphic % MORE_PER_LINE) * TILEX;
831 *y = (graphic / MORE_PER_LINE) * TILEY;
833 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
835 graphic -= GFX_START_ROCKSFONT;
836 *bitmap = pix[PIX_FONT_EM];
837 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
838 *y = (graphic / FONT_CHARS_PER_LINE) * TILEY;
842 *bitmap = pix[PIX_SP];
848 void DrawGraphic(int x, int y, int graphic)
851 if (!IN_SCR_FIELD(x, y))
853 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic);
854 printf("DrawGraphic(): This should never happen!\n");
859 DrawGraphicExt(drawto_field, FX + x * TILEX, FY + y * TILEY, graphic);
863 void DrawNewGraphic(int x, int y, int graphic, int frame)
866 if (!IN_SCR_FIELD(x, y))
868 printf("DrawNewGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic);
869 printf("DrawNewGraphic(): This should never happen!\n");
874 DrawNewGraphicExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
879 void DrawGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic)
884 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
885 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
888 void DrawNewGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic,
891 Bitmap *src_bitmap = new_graphic_info[graphic].bitmap;
892 int src_x = new_graphic_info[graphic].src_x;
893 int src_y = new_graphic_info[graphic].src_y;
895 if (new_graphic_info[graphic].anim_vertical)
896 src_y += frame * TILEY;
898 src_x += frame * TILEX;
900 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
903 void DrawGraphicThruMask(int x, int y, int graphic)
906 if (!IN_SCR_FIELD(x, y))
908 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
909 printf("DrawGraphicThruMask(): This should never happen!\n");
914 DrawGraphicThruMaskExt(drawto_field, FX + x * TILEX, FY + y *TILEY, graphic);
918 void DrawNewGraphicThruMask(int x, int y, int graphic, int frame)
921 if (!IN_SCR_FIELD(x, y))
923 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
924 printf("DrawGraphicThruMask(): This should never happen!\n");
929 DrawNewGraphicThruMaskExt(drawto_field, FX + x * TILEX, FY + y *TILEY,
934 void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
941 if (graphic == GFX_LEERRAUM)
944 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
945 drawing_gc = src_bitmap->stored_clip_gc;
947 if (tile_clipmask[tile] != None)
949 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
950 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
951 BlitBitmapMasked(src_bitmap, d,
952 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
958 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
962 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
963 BlitBitmapMasked(src_bitmap, d,
964 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
968 void DrawNewGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y,
969 int graphic, int frame)
971 Bitmap *src_bitmap = new_graphic_info[graphic].bitmap;
972 GC drawing_gc = src_bitmap->stored_clip_gc;
973 int src_x = new_graphic_info[graphic].src_x;
974 int src_y = new_graphic_info[graphic].src_y;
976 if (new_graphic_info[graphic].anim_vertical)
977 src_y += frame * TILEY;
979 src_x += frame * TILEX;
981 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
982 BlitBitmapMasked(src_bitmap, d, src_x, src_y, TILEX, TILEY, dest_x, dest_y);
985 void DrawMiniGraphic(int x, int y, int graphic)
987 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
988 MarkTileDirty(x/2, y/2);
991 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
993 if (graphic >= GFX_START_ROCKSELEMENTS && graphic <= GFX_END_ROCKSELEMENTS)
995 graphic -= GFX_START_ROCKSELEMENTS;
996 *bitmap = pix[PIX_ELEMENTS];
997 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
998 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
1000 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1002 graphic -= GFX_START_ROCKSSP;
1003 *bitmap = pix[PIX_SP];
1004 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
1005 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
1007 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1009 graphic -= GFX_START_ROCKSDC;
1010 *bitmap = pix[PIX_DC];
1011 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
1012 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
1014 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1016 graphic -= GFX_START_ROCKSMORE;
1017 *bitmap = pix[PIX_MORE];
1018 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
1019 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
1021 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
1023 graphic -= GFX_START_ROCKSFONT;
1024 *bitmap = pix[PIX_FONT_EM];
1025 *x = MINI_FONT_STARTX + (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
1026 *y = MINI_FONT_STARTY + (graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE;
1030 *bitmap = pix[PIX_SP];
1031 *x = MINI_SP_STARTX;
1032 *y = MINI_SP_STARTY;
1036 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
1041 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
1042 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
1045 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
1046 int cut_mode, int mask_mode)
1048 int width = TILEX, height = TILEY;
1050 int src_x, src_y, dest_x, dest_y;
1057 DrawGraphic(x, y, graphic);
1061 if (dx || dy) /* Verschiebung der Grafik? */
1063 if (x < BX1) /* Element kommt von links ins Bild */
1070 else if (x > BX2) /* Element kommt von rechts ins Bild */
1076 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1082 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1084 else if (dx) /* allg. Bewegung in x-Richtung */
1085 MarkTileDirty(x + SIGN(dx), y);
1087 if (y < BY1) /* Element kommt von oben ins Bild */
1089 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1097 else if (y > BY2) /* Element kommt von unten ins Bild */
1103 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1109 else if (dy > 0 && cut_mode == CUT_ABOVE)
1111 if (y == BY2) /* Element unterhalb des Bildes */
1117 MarkTileDirty(x, y + 1);
1118 } /* Element verläßt unten das Bild */
1119 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1121 else if (dy) /* allg. Bewegung in y-Richtung */
1122 MarkTileDirty(x, y + SIGN(dy));
1125 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
1126 drawing_gc = src_bitmap->stored_clip_gc;
1131 dest_x = FX + x * TILEX + dx;
1132 dest_y = FY + y * TILEY + dy;
1135 if (!IN_SCR_FIELD(x,y))
1137 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1138 printf("DrawGraphicShifted(): This should never happen!\n");
1143 if (mask_mode == USE_MASKING)
1145 if (tile_clipmask[tile] != None)
1147 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1148 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1149 BlitBitmapMasked(src_bitmap, drawto_field,
1150 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1156 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1160 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1161 BlitBitmapMasked(src_bitmap, drawto_field,
1162 src_x, src_y, width, height, dest_x, dest_y);
1166 BlitBitmap(src_bitmap, drawto_field,
1167 src_x, src_y, width, height, dest_x, dest_y);
1172 void DrawNewGraphicShifted(int x,int y, int dx,int dy, int graphic, int frame,
1173 int cut_mode, int mask_mode)
1180 int width = TILEX, height = TILEY;
1186 DrawNewGraphic(x, y, graphic, frame);
1190 if (dx || dy) /* Verschiebung der Grafik? */
1192 if (x < BX1) /* Element kommt von links ins Bild */
1199 else if (x > BX2) /* Element kommt von rechts ins Bild */
1205 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1211 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1213 else if (dx) /* allg. Bewegung in x-Richtung */
1214 MarkTileDirty(x + SIGN(dx), y);
1216 if (y < BY1) /* Element kommt von oben ins Bild */
1218 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1226 else if (y > BY2) /* Element kommt von unten ins Bild */
1232 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1238 else if (dy > 0 && cut_mode == CUT_ABOVE)
1240 if (y == BY2) /* Element unterhalb des Bildes */
1246 MarkTileDirty(x, y + 1);
1247 } /* Element verläßt unten das Bild */
1248 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1250 else if (dy) /* allg. Bewegung in y-Richtung */
1251 MarkTileDirty(x, y + SIGN(dy));
1254 src_bitmap = new_graphic_info[graphic].bitmap;
1255 drawing_gc = src_bitmap->stored_clip_gc;
1256 src_x = new_graphic_info[graphic].src_x;
1257 src_y = new_graphic_info[graphic].src_y;
1259 if (new_graphic_info[graphic].anim_vertical)
1260 src_y += frame * TILEY;
1262 src_x += frame * TILEX;
1267 dest_x = FX + x * TILEX + dx;
1268 dest_y = FY + y * TILEY + dy;
1271 if (!IN_SCR_FIELD(x,y))
1273 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1274 printf("DrawGraphicShifted(): This should never happen!\n");
1279 if (mask_mode == USE_MASKING)
1280 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1282 BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
1288 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1291 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1294 void DrawNewGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1295 int frame, int cut_mode)
1297 DrawNewGraphicShifted(x,y, dx,dy, graphic, frame, cut_mode, USE_MASKING);
1300 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1301 int cut_mode, int mask_mode)
1303 int ux = LEVELX(x), uy = LEVELY(y);
1304 int graphic = el2gfx(element);
1305 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1306 int phase4 = phase8 / 2;
1307 int phase2 = phase8 / 4;
1308 int dir = MovDir[ux][uy];
1310 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1312 graphic += 1 * !phase2;
1316 else if (dir == MV_LEFT)
1318 else if (dir == MV_DOWN)
1321 else if (element == EL_SP_SNIKSNAK)
1324 graphic = GFX_SP_SNIKSNAK_LEFT;
1325 else if (dir == MV_RIGHT)
1326 graphic = GFX_SP_SNIKSNAK_RIGHT;
1327 else if (dir == MV_UP)
1328 graphic = GFX_SP_SNIKSNAK_UP;
1330 graphic = GFX_SP_SNIKSNAK_DOWN;
1332 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1334 else if (element == EL_SP_ELECTRON)
1336 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1338 else if (element == EL_MOLE || element == EL_PINGUIN ||
1339 element == EL_SCHWEIN || element == EL_DRACHE)
1342 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1343 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1344 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1345 else if (dir == MV_RIGHT)
1346 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1347 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1348 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1349 else if (dir == MV_UP)
1350 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1351 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1352 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1354 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1355 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1356 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1360 else if (element == EL_SONDE)
1362 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1364 else if (element == EL_SALZSAEURE)
1366 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1368 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1372 else if (element == EL_BALLOON)
1376 else if ((element == EL_FELSBROCKEN ||
1377 element == EL_SP_ZONK ||
1378 element == EL_BD_ROCK ||
1379 element == EL_SP_INFOTRON ||
1383 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1385 if (element == EL_FELSBROCKEN ||
1386 element == EL_SP_ZONK ||
1387 element == EL_BD_ROCK)
1390 graphic += (4 - phase4) % 4;
1391 else if (dir == MV_RIGHT)
1394 graphic += phase2 * 2;
1396 else if (element != EL_SP_INFOTRON)
1400 else if (element == EL_MAGIC_WALL_EMPTY ||
1401 element == EL_MAGIC_WALL_EMPTYING ||
1402 element == EL_MAGIC_WALL_BD_EMPTY ||
1403 element == EL_MAGIC_WALL_BD_EMPTYING ||
1404 element == EL_MAGIC_WALL_FULL ||
1405 element == EL_MAGIC_WALL_BD_FULL)
1407 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1409 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1411 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1412 graphic += (x + 2 * y + 4) % 4;
1414 else if (element == EL_MAUER_LEBT)
1416 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1418 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1419 links_massiv = TRUE;
1420 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1421 rechts_massiv = TRUE;
1423 if (links_massiv && rechts_massiv)
1424 graphic = GFX_MAUERWERK;
1425 else if (links_massiv)
1426 graphic = GFX_MAUER_R;
1427 else if (rechts_massiv)
1428 graphic = GFX_MAUER_L;
1430 else if ((element == EL_INVISIBLE_STEEL ||
1431 element == EL_UNSICHTBAR ||
1432 element == EL_SAND_INVISIBLE) && game.light_time_left)
1434 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1435 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1436 GFX_SAND_INVISIBLE_ON);
1440 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1441 else if (mask_mode == USE_MASKING)
1442 DrawGraphicThruMask(x, y, graphic);
1444 DrawGraphic(x, y, graphic);
1447 void DrawNewScreenElementExt(int x, int y, int dx, int dy, int element,
1448 int cut_mode, int mask_mode)
1450 int ux = LEVELX(x), uy = LEVELY(y);
1451 int dir = MovDir[ux][uy];
1452 int graphic = el_dir2img(element, dir);
1453 int frame = getNewGraphicAnimationFrame(graphic);
1454 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1455 int phase4 = phase8 / 2;
1456 int phase2 = phase8 / 4;
1458 if (element == EL_KAEFER)
1462 else if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1464 graphic += 1 * !phase2;
1468 else if (dir == MV_LEFT)
1470 else if (dir == MV_DOWN)
1473 else if (element == EL_SP_SNIKSNAK)
1476 graphic = GFX_SP_SNIKSNAK_LEFT;
1477 else if (dir == MV_RIGHT)
1478 graphic = GFX_SP_SNIKSNAK_RIGHT;
1479 else if (dir == MV_UP)
1480 graphic = GFX_SP_SNIKSNAK_UP;
1482 graphic = GFX_SP_SNIKSNAK_DOWN;
1484 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1486 else if (element == EL_SP_ELECTRON)
1489 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1491 graphic = GFX2_SP_ELECTRON + getNewGraphicAnimationFrame(graphic);
1494 else if (element == EL_MOLE || element == EL_PINGUIN ||
1495 element == EL_SCHWEIN || element == EL_DRACHE)
1498 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1499 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1500 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1501 else if (dir == MV_RIGHT)
1502 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1503 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1504 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1505 else if (dir == MV_UP)
1506 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1507 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1508 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1510 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1511 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1512 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1516 else if (element == EL_SONDE)
1519 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1521 graphic = GFX_SONDE_START + getNewGraphicAnimationFrame(graphic);
1524 else if (element == EL_SALZSAEURE)
1527 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1529 graphic = GFX_GEBLUBBER + getNewGraphicAnimationFrame(graphic);
1532 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1536 else if (element == EL_BALLOON)
1540 else if ((element == EL_FELSBROCKEN ||
1541 element == EL_SP_ZONK ||
1542 element == EL_BD_ROCK ||
1543 element == EL_SP_INFOTRON ||
1547 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1549 if (element == EL_FELSBROCKEN ||
1550 element == EL_SP_ZONK ||
1551 element == EL_BD_ROCK)
1554 graphic += (4 - phase4) % 4;
1555 else if (dir == MV_RIGHT)
1558 graphic += phase2 * 2;
1560 else if (element != EL_SP_INFOTRON)
1564 else if (element == EL_MAGIC_WALL_EMPTY ||
1565 element == EL_MAGIC_WALL_EMPTYING ||
1566 element == EL_MAGIC_WALL_BD_EMPTY ||
1567 element == EL_MAGIC_WALL_BD_EMPTYING ||
1568 element == EL_MAGIC_WALL_FULL ||
1569 element == EL_MAGIC_WALL_BD_FULL)
1572 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1574 graphic += 3 + getNewGraphicAnimationFrame(graphic);
1577 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1579 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1580 graphic += (x + 2 * y + 4) % 4;
1582 else if (element == EL_MAUER_LEBT)
1584 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1586 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1587 links_massiv = TRUE;
1588 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1589 rechts_massiv = TRUE;
1591 if (links_massiv && rechts_massiv)
1592 graphic = GFX_MAUERWERK;
1593 else if (links_massiv)
1594 graphic = GFX_MAUER_R;
1595 else if (rechts_massiv)
1596 graphic = GFX_MAUER_L;
1598 else if ((element == EL_INVISIBLE_STEEL ||
1599 element == EL_UNSICHTBAR ||
1600 element == EL_SAND_INVISIBLE) && game.light_time_left)
1602 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1603 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1604 GFX_SAND_INVISIBLE_ON);
1608 DrawNewGraphicShifted(x, y, dx, dy, graphic, frame, cut_mode, mask_mode);
1609 else if (mask_mode == USE_MASKING)
1610 DrawNewGraphicThruMask(x, y, graphic, frame);
1612 DrawNewGraphic(x, y, graphic, frame);
1615 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1616 int cut_mode, int mask_mode)
1618 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1619 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1620 cut_mode, mask_mode);
1623 void DrawNewLevelElementExt(int x, int y, int dx, int dy, int element,
1624 int cut_mode, int mask_mode)
1626 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1627 DrawNewScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1628 cut_mode, mask_mode);
1631 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1634 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1637 void DrawNewScreenElementShifted(int x, int y, int dx, int dy, int element,
1640 DrawNewScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1643 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1646 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1649 void DrawNewLevelElementShifted(int x, int y, int dx, int dy, int element,
1652 DrawNewLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1655 void DrawScreenElementThruMask(int x, int y, int element)
1657 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1660 void DrawNewScreenElementThruMask(int x, int y, int element)
1662 DrawNewScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1665 void DrawLevelElementThruMask(int x, int y, int element)
1667 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1670 void DrawNewLevelElementThruMask(int x, int y, int element)
1672 DrawNewLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1675 void DrawLevelFieldThruMask(int x, int y)
1677 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1680 void DrawNewLevelFieldThruMask(int x, int y)
1682 DrawNewLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1685 void ErdreichAnbroeckeln(int x, int y)
1689 int i, width, height, cx,cy;
1690 int ux = LEVELX(x), uy = LEVELY(y);
1691 int element, graphic;
1693 static int xy[4][2] =
1701 if (!IN_LEV_FIELD(ux, uy))
1704 element = Feld[ux][uy];
1706 if (element == EL_ERDREICH ||
1707 element == EL_LANDMINE ||
1708 element == EL_TRAP_INACTIVE ||
1709 element == EL_TRAP_ACTIVE)
1711 if (!IN_SCR_FIELD(x, y))
1714 graphic = GFX_ERDENRAND;
1716 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
1722 uxx = ux + xy[i][0];
1723 uyy = uy + xy[i][1];
1724 if (!IN_LEV_FIELD(uxx, uyy))
1727 element = Feld[uxx][uyy];
1729 if (element == EL_ERDREICH ||
1730 element == EL_LANDMINE ||
1731 element == EL_TRAP_INACTIVE ||
1732 element == EL_TRAP_ACTIVE)
1735 if (i == 1 || i == 2)
1739 cx = (i == 2 ? TILEX - snip : 0);
1747 cy = (i == 3 ? TILEY - snip : 0);
1750 BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
1751 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1754 MarkTileDirty(x, y);
1758 graphic = GFX_ERDENRAND;
1760 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
1764 int xx, yy, uxx, uyy;
1768 uxx = ux + xy[i][0];
1769 uyy = uy + xy[i][1];
1771 if (!IN_LEV_FIELD(uxx, uyy) ||
1772 (Feld[uxx][uyy] != EL_ERDREICH &&
1773 Feld[uxx][uyy] != EL_LANDMINE &&
1774 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1775 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1776 !IN_SCR_FIELD(xx, yy))
1779 if (i == 1 || i == 2)
1783 cx = (i == 1 ? TILEX - snip : 0);
1791 cy = (i==0 ? TILEY-snip : 0);
1794 BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
1795 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1797 MarkTileDirty(xx, yy);
1802 void DrawScreenElement(int x, int y, int element)
1804 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1805 ErdreichAnbroeckeln(x, y);
1808 void DrawNewScreenElement(int x, int y, int element)
1810 DrawNewScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1811 ErdreichAnbroeckeln(x, y);
1814 void DrawLevelElement(int x, int y, int element)
1816 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1817 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1820 void DrawNewLevelElement(int x, int y, int element)
1822 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1823 DrawNewScreenElement(SCREENX(x), SCREENY(y), element);
1826 void DrawScreenField(int x, int y)
1828 int ux = LEVELX(x), uy = LEVELY(y);
1829 int element, content;
1831 if (!IN_LEV_FIELD(ux, uy))
1833 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1834 element = EL_LEERRAUM;
1836 element = BorderElement;
1838 DrawScreenElement(x, y, element);
1842 element = Feld[ux][uy];
1843 content = Store[ux][uy];
1845 if (IS_MOVING(ux, uy))
1847 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1848 boolean cut_mode = NO_CUTTING;
1850 if (element == EL_QUICKSAND_EMPTYING ||
1851 element == EL_MAGIC_WALL_EMPTYING ||
1852 element == EL_MAGIC_WALL_BD_EMPTYING ||
1853 element == EL_AMOEBA_DRIPPING)
1854 cut_mode = CUT_ABOVE;
1855 else if (element == EL_QUICKSAND_FILLING ||
1856 element == EL_MAGIC_WALL_FILLING ||
1857 element == EL_MAGIC_WALL_BD_FILLING)
1858 cut_mode = CUT_BELOW;
1860 if (cut_mode == CUT_ABOVE)
1861 DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1863 DrawScreenElement(x, y, EL_LEERRAUM);
1866 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1867 else if (cut_mode == NO_CUTTING)
1868 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1870 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1872 if (content == EL_SALZSAEURE)
1873 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1875 else if (IS_BLOCKED(ux, uy))
1880 boolean cut_mode = NO_CUTTING;
1881 int element_old, content_old;
1883 Blocked2Moving(ux, uy, &oldx, &oldy);
1886 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1887 MovDir[oldx][oldy] == MV_RIGHT);
1889 element_old = Feld[oldx][oldy];
1890 content_old = Store[oldx][oldy];
1892 if (element_old == EL_QUICKSAND_EMPTYING ||
1893 element_old == EL_MAGIC_WALL_EMPTYING ||
1894 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1895 element_old == EL_AMOEBA_DRIPPING)
1896 cut_mode = CUT_ABOVE;
1898 DrawScreenElement(x, y, EL_LEERRAUM);
1901 DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1903 else if (cut_mode == NO_CUTTING)
1904 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1907 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
1910 else if (IS_DRAWABLE(element))
1911 DrawScreenElement(x, y, element);
1913 DrawScreenElement(x, y, EL_LEERRAUM);
1916 void DrawNewScreenField(int x, int y)
1918 int ux = LEVELX(x), uy = LEVELY(y);
1919 int element, content;
1921 if (!IN_LEV_FIELD(ux, uy))
1923 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1924 element = EL_LEERRAUM;
1926 element = BorderElement;
1928 DrawNewScreenElement(x, y, element);
1932 element = Feld[ux][uy];
1933 content = Store[ux][uy];
1935 if (IS_MOVING(ux, uy))
1937 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1938 boolean cut_mode = NO_CUTTING;
1940 if (element == EL_QUICKSAND_EMPTYING ||
1941 element == EL_MAGIC_WALL_EMPTYING ||
1942 element == EL_MAGIC_WALL_BD_EMPTYING ||
1943 element == EL_AMOEBA_DRIPPING)
1944 cut_mode = CUT_ABOVE;
1945 else if (element == EL_QUICKSAND_FILLING ||
1946 element == EL_MAGIC_WALL_FILLING ||
1947 element == EL_MAGIC_WALL_BD_FILLING)
1948 cut_mode = CUT_BELOW;
1950 if (cut_mode == CUT_ABOVE)
1951 DrawNewScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1953 DrawNewScreenElement(x, y, EL_LEERRAUM);
1956 DrawNewScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1957 else if (cut_mode == NO_CUTTING)
1958 DrawNewScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1960 DrawNewScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1962 if (content == EL_SALZSAEURE)
1963 DrawNewLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1965 else if (IS_BLOCKED(ux, uy))
1970 boolean cut_mode = NO_CUTTING;
1971 int element_old, content_old;
1973 Blocked2Moving(ux, uy, &oldx, &oldy);
1976 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1977 MovDir[oldx][oldy] == MV_RIGHT);
1979 element_old = Feld[oldx][oldy];
1980 content_old = Store[oldx][oldy];
1982 if (element_old == EL_QUICKSAND_EMPTYING ||
1983 element_old == EL_MAGIC_WALL_EMPTYING ||
1984 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1985 element_old == EL_AMOEBA_DRIPPING)
1986 cut_mode = CUT_ABOVE;
1988 DrawNewScreenElement(x, y, EL_LEERRAUM);
1991 DrawNewScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1993 else if (cut_mode == NO_CUTTING)
1994 DrawNewScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1997 DrawNewScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
2000 else if (IS_DRAWABLE(element))
2001 DrawNewScreenElement(x, y, element);
2003 DrawNewScreenElement(x, y, EL_LEERRAUM);
2006 void DrawLevelField(int x, int y)
2008 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
2009 DrawScreenField(SCREENX(x), SCREENY(y));
2010 else if (IS_MOVING(x, y))
2014 Moving2Blocked(x, y, &newx, &newy);
2015 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
2016 DrawScreenField(SCREENX(newx), SCREENY(newy));
2018 else if (IS_BLOCKED(x, y))
2022 Blocked2Moving(x, y, &oldx, &oldy);
2023 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
2024 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
2028 void DrawNewLevelField(int x, int y)
2030 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
2031 DrawNewScreenField(SCREENX(x), SCREENY(y));
2032 else if (IS_MOVING(x, y))
2036 Moving2Blocked(x, y, &newx, &newy);
2037 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
2038 DrawNewScreenField(SCREENX(newx), SCREENY(newy));
2040 else if (IS_BLOCKED(x, y))
2044 Blocked2Moving(x, y, &oldx, &oldy);
2045 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
2046 DrawNewScreenField(SCREENX(oldx), SCREENY(oldy));
2050 void DrawMiniElement(int x, int y, int element)
2056 DrawMiniGraphic(x, y, -1);
2060 graphic = el2gfx(element);
2061 DrawMiniGraphic(x, y, graphic);
2064 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
2066 int x = sx + scroll_x, y = sy + scroll_y;
2068 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
2069 DrawMiniElement(sx, sy, EL_LEERRAUM);
2070 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
2071 DrawMiniElement(sx, sy, Feld[x][y]);
2074 int steel_type, steel_position;
2077 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
2078 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
2079 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
2080 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
2081 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
2082 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
2085 steel_type = (BorderElement == EL_BETON ? 0 : 1);
2086 steel_position = (x == -1 && y == -1 ? 0 :
2087 x == lev_fieldx && y == -1 ? 1 :
2088 x == -1 && y == lev_fieldy ? 2 :
2089 x == lev_fieldx && y == lev_fieldy ? 3 :
2090 x == -1 || x == lev_fieldx ? 4 :
2091 y == -1 || y == lev_fieldy ? 5 : -1);
2093 if (steel_position != -1)
2094 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
2098 void DrawMicroElement(int xpos, int ypos, int element)
2102 if (element == EL_LEERRAUM)
2105 graphic = el2gfx(element);
2107 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
2109 graphic -= GFX_START_ROCKSSP;
2110 BlitBitmap(pix[PIX_SP], drawto,
2111 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
2112 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
2113 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
2115 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
2117 graphic -= GFX_START_ROCKSDC;
2118 BlitBitmap(pix[PIX_DC], drawto,
2119 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
2120 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
2121 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
2123 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
2125 graphic -= GFX_START_ROCKSMORE;
2126 BlitBitmap(pix[PIX_MORE], drawto,
2127 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
2128 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
2129 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
2131 else if (graphic >= GFX_CHAR_START && graphic <= GFX_CHAR_END)
2133 graphic -= GFX_CHAR_START;
2134 BlitBitmap(pix[PIX_FONT_EM], drawto,
2135 MICRO_FONT_STARTX + (graphic % MICRO_GFX_PER_LINE)* MICRO_TILEX,
2136 MICRO_FONT_STARTY + (graphic / MICRO_GFX_PER_LINE)* MICRO_TILEY,
2137 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
2140 BlitBitmap(pix[PIX_ELEMENTS], drawto,
2141 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
2142 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
2143 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
2152 for(x=BX1; x<=BX2; x++)
2153 for(y=BY1; y<=BY2; y++)
2154 DrawScreenField(x, y);
2156 redraw_mask |= REDRAW_FIELD;
2159 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
2163 for(x=0; x<size_x; x++)
2164 for(y=0; y<size_y; y++)
2165 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
2167 redraw_mask |= REDRAW_FIELD;
2170 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
2174 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
2176 if (lev_fieldx < STD_LEV_FIELDX)
2177 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
2178 if (lev_fieldy < STD_LEV_FIELDY)
2179 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
2181 xpos += MICRO_TILEX;
2182 ypos += MICRO_TILEY;
2184 for(x=-1; x<=STD_LEV_FIELDX; x++)
2186 for(y=-1; y<=STD_LEV_FIELDY; y++)
2188 int lx = from_x + x, ly = from_y + y;
2190 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
2191 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
2193 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
2194 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
2199 redraw_mask |= REDRAW_MICROLEVEL;
2202 #define MICROLABEL_EMPTY 0
2203 #define MICROLABEL_LEVEL_NAME 1
2204 #define MICROLABEL_CREATED_BY 2
2205 #define MICROLABEL_LEVEL_AUTHOR 3
2206 #define MICROLABEL_IMPORTED_FROM 4
2207 #define MICROLABEL_LEVEL_IMPORT_INFO 5
2209 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
2211 static void DrawMicroLevelLabelExt(int mode)
2213 char label_text[MAX_MICROLABEL_SIZE + 1];
2215 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
2217 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
2218 mode == MICROLABEL_CREATED_BY ? "created by" :
2219 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
2220 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
2221 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
2222 leveldir_current->imported_from : ""),
2223 MAX_MICROLABEL_SIZE);
2224 label_text[MAX_MICROLABEL_SIZE] = '\0';
2226 if (strlen(label_text) > 0)
2228 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
2229 int lypos = MICROLABEL_YPOS;
2231 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
2234 redraw_mask |= REDRAW_MICROLEVEL;
2237 void DrawMicroLevel(int xpos, int ypos, boolean restart)
2239 static unsigned long scroll_delay = 0;
2240 static unsigned long label_delay = 0;
2241 static int from_x, from_y, scroll_direction;
2242 static int label_state, label_counter;
2246 from_x = from_y = 0;
2247 scroll_direction = MV_RIGHT;
2251 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
2252 DrawMicroLevelLabelExt(label_state);
2254 /* initialize delay counters */
2255 DelayReached(&scroll_delay, 0);
2256 DelayReached(&label_delay, 0);
2261 /* scroll micro level, if needed */
2262 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
2263 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
2265 switch (scroll_direction)
2271 scroll_direction = MV_UP;
2275 if (from_x < lev_fieldx - STD_LEV_FIELDX)
2278 scroll_direction = MV_DOWN;
2285 scroll_direction = MV_RIGHT;
2289 if (from_y < lev_fieldy - STD_LEV_FIELDY)
2292 scroll_direction = MV_LEFT;
2299 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
2302 /* redraw micro level label, if needed */
2303 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
2304 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
2305 strcmp(level.author, leveldir_current->name) != 0 &&
2306 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
2308 int max_label_counter = 23;
2310 if (leveldir_current->imported_from != NULL)
2311 max_label_counter += 14;
2313 label_counter = (label_counter + 1) % max_label_counter;
2314 label_state = (label_counter >= 0 && label_counter <= 7 ?
2315 MICROLABEL_LEVEL_NAME :
2316 label_counter >= 9 && label_counter <= 12 ?
2317 MICROLABEL_CREATED_BY :
2318 label_counter >= 14 && label_counter <= 21 ?
2319 MICROLABEL_LEVEL_AUTHOR :
2320 label_counter >= 23 && label_counter <= 26 ?
2321 MICROLABEL_IMPORTED_FROM :
2322 label_counter >= 28 && label_counter <= 35 ?
2323 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
2324 DrawMicroLevelLabelExt(label_state);
2328 int REQ_in_range(int x, int y)
2330 if (y > DY+249 && y < DY+278)
2332 if (x > DX+1 && x < DX+48)
2334 else if (x > DX+51 && x < DX+98)
2340 #define MAX_REQUEST_LINES 13
2341 #define MAX_REQUEST_LINE_LEN 7
2343 boolean Request(char *text, unsigned int req_state)
2345 int mx, my, ty, result = -1;
2346 unsigned int old_door_state;
2348 #if defined(PLATFORM_UNIX)
2349 /* pause network game while waiting for request to answer */
2350 if (options.network &&
2351 game_status == PLAYING &&
2352 req_state & REQUEST_WAIT_FOR)
2353 SendToServer_PausePlaying();
2356 old_door_state = GetDoorState();
2360 CloseDoor(DOOR_CLOSE_1);
2362 /* save old door content */
2363 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2364 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
2365 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
2367 /* clear door drawing field */
2368 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
2370 /* write text for request */
2371 for(ty=0; ty < MAX_REQUEST_LINES; ty++)
2373 char text_line[MAX_REQUEST_LINE_LEN + 1];
2379 for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
2382 if (!tc || tc == ' ')
2393 strncpy(text_line, text, tl);
2396 DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
2397 text_line, FS_SMALL, FC_YELLOW);
2399 text += tl + (tc == ' ' ? 1 : 0);
2402 if (req_state & REQ_ASK)
2404 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
2405 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
2407 else if (req_state & REQ_CONFIRM)
2409 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
2411 else if (req_state & REQ_PLAYER)
2413 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
2414 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
2415 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
2416 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
2419 /* copy request gadgets to door backbuffer */
2420 BlitBitmap(drawto, pix[PIX_DB_DOOR],
2421 DX, DY, DXSIZE, DYSIZE,
2422 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2424 OpenDoor(DOOR_OPEN_1);
2430 if (!(req_state & REQUEST_WAIT_FOR))
2433 if (game_status != MAINMENU)
2436 button_status = MB_RELEASED;
2438 request_gadget_id = -1;
2450 case EVENT_BUTTONPRESS:
2451 case EVENT_BUTTONRELEASE:
2452 case EVENT_MOTIONNOTIFY:
2454 if (event.type == EVENT_MOTIONNOTIFY)
2456 if (!PointerInWindow(window))
2457 continue; /* window and pointer are on different screens */
2462 motion_status = TRUE;
2463 mx = ((MotionEvent *) &event)->x;
2464 my = ((MotionEvent *) &event)->y;
2468 motion_status = FALSE;
2469 mx = ((ButtonEvent *) &event)->x;
2470 my = ((ButtonEvent *) &event)->y;
2471 if (event.type == EVENT_BUTTONPRESS)
2472 button_status = ((ButtonEvent *) &event)->button;
2474 button_status = MB_RELEASED;
2477 /* this sets 'request_gadget_id' */
2478 HandleGadgets(mx, my, button_status);
2480 switch(request_gadget_id)
2482 case TOOL_CTRL_ID_YES:
2485 case TOOL_CTRL_ID_NO:
2488 case TOOL_CTRL_ID_CONFIRM:
2489 result = TRUE | FALSE;
2492 case TOOL_CTRL_ID_PLAYER_1:
2495 case TOOL_CTRL_ID_PLAYER_2:
2498 case TOOL_CTRL_ID_PLAYER_3:
2501 case TOOL_CTRL_ID_PLAYER_4:
2512 case EVENT_KEYPRESS:
2513 switch(GetEventKey((KeyEvent *)&event, TRUE))
2526 if (req_state & REQ_PLAYER)
2530 case EVENT_KEYRELEASE:
2531 ClearPlayerAction();
2535 HandleOtherEvents(&event);
2539 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2541 int joy = AnyJoystick();
2543 if (joy & JOY_BUTTON_1)
2545 else if (joy & JOY_BUTTON_2)
2551 /* don't eat all CPU time */
2555 if (game_status != MAINMENU)
2560 if (!(req_state & REQ_STAY_OPEN))
2562 CloseDoor(DOOR_CLOSE_1);
2564 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2566 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2567 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2568 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2569 OpenDoor(DOOR_OPEN_1);
2575 #if defined(PLATFORM_UNIX)
2576 /* continue network game after request */
2577 if (options.network &&
2578 game_status == PLAYING &&
2579 req_state & REQUEST_WAIT_FOR)
2580 SendToServer_ContinuePlaying();
2586 unsigned int OpenDoor(unsigned int door_state)
2588 unsigned int new_door_state;
2590 if (door_state & DOOR_COPY_BACK)
2592 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2593 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2594 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2595 door_state &= ~DOOR_COPY_BACK;
2598 new_door_state = MoveDoor(door_state);
2600 return(new_door_state);
2603 unsigned int CloseDoor(unsigned int door_state)
2605 unsigned int new_door_state;
2607 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2608 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2609 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2610 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2612 new_door_state = MoveDoor(door_state);
2614 return(new_door_state);
2617 unsigned int GetDoorState()
2619 return MoveDoor(DOOR_GET_STATE);
2622 unsigned int SetDoorState(unsigned int door_state)
2624 return MoveDoor(door_state | DOOR_SET_STATE);
2627 unsigned int MoveDoor(unsigned int door_state)
2629 static int door1 = DOOR_OPEN_1;
2630 static int door2 = DOOR_CLOSE_2;
2631 static unsigned long door_delay = 0;
2632 int x, start, stepsize = 2;
2633 unsigned long door_delay_value = stepsize * 5;
2635 if (door_state == DOOR_GET_STATE)
2636 return(door1 | door2);
2638 if (door_state & DOOR_SET_STATE)
2640 if (door_state & DOOR_ACTION_1)
2641 door1 = door_state & DOOR_ACTION_1;
2642 if (door_state & DOOR_ACTION_2)
2643 door2 = door_state & DOOR_ACTION_2;
2645 return(door1 | door2);
2648 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2649 door_state &= ~DOOR_OPEN_1;
2650 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2651 door_state &= ~DOOR_CLOSE_1;
2652 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2653 door_state &= ~DOOR_OPEN_2;
2654 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2655 door_state &= ~DOOR_CLOSE_2;
2657 if (setup.quick_doors)
2660 door_delay_value = 0;
2661 StopSound(SND_MENU_DOOR_OPENING);
2662 StopSound(SND_MENU_DOOR_CLOSING);
2665 if (door_state & DOOR_ACTION)
2667 if (!(door_state & DOOR_NO_DELAY))
2669 /* opening door sound has priority over simultaneously closing door */
2670 if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
2671 PlaySoundStereo(SND_MENU_DOOR_OPENING, SOUND_MAX_RIGHT);
2672 else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
2673 PlaySoundStereo(SND_MENU_DOOR_CLOSING, SOUND_MAX_RIGHT);
2676 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2678 for(x=start; x<=DXSIZE; x+=stepsize)
2680 Bitmap *bitmap = pix[PIX_DOOR];
2681 GC gc = bitmap->stored_clip_gc;
2683 WaitUntilDelayReached(&door_delay, door_delay_value);
2685 if (door_state & DOOR_ACTION_1)
2687 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2688 int j = (DXSIZE - i) / 3;
2690 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2691 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2692 DXSIZE,DYSIZE - i/2, DX, DY);
2694 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2696 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2697 BlitBitmapMasked(bitmap, drawto,
2698 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2699 DX + DXSIZE - i, DY + j);
2700 BlitBitmapMasked(bitmap, drawto,
2701 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2702 DX + DXSIZE - i, DY + 140 + j);
2703 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2704 BlitBitmapMasked(bitmap, drawto,
2705 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2707 BlitBitmapMasked(bitmap, drawto,
2708 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2711 BlitBitmapMasked(bitmap, drawto,
2712 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2714 BlitBitmapMasked(bitmap, drawto,
2715 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2717 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2718 BlitBitmapMasked(bitmap, drawto,
2719 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2720 DX + DXSIZE - i, DY + 77 + j);
2721 BlitBitmapMasked(bitmap, drawto,
2722 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2723 DX + DXSIZE - i, DY + 203 + j);
2725 redraw_mask |= REDRAW_DOOR_1;
2728 if (door_state & DOOR_ACTION_2)
2730 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2731 int j = (VXSIZE - i) / 3;
2733 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2734 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2735 VXSIZE, VYSIZE - i/2, VX, VY);
2737 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2739 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2740 BlitBitmapMasked(bitmap, drawto,
2741 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2742 VX + VXSIZE-i, VY+j);
2743 SetClipOrigin(bitmap, gc,
2744 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2745 BlitBitmapMasked(bitmap, drawto,
2746 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2749 BlitBitmapMasked(bitmap, drawto,
2750 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2751 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2752 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2753 BlitBitmapMasked(bitmap, drawto,
2754 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2756 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2758 redraw_mask |= REDRAW_DOOR_2;
2763 if (game_status == MAINMENU)
2768 if (setup.quick_doors)
2770 StopSound(SND_MENU_DOOR_OPENING);
2771 StopSound(SND_MENU_DOOR_CLOSING);
2774 if (door_state & DOOR_ACTION_1)
2775 door1 = door_state & DOOR_ACTION_1;
2776 if (door_state & DOOR_ACTION_2)
2777 door2 = door_state & DOOR_ACTION_2;
2779 return (door1 | door2);
2782 void DrawSpecialEditorDoor()
2784 /* draw bigger toolbox window */
2785 BlitBitmap(pix[PIX_DOOR], drawto,
2786 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2788 redraw_mask |= REDRAW_ALL;
2791 void UndrawSpecialEditorDoor()
2793 /* draw normal tape recorder window */
2794 BlitBitmap(pix[PIX_BACK], drawto,
2795 562, 344, 108, 56, EX - 4, EY - 12);
2797 redraw_mask |= REDRAW_ALL;
2801 int ReadPixel(DrawBuffer *bitmap, int x, int y)
2803 XImage *pixel_image;
2804 unsigned long pixel_value;
2806 pixel_image = XGetImage(display, bitmap->drawable,
2807 x, y, 1, 1, AllPlanes, ZPixmap);
2808 pixel_value = XGetPixel(pixel_image, 0, 0);
2810 XDestroyImage(pixel_image);
2816 /* ---------- new tool button stuff ---------------------------------------- */
2818 /* graphic position values for tool buttons */
2819 #define TOOL_BUTTON_YES_XPOS 2
2820 #define TOOL_BUTTON_YES_YPOS 250
2821 #define TOOL_BUTTON_YES_GFX_YPOS 0
2822 #define TOOL_BUTTON_YES_XSIZE 46
2823 #define TOOL_BUTTON_YES_YSIZE 28
2824 #define TOOL_BUTTON_NO_XPOS 52
2825 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2826 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2827 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2828 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2829 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2830 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2831 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2832 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2833 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2834 #define TOOL_BUTTON_PLAYER_XSIZE 30
2835 #define TOOL_BUTTON_PLAYER_YSIZE 30
2836 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2837 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2838 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2839 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2840 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2841 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2842 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2843 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2844 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2845 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2846 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2847 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2848 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2849 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2850 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2851 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2852 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2853 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2854 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2855 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2864 } toolbutton_info[NUM_TOOL_BUTTONS] =
2867 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2868 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2869 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2874 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2875 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2876 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2881 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2882 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2883 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2884 TOOL_CTRL_ID_CONFIRM,
2888 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2889 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2890 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2891 TOOL_CTRL_ID_PLAYER_1,
2895 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2896 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2897 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2898 TOOL_CTRL_ID_PLAYER_2,
2902 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2903 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2904 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2905 TOOL_CTRL_ID_PLAYER_3,
2909 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2910 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2911 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2912 TOOL_CTRL_ID_PLAYER_4,
2917 void CreateToolButtons()
2921 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2923 Bitmap *gd_bitmap = pix[PIX_DOOR];
2924 Bitmap *deco_bitmap = None;
2925 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2926 struct GadgetInfo *gi;
2927 unsigned long event_mask;
2928 int gd_xoffset, gd_yoffset;
2929 int gd_x1, gd_x2, gd_y;
2932 event_mask = GD_EVENT_RELEASED;
2934 gd_xoffset = toolbutton_info[i].xpos;
2935 gd_yoffset = toolbutton_info[i].ypos;
2936 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2937 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2938 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2940 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2942 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2943 &deco_bitmap, &deco_x, &deco_y);
2944 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2945 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2948 gi = CreateGadget(GDI_CUSTOM_ID, id,
2949 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2950 GDI_X, DX + toolbutton_info[i].x,
2951 GDI_Y, DY + toolbutton_info[i].y,
2952 GDI_WIDTH, toolbutton_info[i].width,
2953 GDI_HEIGHT, toolbutton_info[i].height,
2954 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2955 GDI_STATE, GD_BUTTON_UNPRESSED,
2956 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2957 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2958 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2959 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2960 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2961 GDI_DECORATION_SHIFTING, 1, 1,
2962 GDI_EVENT_MASK, event_mask,
2963 GDI_CALLBACK_ACTION, HandleToolButtons,
2967 Error(ERR_EXIT, "cannot create gadget");
2969 tool_gadget[id] = gi;
2973 static void UnmapToolButtons()
2977 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2978 UnmapGadget(tool_gadget[i]);
2981 static void HandleToolButtons(struct GadgetInfo *gi)
2983 request_gadget_id = gi->custom_id;
2986 int get_next_element(int element)
2990 case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
2991 case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
2992 case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
2993 case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
2994 case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
2995 case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
2996 case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
2998 default: return element;
3002 int el2gfx_OLD(int element)
3006 case EL_LEERRAUM: return -1;
3007 case EL_ERDREICH: return GFX_ERDREICH;
3008 case EL_MAUERWERK: return GFX_MAUERWERK;
3009 case EL_FELSBODEN: return GFX_FELSBODEN;
3010 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
3011 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
3012 case EL_EDELSTEIN: return GFX_EDELSTEIN;
3013 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
3014 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
3015 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
3016 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
3017 case EL_SPIELER1: return GFX_SPIELER1;
3018 case EL_SPIELER2: return GFX_SPIELER2;
3019 case EL_SPIELER3: return GFX_SPIELER3;
3020 case EL_SPIELER4: return GFX_SPIELER4;
3021 case EL_KAEFER: return GFX_KAEFER;
3022 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
3023 case EL_KAEFER_UP: return GFX_KAEFER_UP;
3024 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
3025 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
3026 case EL_FLIEGER: return GFX_FLIEGER;
3027 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
3028 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
3029 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
3030 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
3031 case EL_BUTTERFLY: return GFX_BUTTERFLY;
3032 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
3033 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
3034 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
3035 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
3036 case EL_FIREFLY: return GFX_FIREFLY;
3037 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
3038 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
3039 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
3040 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
3041 case EL_MAMPFER: return GFX_MAMPFER;
3042 case EL_ROBOT: return GFX_ROBOT;
3043 case EL_BETON: return GFX_BETON;
3044 case EL_DIAMANT: return GFX_DIAMANT;
3045 case EL_MORAST_LEER: return GFX_MORAST_LEER;
3046 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
3047 case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
3048 case EL_TROPFEN: return GFX_TROPFEN;
3049 case EL_BOMBE: return GFX_BOMBE;
3050 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
3051 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
3052 case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
3053 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
3054 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
3055 case EL_SALZSAEURE: return GFX_SALZSAEURE;
3056 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
3057 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
3058 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
3059 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
3060 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
3061 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
3062 case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
3063 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
3064 case EL_LIFE: return GFX_LIFE;
3065 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
3066 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
3067 case EL_BADEWANNE: return GFX_BADEWANNE;
3068 case EL_BADEWANNE1: return GFX_BADEWANNE1;
3069 case EL_BADEWANNE2: return GFX_BADEWANNE2;
3070 case EL_BADEWANNE3: return GFX_BADEWANNE3;
3071 case EL_BADEWANNE4: return GFX_BADEWANNE4;
3072 case EL_BADEWANNE5: return GFX_BADEWANNE5;
3073 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
3074 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
3075 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
3076 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
3077 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
3078 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
3079 case EL_PFORTE1: return GFX_PFORTE1;
3080 case EL_PFORTE2: return GFX_PFORTE2;
3081 case EL_PFORTE3: return GFX_PFORTE3;
3082 case EL_PFORTE4: return GFX_PFORTE4;
3083 case EL_PFORTE1X: return GFX_PFORTE1X;
3084 case EL_PFORTE2X: return GFX_PFORTE2X;
3085 case EL_PFORTE3X: return GFX_PFORTE3X;
3086 case EL_PFORTE4X: return GFX_PFORTE4X;
3087 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
3088 case EL_PACMAN: return GFX_PACMAN;
3089 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
3090 case EL_PACMAN_UP: return GFX_PACMAN_UP;
3091 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
3092 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
3093 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
3094 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
3095 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
3096 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
3097 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
3098 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
3099 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
3100 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
3101 case EL_MAUER_X: return GFX_MAUER_X;
3102 case EL_MAUER_Y: return GFX_MAUER_Y;
3103 case EL_MAUER_XY: return GFX_MAUER_XY;
3104 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
3105 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
3106 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
3107 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
3108 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
3109 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
3110 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
3111 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
3112 case EL_MAMPFER2: return GFX_MAMPFER2;
3113 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
3114 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
3115 case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
3116 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
3117 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
3118 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
3119 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
3120 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
3121 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
3122 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
3123 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
3124 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
3125 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
3126 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
3127 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
3128 case EL_MOLE: return GFX_MOLE;
3129 case EL_PINGUIN: return GFX_PINGUIN;
3130 case EL_SCHWEIN: return GFX_SCHWEIN;
3131 case EL_DRACHE: return GFX_DRACHE;
3132 case EL_SONDE: return GFX_SONDE;
3133 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
3134 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
3135 case EL_PFEIL_UP: return GFX_PFEIL_UP;
3136 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
3137 case EL_SPEED_PILL: return GFX_SPEED_PILL;
3138 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
3139 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
3140 case EL_SP_ZONK: return GFX_SP_ZONK;
3141 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
3142 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
3143 case EL_BLACK_ORB: return GFX_BLACK_ORB;
3144 case EL_EM_GATE_1: return GFX_EM_GATE_1;
3145 case EL_EM_GATE_2: return GFX_EM_GATE_2;
3146 case EL_EM_GATE_3: return GFX_EM_GATE_3;
3147 case EL_EM_GATE_4: return GFX_EM_GATE_4;
3148 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
3149 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
3150 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
3151 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
3152 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
3153 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
3154 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
3155 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
3156 case EL_EM_KEY_1: return GFX_EM_KEY_1;
3157 case EL_EM_KEY_2: return GFX_EM_KEY_2;
3158 case EL_EM_KEY_3: return GFX_EM_KEY_3;
3159 case EL_EM_KEY_4: return GFX_EM_KEY_4;
3160 case EL_PEARL: return GFX_PEARL;
3161 case EL_CRYSTAL: return GFX_CRYSTAL;
3162 case EL_WALL_PEARL: return GFX_WALL_PEARL;
3163 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
3164 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
3165 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
3166 case EL_KEY_WHITE: return GFX_KEY_WHITE;
3167 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
3168 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
3169 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
3170 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
3171 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
3172 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
3173 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
3174 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
3175 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
3176 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
3177 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
3178 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
3179 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
3180 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
3181 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
3182 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
3183 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
3184 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
3185 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
3186 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
3187 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
3188 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
3189 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
3190 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
3191 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
3192 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
3193 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
3194 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
3195 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
3196 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
3197 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
3198 case EL_LANDMINE: return GFX_LANDMINE;
3199 case EL_ENVELOPE: return GFX_ENVELOPE;
3200 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
3201 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
3202 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
3203 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
3204 case EL_SIGN_STOP: return GFX_SIGN_STOP;
3205 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
3206 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
3207 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
3208 case EL_SIGN_HEART: return GFX_SIGN_HEART;
3209 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
3210 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
3211 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
3212 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
3213 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
3214 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
3215 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
3216 case EL_MOLE_UP: return GFX_MOLE_UP;
3217 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
3218 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
3219 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
3220 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
3221 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
3222 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
3223 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
3224 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
3225 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
3226 case EL_BALLOON: return GFX_BALLOON;
3227 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
3228 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
3229 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
3230 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
3231 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
3232 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
3233 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
3234 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
3235 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
3236 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
3237 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
3238 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
3239 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
3240 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
3241 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
3242 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
3243 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
3244 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
3245 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
3246 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
3247 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
3248 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
3249 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
3250 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
3251 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
3252 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
3253 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
3254 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
3255 case EL_SPRING: return GFX_SPRING;
3256 case EL_SPRING_MOVING: return GFX_SPRING;
3257 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
3258 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
3259 case EL_BD_WALL: return GFX_BD_WALL;
3260 case EL_BD_ROCK: return GFX_BD_ROCK;
3261 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
3262 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
3266 if (IS_CHAR(element))
3267 return GFX_CHAR_START + (element - EL_CHAR_START);
3268 else if (element >= EL_SP_START && element <= EL_SP_END)
3270 int nr_element = element - EL_SP_START;
3271 int gfx_per_line = 8;
3273 (nr_element / gfx_per_line) * SP_PER_LINE +
3274 (nr_element % gfx_per_line);
3276 return GFX_START_ROCKSSP + nr_graphic;
3284 int el2gfx(int element)
3286 int graphic_NEW = element_info[element].graphic;
3289 int graphic_OLD = el2gfx_OLD(element);
3291 if (element >= MAX_ELEMENTS)
3293 Error(ERR_WARN, "el2gfx: element == %d >= MAX_ELEMENTS", element);
3296 if (graphic_NEW != graphic_OLD)
3298 Error(ERR_WARN, "el2gfx: graphic_NEW (%d) != graphic_OLD (%d)",
3299 graphic_NEW, graphic_OLD);
3306 int el2img(int element)
3310 case EL_BUTTERFLY: return IMG_BD_BUTTERFLY;
3311 case EL_FIREFLY: return IMG_BD_FIREFLY;
3317 return IMG_EMPTY_SPACE;
3320 int el_dir2img(int element, int direction)
3322 if (element_info[element].has_direction_graphic)
3323 return element_info[element].direction_graphic[LOG_MV_DIR(direction)];
3325 return el2img(element);