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 /* 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_OSCILLATE);
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_OSCILLATE);
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_OSCILLATE)
695 int max_anim_frames = 2 * frames - 2;
696 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
697 phase = (phase < frames ? phase : max_anim_frames - phase);
700 phase = (FrameCounter % (delay * frames)) / delay;
702 if (mode == ANIM_REVERSE)
708 void DrawGraphicAnimationExt(int x, int y, int graphic,
709 int frames, int delay, int mode, int mask_mode)
711 int phase = getGraphicAnimationPhase(frames, delay, mode);
713 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
715 if (mask_mode == USE_MASKING)
716 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
718 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
722 void DrawGraphicAnimation(int x, int y, int graphic,
723 int frames, int delay, int mode)
725 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
728 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
729 int frames, int delay, int mode)
731 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
734 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
737 int frames, int delay,
740 int phase = getGraphicAnimationPhase(frames, delay, mode);
742 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
745 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
747 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
749 graphic -= GFX_START_ROCKSSCREEN;
750 *bitmap_nr = PIX_BACK;
751 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
752 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
754 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
756 graphic -= GFX_START_ROCKSHEROES;
757 *bitmap_nr = PIX_HEROES;
758 *x = (graphic % HEROES_PER_LINE) * TILEX;
759 *y = (graphic / HEROES_PER_LINE) * TILEY;
761 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
763 graphic -= GFX_START_ROCKSSP;
765 *x = (graphic % SP_PER_LINE) * TILEX;
766 *y = (graphic / SP_PER_LINE) * TILEY;
768 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
770 graphic -= GFX_START_ROCKSDC;
772 *x = (graphic % DC_PER_LINE) * TILEX;
773 *y = (graphic / DC_PER_LINE) * TILEY;
775 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
777 graphic -= GFX_START_ROCKSMORE;
778 *bitmap_nr = PIX_MORE;
779 *x = (graphic % MORE_PER_LINE) * TILEX;
780 *y = (graphic / MORE_PER_LINE) * TILEY;
782 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
784 graphic -= GFX_START_ROCKSFONT;
785 *bitmap_nr = PIX_BIGFONT;
786 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
787 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
788 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
798 void DrawGraphic(int x, int y, int graphic)
801 if (!IN_SCR_FIELD(x,y))
803 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
804 printf("DrawGraphic(): This should never happen!\n");
809 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
813 void DrawGraphicExt(DrawBuffer *bitmap, int x, int y, int graphic)
818 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
819 BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
822 void DrawGraphicThruMask(int x, int y, int graphic)
825 if (!IN_SCR_FIELD(x,y))
827 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
828 printf("DrawGraphicThruMask(): This should never happen!\n");
833 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
837 void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
845 if (graphic == GFX_LEERRAUM)
848 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
849 src_bitmap = pix[bitmap_nr];
850 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
852 if (tile_clipmask[tile] != None)
854 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
855 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
856 BlitBitmapMasked(src_bitmap, d,
857 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
863 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
867 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
868 BlitBitmapMasked(src_bitmap, d,
869 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
873 void DrawMiniGraphic(int x, int y, int graphic)
875 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
876 MarkTileDirty(x/2, y/2);
879 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
881 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
883 graphic -= GFX_START_ROCKSSCREEN;
884 *bitmap = pix[PIX_BACK];
885 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
886 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
888 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
890 graphic -= GFX_START_ROCKSSP;
891 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
892 *bitmap = pix[PIX_SP];
893 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
894 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
896 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
898 graphic -= GFX_START_ROCKSDC;
899 *bitmap = pix[PIX_DC];
900 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
901 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
903 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
905 graphic -= GFX_START_ROCKSMORE;
906 *bitmap = pix[PIX_MORE];
907 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
908 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
910 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
912 graphic -= GFX_START_ROCKSFONT;
913 *bitmap = pix[PIX_SMALLFONT];
914 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
915 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
916 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
920 *bitmap = pix[PIX_SP];
926 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
931 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
932 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
935 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
936 int cut_mode, int mask_mode)
938 int width = TILEX, height = TILEY;
940 int src_x, src_y, dest_x, dest_y;
948 DrawGraphic(x, y, graphic);
952 if (dx || dy) /* Verschiebung der Grafik? */
954 if (x < BX1) /* Element kommt von links ins Bild */
961 else if (x > BX2) /* Element kommt von rechts ins Bild */
967 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
973 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
975 else if (dx) /* allg. Bewegung in x-Richtung */
976 MarkTileDirty(x + SIGN(dx), y);
978 if (y < BY1) /* Element kommt von oben ins Bild */
980 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
988 else if (y > BY2) /* Element kommt von unten ins Bild */
994 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1000 else if (dy > 0 && cut_mode == CUT_ABOVE)
1002 if (y == BY2) /* Element unterhalb des Bildes */
1008 MarkTileDirty(x, y + 1);
1009 } /* Element verläßt unten das Bild */
1010 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1012 else if (dy) /* allg. Bewegung in y-Richtung */
1013 MarkTileDirty(x, y + SIGN(dy));
1016 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1017 src_bitmap = pix[bitmap_nr];
1018 drawing_gc = pix[bitmap_nr]->stored_clip_gc;
1023 dest_x = FX + x * TILEX + dx;
1024 dest_y = FY + y * TILEY + dy;
1027 if (!IN_SCR_FIELD(x,y))
1029 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1030 printf("DrawGraphicShifted(): This should never happen!\n");
1035 if (mask_mode == USE_MASKING)
1037 if (tile_clipmask[tile] != None)
1039 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1040 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1041 BlitBitmapMasked(src_bitmap, drawto_field,
1042 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1048 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1052 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1053 BlitBitmapMasked(src_bitmap, drawto_field,
1054 src_x, src_y, width, height, dest_x, dest_y);
1058 BlitBitmap(pix[bitmap_nr], drawto_field,
1059 src_x, src_y, width, height, dest_x, dest_y);
1064 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1067 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1070 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1071 int cut_mode, int mask_mode)
1073 int ux = LEVELX(x), uy = LEVELY(y);
1074 int graphic = el2gfx(element);
1075 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1076 int phase4 = phase8 / 2;
1077 int phase2 = phase8 / 4;
1078 int dir = MovDir[ux][uy];
1080 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1082 graphic += 4 * !phase2;
1086 else if (dir == MV_LEFT)
1088 else if (dir == MV_DOWN)
1091 else if (element == EL_SP_SNIKSNAK)
1094 graphic = GFX_SP_SNIKSNAK_LEFT;
1095 else if (dir == MV_RIGHT)
1096 graphic = GFX_SP_SNIKSNAK_RIGHT;
1097 else if (dir == MV_UP)
1098 graphic = GFX_SP_SNIKSNAK_UP;
1100 graphic = GFX_SP_SNIKSNAK_DOWN;
1102 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1104 else if (element == EL_SP_ELECTRON)
1106 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1108 else if (element == EL_MOLE || element == EL_PINGUIN ||
1109 element == EL_SCHWEIN || element == EL_DRACHE)
1112 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1113 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1114 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1115 else if (dir == MV_RIGHT)
1116 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1117 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1118 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1119 else if (dir == MV_UP)
1120 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1121 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1122 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1124 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1125 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1126 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1130 else if (element == EL_SONDE)
1132 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1134 else if (element == EL_SALZSAEURE)
1136 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1138 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1142 else if (element == EL_BALLOON)
1146 else if ((element == EL_FELSBROCKEN ||
1147 element == EL_SP_ZONK ||
1148 element == EL_BD_ROCK ||
1149 element == EL_SP_INFOTRON ||
1153 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1155 if (element == EL_FELSBROCKEN ||
1156 element == EL_SP_ZONK ||
1157 element == EL_BD_ROCK)
1160 graphic += (4 - phase4) % 4;
1161 else if (dir == MV_RIGHT)
1164 graphic += phase2 * 2;
1166 else if (element != EL_SP_INFOTRON)
1170 else if (element == EL_MAGIC_WALL_EMPTY ||
1171 element == EL_MAGIC_WALL_EMPTYING ||
1172 element == EL_MAGIC_WALL_BD_EMPTY ||
1173 element == EL_MAGIC_WALL_BD_EMPTYING ||
1174 element == EL_MAGIC_WALL_FULL ||
1175 element == EL_MAGIC_WALL_BD_FULL)
1177 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1179 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1181 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1182 graphic += (x + 2 * y + 4) % 4;
1184 else if (element == EL_MAUER_LEBT)
1186 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1188 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1189 links_massiv = TRUE;
1190 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1191 rechts_massiv = TRUE;
1193 if (links_massiv && rechts_massiv)
1194 graphic = GFX_MAUERWERK;
1195 else if (links_massiv)
1196 graphic = GFX_MAUER_R;
1197 else if (rechts_massiv)
1198 graphic = GFX_MAUER_L;
1200 else if ((element == EL_INVISIBLE_STEEL ||
1201 element == EL_UNSICHTBAR ||
1202 element == EL_SAND_INVISIBLE) && game.light_time_left)
1204 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1205 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1206 GFX_SAND_INVISIBLE_ON);
1210 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1211 else if (mask_mode == USE_MASKING)
1212 DrawGraphicThruMask(x, y, graphic);
1214 DrawGraphic(x, y, graphic);
1217 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1218 int cut_mode, int mask_mode)
1220 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1221 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1222 cut_mode, mask_mode);
1225 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1228 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1231 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1234 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1237 void DrawScreenElementThruMask(int x, int y, int element)
1239 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1242 void DrawLevelElementThruMask(int x, int y, int element)
1244 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1247 void DrawLevelFieldThruMask(int x, int y)
1249 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1252 void ErdreichAnbroeckeln(int x, int y)
1254 int i, width, height, cx,cy;
1255 int ux = LEVELX(x), uy = LEVELY(y);
1256 int element, graphic;
1258 static int xy[4][2] =
1266 if (!IN_LEV_FIELD(ux, uy))
1269 element = Feld[ux][uy];
1271 if (element == EL_ERDREICH ||
1272 element == EL_LANDMINE ||
1273 element == EL_TRAP_INACTIVE ||
1274 element == EL_TRAP_ACTIVE)
1276 if (!IN_SCR_FIELD(x, y))
1279 graphic = GFX_ERDENRAND;
1285 uxx = ux + xy[i][0];
1286 uyy = uy + xy[i][1];
1287 if (!IN_LEV_FIELD(uxx, uyy))
1290 element = Feld[uxx][uyy];
1292 if (element == EL_ERDREICH ||
1293 element == EL_LANDMINE ||
1294 element == EL_TRAP_INACTIVE ||
1295 element == EL_TRAP_ACTIVE)
1298 if (i == 1 || i == 2)
1302 cx = (i == 2 ? TILEX - snip : 0);
1310 cy = (i == 3 ? TILEY - snip : 0);
1313 BlitBitmap(pix[PIX_BACK], drawto_field,
1314 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1315 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1316 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1319 MarkTileDirty(x, y);
1323 graphic = GFX_ERDENRAND;
1327 int xx, yy, uxx, uyy;
1331 uxx = ux + xy[i][0];
1332 uyy = uy + xy[i][1];
1334 if (!IN_LEV_FIELD(uxx, uyy) ||
1335 (Feld[uxx][uyy] != EL_ERDREICH &&
1336 Feld[uxx][uyy] != EL_LANDMINE &&
1337 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1338 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1339 !IN_SCR_FIELD(xx, yy))
1342 if (i == 1 || i == 2)
1346 cx = (i == 1 ? TILEX - snip : 0);
1354 cy = (i==0 ? TILEY-snip : 0);
1357 BlitBitmap(pix[PIX_BACK], drawto_field,
1358 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1359 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1360 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1362 MarkTileDirty(xx, yy);
1367 void DrawScreenElement(int x, int y, int element)
1369 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1370 ErdreichAnbroeckeln(x, y);
1373 void DrawLevelElement(int x, int y, int element)
1375 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1376 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1379 void DrawScreenField(int x, int y)
1381 int ux = LEVELX(x), uy = LEVELY(y);
1382 int element, content;
1384 if (!IN_LEV_FIELD(ux, uy))
1386 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1387 element = EL_LEERRAUM;
1389 element = BorderElement;
1391 DrawScreenElement(x, y, element);
1395 element = Feld[ux][uy];
1396 content = Store[ux][uy];
1398 if (IS_MOVING(ux, uy))
1400 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1401 boolean cut_mode = NO_CUTTING;
1403 if (element == EL_QUICKSAND_EMPTYING ||
1404 element == EL_MAGIC_WALL_EMPTYING ||
1405 element == EL_MAGIC_WALL_BD_EMPTYING ||
1406 element == EL_AMOEBA_DRIPPING)
1407 cut_mode = CUT_ABOVE;
1408 else if (element == EL_QUICKSAND_FILLING ||
1409 element == EL_MAGIC_WALL_FILLING ||
1410 element == EL_MAGIC_WALL_BD_FILLING)
1411 cut_mode = CUT_BELOW;
1413 if (cut_mode == CUT_ABOVE)
1414 DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1416 DrawScreenElement(x, y, EL_LEERRAUM);
1419 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1420 else if (cut_mode == NO_CUTTING)
1421 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1423 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1425 if (content == EL_SALZSAEURE)
1426 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1428 else if (IS_BLOCKED(ux, uy))
1433 boolean cut_mode = NO_CUTTING;
1434 int element_old, content_old;
1436 Blocked2Moving(ux, uy, &oldx, &oldy);
1439 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1440 MovDir[oldx][oldy] == MV_RIGHT);
1442 element_old = Feld[oldx][oldy];
1443 content_old = Store[oldx][oldy];
1445 if (element_old == EL_QUICKSAND_EMPTYING ||
1446 element_old == EL_MAGIC_WALL_EMPTYING ||
1447 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1448 element_old == EL_AMOEBA_DRIPPING)
1449 cut_mode = CUT_ABOVE;
1451 DrawScreenElement(x, y, EL_LEERRAUM);
1454 DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1456 else if (cut_mode == NO_CUTTING)
1457 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1460 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
1463 else if (IS_DRAWABLE(element))
1464 DrawScreenElement(x, y, element);
1466 DrawScreenElement(x, y, EL_LEERRAUM);
1469 void DrawLevelField(int x, int y)
1471 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1472 DrawScreenField(SCREENX(x), SCREENY(y));
1473 else if (IS_MOVING(x, y))
1477 Moving2Blocked(x, y, &newx, &newy);
1478 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1479 DrawScreenField(SCREENX(newx), SCREENY(newy));
1481 else if (IS_BLOCKED(x, y))
1485 Blocked2Moving(x, y, &oldx, &oldy);
1486 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1487 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1491 void DrawMiniElement(int x, int y, int element)
1497 DrawMiniGraphic(x, y, -1);
1501 graphic = el2gfx(element);
1502 DrawMiniGraphic(x, y, graphic);
1505 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1507 int x = sx + scroll_x, y = sy + scroll_y;
1509 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1510 DrawMiniElement(sx, sy, EL_LEERRAUM);
1511 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1512 DrawMiniElement(sx, sy, Feld[x][y]);
1515 int steel_type, steel_position;
1518 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1519 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1520 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1521 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1522 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1523 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1526 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1527 steel_position = (x == -1 && y == -1 ? 0 :
1528 x == lev_fieldx && y == -1 ? 1 :
1529 x == -1 && y == lev_fieldy ? 2 :
1530 x == lev_fieldx && y == lev_fieldy ? 3 :
1531 x == -1 || x == lev_fieldx ? 4 :
1532 y == -1 || y == lev_fieldy ? 5 : -1);
1534 if (steel_position != -1)
1535 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1539 void DrawMicroElement(int xpos, int ypos, int element)
1543 if (element == EL_LEERRAUM)
1546 graphic = el2gfx(element);
1548 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1550 graphic -= GFX_START_ROCKSSP;
1551 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1552 BlitBitmap(pix[PIX_SP], drawto,
1553 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1554 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1555 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1557 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1559 graphic -= GFX_START_ROCKSDC;
1560 BlitBitmap(pix[PIX_DC], drawto,
1561 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1562 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1563 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1565 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1567 graphic -= GFX_START_ROCKSMORE;
1568 BlitBitmap(pix[PIX_MORE], drawto,
1569 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1570 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1571 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1574 BlitBitmap(pix[PIX_BACK], drawto,
1575 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1576 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1577 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1586 for(x=BX1; x<=BX2; x++)
1587 for(y=BY1; y<=BY2; y++)
1588 DrawScreenField(x, y);
1590 redraw_mask |= REDRAW_FIELD;
1593 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1597 for(x=0; x<size_x; x++)
1598 for(y=0; y<size_y; y++)
1599 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1601 redraw_mask |= REDRAW_FIELD;
1604 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1608 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1610 if (lev_fieldx < STD_LEV_FIELDX)
1611 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1612 if (lev_fieldy < STD_LEV_FIELDY)
1613 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1615 xpos += MICRO_TILEX;
1616 ypos += MICRO_TILEY;
1618 for(x=-1; x<=STD_LEV_FIELDX; x++)
1620 for(y=-1; y<=STD_LEV_FIELDY; y++)
1622 int lx = from_x + x, ly = from_y + y;
1624 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1625 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1627 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1628 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1633 redraw_mask |= REDRAW_MICROLEVEL;
1636 #define MICROLABEL_EMPTY 0
1637 #define MICROLABEL_LEVEL_NAME 1
1638 #define MICROLABEL_CREATED_BY 2
1639 #define MICROLABEL_LEVEL_AUTHOR 3
1640 #define MICROLABEL_IMPORTED_FROM 4
1641 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1643 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1645 static void DrawMicroLevelLabelExt(int mode)
1647 char label_text[MAX_MICROLABEL_SIZE + 1];
1649 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1651 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1652 mode == MICROLABEL_CREATED_BY ? "created by" :
1653 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1654 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1655 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1656 leveldir_current->imported_from : ""),
1657 MAX_MICROLABEL_SIZE);
1658 label_text[MAX_MICROLABEL_SIZE] = '\0';
1660 if (strlen(label_text) > 0)
1662 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1663 int lypos = MICROLABEL_YPOS;
1665 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1668 redraw_mask |= REDRAW_MICROLEVEL;
1671 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1673 static unsigned long scroll_delay = 0;
1674 static unsigned long label_delay = 0;
1675 static int from_x, from_y, scroll_direction;
1676 static int label_state, label_counter;
1680 from_x = from_y = 0;
1681 scroll_direction = MV_RIGHT;
1685 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1686 DrawMicroLevelLabelExt(label_state);
1688 /* initialize delay counters */
1689 DelayReached(&scroll_delay, 0);
1690 DelayReached(&label_delay, 0);
1695 /* scroll micro level, if needed */
1696 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1697 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1699 switch (scroll_direction)
1705 scroll_direction = MV_UP;
1709 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1712 scroll_direction = MV_DOWN;
1719 scroll_direction = MV_RIGHT;
1723 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1726 scroll_direction = MV_LEFT;
1733 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1736 /* redraw micro level label, if needed */
1737 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1738 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1739 strcmp(level.author, leveldir_current->name) != 0 &&
1740 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1742 int max_label_counter = 23;
1744 if (leveldir_current->imported_from != NULL)
1745 max_label_counter += 14;
1747 label_counter = (label_counter + 1) % max_label_counter;
1748 label_state = (label_counter >= 0 && label_counter <= 7 ?
1749 MICROLABEL_LEVEL_NAME :
1750 label_counter >= 9 && label_counter <= 12 ?
1751 MICROLABEL_CREATED_BY :
1752 label_counter >= 14 && label_counter <= 21 ?
1753 MICROLABEL_LEVEL_AUTHOR :
1754 label_counter >= 23 && label_counter <= 26 ?
1755 MICROLABEL_IMPORTED_FROM :
1756 label_counter >= 28 && label_counter <= 35 ?
1757 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1758 DrawMicroLevelLabelExt(label_state);
1762 int REQ_in_range(int x, int y)
1764 if (y > DY+249 && y < DY+278)
1766 if (x > DX+1 && x < DX+48)
1768 else if (x > DX+51 && x < DX+98)
1774 #define MAX_REQUEST_LINES 13
1775 #define MAX_REQUEST_LINE_LEN 7
1777 boolean Request(char *text, unsigned int req_state)
1779 int mx, my, ty, result = -1;
1780 unsigned int old_door_state;
1782 #if defined(PLATFORM_UNIX)
1783 /* pause network game while waiting for request to answer */
1784 if (options.network &&
1785 game_status == PLAYING &&
1786 req_state & REQUEST_WAIT_FOR)
1787 SendToServer_PausePlaying();
1790 old_door_state = GetDoorState();
1794 CloseDoor(DOOR_CLOSE_1);
1796 /* save old door content */
1797 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1798 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1799 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1801 /* clear door drawing field */
1802 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1804 /* write text for request */
1805 for(ty=0; ty < MAX_REQUEST_LINES; ty++)
1807 char text_line[MAX_REQUEST_LINE_LEN + 1];
1813 for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
1816 if (!tc || tc == ' ')
1827 strncpy(text_line, text, tl);
1830 DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
1831 text_line, FS_SMALL, FC_YELLOW);
1833 text += tl + (tc == ' ' ? 1 : 0);
1836 if (req_state & REQ_ASK)
1838 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1839 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1841 else if (req_state & REQ_CONFIRM)
1843 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1845 else if (req_state & REQ_PLAYER)
1847 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1848 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1849 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1850 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1853 /* copy request gadgets to door backbuffer */
1854 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1855 DX, DY, DXSIZE, DYSIZE,
1856 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1858 OpenDoor(DOOR_OPEN_1);
1864 if (!(req_state & REQUEST_WAIT_FOR))
1867 if (game_status != MAINMENU)
1870 button_status = MB_RELEASED;
1872 request_gadget_id = -1;
1884 case EVENT_BUTTONPRESS:
1885 case EVENT_BUTTONRELEASE:
1886 case EVENT_MOTIONNOTIFY:
1888 if (event.type == EVENT_MOTIONNOTIFY)
1890 if (!PointerInWindow(window))
1891 continue; /* window and pointer are on different screens */
1896 motion_status = TRUE;
1897 mx = ((MotionEvent *) &event)->x;
1898 my = ((MotionEvent *) &event)->y;
1902 motion_status = FALSE;
1903 mx = ((ButtonEvent *) &event)->x;
1904 my = ((ButtonEvent *) &event)->y;
1905 if (event.type == EVENT_BUTTONPRESS)
1906 button_status = ((ButtonEvent *) &event)->button;
1908 button_status = MB_RELEASED;
1911 /* this sets 'request_gadget_id' */
1912 HandleGadgets(mx, my, button_status);
1914 switch(request_gadget_id)
1916 case TOOL_CTRL_ID_YES:
1919 case TOOL_CTRL_ID_NO:
1922 case TOOL_CTRL_ID_CONFIRM:
1923 result = TRUE | FALSE;
1926 case TOOL_CTRL_ID_PLAYER_1:
1929 case TOOL_CTRL_ID_PLAYER_2:
1932 case TOOL_CTRL_ID_PLAYER_3:
1935 case TOOL_CTRL_ID_PLAYER_4:
1946 case EVENT_KEYPRESS:
1947 switch(GetEventKey((KeyEvent *)&event, TRUE))
1960 if (req_state & REQ_PLAYER)
1964 case EVENT_KEYRELEASE:
1965 ClearPlayerAction();
1969 HandleOtherEvents(&event);
1973 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1975 int joy = AnyJoystick();
1977 if (joy & JOY_BUTTON_1)
1979 else if (joy & JOY_BUTTON_2)
1985 /* don't eat all CPU time */
1989 if (game_status != MAINMENU)
1994 if (!(req_state & REQ_STAY_OPEN))
1996 CloseDoor(DOOR_CLOSE_1);
1998 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2000 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2001 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2002 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2003 OpenDoor(DOOR_OPEN_1);
2009 #if defined(PLATFORM_UNIX)
2010 /* continue network game after request */
2011 if (options.network &&
2012 game_status == PLAYING &&
2013 req_state & REQUEST_WAIT_FOR)
2014 SendToServer_ContinuePlaying();
2020 unsigned int OpenDoor(unsigned int door_state)
2022 unsigned int new_door_state;
2024 if (door_state & DOOR_COPY_BACK)
2026 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2027 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2028 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2029 door_state &= ~DOOR_COPY_BACK;
2032 new_door_state = MoveDoor(door_state);
2034 return(new_door_state);
2037 unsigned int CloseDoor(unsigned int door_state)
2039 unsigned int new_door_state;
2041 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2042 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2043 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2044 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2046 new_door_state = MoveDoor(door_state);
2048 return(new_door_state);
2051 unsigned int GetDoorState()
2053 return MoveDoor(DOOR_GET_STATE);
2056 unsigned int SetDoorState(unsigned int door_state)
2058 return MoveDoor(door_state | DOOR_SET_STATE);
2061 unsigned int MoveDoor(unsigned int door_state)
2063 static int door1 = DOOR_OPEN_1;
2064 static int door2 = DOOR_CLOSE_2;
2065 static unsigned long door_delay = 0;
2066 int x, start, stepsize = 2;
2067 unsigned long door_delay_value = stepsize * 5;
2069 if (door_state == DOOR_GET_STATE)
2070 return(door1 | door2);
2072 if (door_state & DOOR_SET_STATE)
2074 if (door_state & DOOR_ACTION_1)
2075 door1 = door_state & DOOR_ACTION_1;
2076 if (door_state & DOOR_ACTION_2)
2077 door2 = door_state & DOOR_ACTION_2;
2079 return(door1 | door2);
2082 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2083 door_state &= ~DOOR_OPEN_1;
2084 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2085 door_state &= ~DOOR_CLOSE_1;
2086 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2087 door_state &= ~DOOR_OPEN_2;
2088 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2089 door_state &= ~DOOR_CLOSE_2;
2091 if (setup.quick_doors)
2094 door_delay_value = 0;
2095 StopSound(SND_MENU_DOOR_OPENING);
2096 StopSound(SND_MENU_DOOR_CLOSING);
2099 if (door_state & DOOR_ACTION)
2101 if (!(door_state & DOOR_NO_DELAY))
2103 if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
2104 PlaySoundStereo(SND_MENU_DOOR_OPENING, SOUND_MAX_RIGHT);
2105 if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
2106 PlaySoundStereo(SND_MENU_DOOR_CLOSING, SOUND_MAX_RIGHT);
2109 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2111 for(x=start; x<=DXSIZE; x+=stepsize)
2113 Bitmap *bitmap = pix[PIX_DOOR];
2114 GC gc = bitmap->stored_clip_gc;
2116 WaitUntilDelayReached(&door_delay, door_delay_value);
2118 if (door_state & DOOR_ACTION_1)
2120 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2121 int j = (DXSIZE - i) / 3;
2123 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2124 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2125 DXSIZE,DYSIZE - i/2, DX, DY);
2127 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2129 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2130 BlitBitmapMasked(bitmap, drawto,
2131 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2132 DX + DXSIZE - i, DY + j);
2133 BlitBitmapMasked(bitmap, drawto,
2134 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2135 DX + DXSIZE - i, DY + 140 + j);
2136 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2137 BlitBitmapMasked(bitmap, drawto,
2138 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2140 BlitBitmapMasked(bitmap, drawto,
2141 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2144 BlitBitmapMasked(bitmap, drawto,
2145 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2147 BlitBitmapMasked(bitmap, drawto,
2148 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2150 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2151 BlitBitmapMasked(bitmap, drawto,
2152 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2153 DX + DXSIZE - i, DY + 77 + j);
2154 BlitBitmapMasked(bitmap, drawto,
2155 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2156 DX + DXSIZE - i, DY + 203 + j);
2158 redraw_mask |= REDRAW_DOOR_1;
2161 if (door_state & DOOR_ACTION_2)
2163 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2164 int j = (VXSIZE - i) / 3;
2166 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2167 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2168 VXSIZE, VYSIZE - i/2, VX, VY);
2170 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2172 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2173 BlitBitmapMasked(bitmap, drawto,
2174 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2175 VX + VXSIZE-i, VY+j);
2176 SetClipOrigin(bitmap, gc,
2177 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2178 BlitBitmapMasked(bitmap, drawto,
2179 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2182 BlitBitmapMasked(bitmap, drawto,
2183 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2184 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2185 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2186 BlitBitmapMasked(bitmap, drawto,
2187 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2189 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2191 redraw_mask |= REDRAW_DOOR_2;
2196 if (game_status == MAINMENU)
2201 if (setup.quick_doors)
2203 StopSound(SND_MENU_DOOR_OPENING);
2204 StopSound(SND_MENU_DOOR_CLOSING);
2207 if (door_state & DOOR_ACTION_1)
2208 door1 = door_state & DOOR_ACTION_1;
2209 if (door_state & DOOR_ACTION_2)
2210 door2 = door_state & DOOR_ACTION_2;
2212 return (door1 | door2);
2215 void DrawSpecialEditorDoor()
2217 /* draw bigger toolbox window */
2218 BlitBitmap(pix[PIX_DOOR], drawto,
2219 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2221 redraw_mask |= REDRAW_ALL;
2224 void UndrawSpecialEditorDoor()
2226 /* draw normal tape recorder window */
2227 BlitBitmap(pix[PIX_BACK], drawto,
2228 562, 344, 108, 56, EX - 4, EY - 12);
2230 redraw_mask |= REDRAW_ALL;
2234 int ReadPixel(DrawBuffer *bitmap, int x, int y)
2236 XImage *pixel_image;
2237 unsigned long pixel_value;
2239 pixel_image = XGetImage(display, bitmap->drawable,
2240 x, y, 1, 1, AllPlanes, ZPixmap);
2241 pixel_value = XGetPixel(pixel_image, 0, 0);
2243 XDestroyImage(pixel_image);
2249 /* ---------- new tool button stuff ---------------------------------------- */
2251 /* graphic position values for tool buttons */
2252 #define TOOL_BUTTON_YES_XPOS 2
2253 #define TOOL_BUTTON_YES_YPOS 250
2254 #define TOOL_BUTTON_YES_GFX_YPOS 0
2255 #define TOOL_BUTTON_YES_XSIZE 46
2256 #define TOOL_BUTTON_YES_YSIZE 28
2257 #define TOOL_BUTTON_NO_XPOS 52
2258 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2259 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2260 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2261 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2262 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2263 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2264 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2265 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2266 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2267 #define TOOL_BUTTON_PLAYER_XSIZE 30
2268 #define TOOL_BUTTON_PLAYER_YSIZE 30
2269 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2270 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2271 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2272 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2273 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2274 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2275 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2276 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2277 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2278 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2279 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2280 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2281 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2282 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2283 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2284 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2285 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2286 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2287 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2288 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2297 } toolbutton_info[NUM_TOOL_BUTTONS] =
2300 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2301 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2302 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2307 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2308 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2309 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2314 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2315 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2316 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2317 TOOL_CTRL_ID_CONFIRM,
2321 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2322 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2323 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2324 TOOL_CTRL_ID_PLAYER_1,
2328 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2329 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2330 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2331 TOOL_CTRL_ID_PLAYER_2,
2335 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2336 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2337 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2338 TOOL_CTRL_ID_PLAYER_3,
2342 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2343 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2344 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2345 TOOL_CTRL_ID_PLAYER_4,
2350 void CreateToolButtons()
2354 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2356 Bitmap *gd_bitmap = pix[PIX_DOOR];
2357 Bitmap *deco_bitmap = None;
2358 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2359 struct GadgetInfo *gi;
2360 unsigned long event_mask;
2361 int gd_xoffset, gd_yoffset;
2362 int gd_x1, gd_x2, gd_y;
2365 event_mask = GD_EVENT_RELEASED;
2367 gd_xoffset = toolbutton_info[i].xpos;
2368 gd_yoffset = toolbutton_info[i].ypos;
2369 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2370 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2371 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2373 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2375 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2376 &deco_bitmap, &deco_x, &deco_y);
2377 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2378 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2381 gi = CreateGadget(GDI_CUSTOM_ID, id,
2382 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2383 GDI_X, DX + toolbutton_info[i].x,
2384 GDI_Y, DY + toolbutton_info[i].y,
2385 GDI_WIDTH, toolbutton_info[i].width,
2386 GDI_HEIGHT, toolbutton_info[i].height,
2387 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2388 GDI_STATE, GD_BUTTON_UNPRESSED,
2389 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2390 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2391 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2392 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2393 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2394 GDI_DECORATION_SHIFTING, 1, 1,
2395 GDI_EVENT_MASK, event_mask,
2396 GDI_CALLBACK_ACTION, HandleToolButtons,
2400 Error(ERR_EXIT, "cannot create gadget");
2402 tool_gadget[id] = gi;
2406 static void UnmapToolButtons()
2410 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2411 UnmapGadget(tool_gadget[i]);
2414 static void HandleToolButtons(struct GadgetInfo *gi)
2416 request_gadget_id = gi->custom_id;
2419 int get_next_element(int element)
2423 case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
2424 case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
2425 case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
2426 case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
2427 case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
2428 case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
2429 case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
2431 default: return element;
2435 int el2gfx(int element)
2439 case EL_LEERRAUM: return -1;
2440 case EL_ERDREICH: return GFX_ERDREICH;
2441 case EL_MAUERWERK: return GFX_MAUERWERK;
2442 case EL_FELSBODEN: return GFX_FELSBODEN;
2443 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2444 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2445 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2446 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2447 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2448 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2449 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2450 case EL_SPIELER1: return GFX_SPIELER1;
2451 case EL_SPIELER2: return GFX_SPIELER2;
2452 case EL_SPIELER3: return GFX_SPIELER3;
2453 case EL_SPIELER4: return GFX_SPIELER4;
2454 case EL_KAEFER: return GFX_KAEFER;
2455 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2456 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2457 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2458 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2459 case EL_FLIEGER: return GFX_FLIEGER;
2460 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2461 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2462 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2463 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2464 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2465 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2466 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2467 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2468 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2469 case EL_FIREFLY: return GFX_FIREFLY;
2470 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2471 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2472 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2473 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2474 case EL_MAMPFER: return GFX_MAMPFER;
2475 case EL_ROBOT: return GFX_ROBOT;
2476 case EL_BETON: return GFX_BETON;
2477 case EL_DIAMANT: return GFX_DIAMANT;
2478 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2479 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2480 case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
2481 case EL_TROPFEN: return GFX_TROPFEN;
2482 case EL_BOMBE: return GFX_BOMBE;
2483 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2484 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2485 case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
2486 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2487 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2488 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2489 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2490 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2491 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2492 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2493 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2494 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2495 case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
2496 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2497 case EL_LIFE: return GFX_LIFE;
2498 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2499 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2500 case EL_BADEWANNE: return GFX_BADEWANNE;
2501 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2502 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2503 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2504 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2505 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2506 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2507 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2508 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2509 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2510 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2511 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2512 case EL_PFORTE1: return GFX_PFORTE1;
2513 case EL_PFORTE2: return GFX_PFORTE2;
2514 case EL_PFORTE3: return GFX_PFORTE3;
2515 case EL_PFORTE4: return GFX_PFORTE4;
2516 case EL_PFORTE1X: return GFX_PFORTE1X;
2517 case EL_PFORTE2X: return GFX_PFORTE2X;
2518 case EL_PFORTE3X: return GFX_PFORTE3X;
2519 case EL_PFORTE4X: return GFX_PFORTE4X;
2520 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2521 case EL_PACMAN: return GFX_PACMAN;
2522 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2523 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2524 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2525 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2526 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2527 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2528 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2529 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2530 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2531 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2532 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2533 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2534 case EL_MAUER_X: return GFX_MAUER_X;
2535 case EL_MAUER_Y: return GFX_MAUER_Y;
2536 case EL_MAUER_XY: return GFX_MAUER_XY;
2537 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2538 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2539 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2540 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2541 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2542 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2543 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2544 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2545 case EL_MAMPFER2: return GFX_MAMPFER2;
2546 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2547 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2548 case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
2549 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2550 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2551 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2552 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2553 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2554 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2555 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2556 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2557 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2558 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2559 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2560 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2561 case EL_MOLE: return GFX_MOLE;
2562 case EL_PINGUIN: return GFX_PINGUIN;
2563 case EL_SCHWEIN: return GFX_SCHWEIN;
2564 case EL_DRACHE: return GFX_DRACHE;
2565 case EL_SONDE: return GFX_SONDE;
2566 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2567 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2568 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2569 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2570 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2571 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2572 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2573 case EL_SP_ZONK: return GFX_SP_ZONK;
2574 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2575 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2576 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2577 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2578 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2579 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2580 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2581 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2582 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2583 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2584 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2585 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2586 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2587 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2588 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2589 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2590 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2591 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2592 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2593 case EL_PEARL: return GFX_PEARL;
2594 case EL_CRYSTAL: return GFX_CRYSTAL;
2595 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2596 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2597 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2598 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2599 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2600 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2601 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2602 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2603 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2604 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2605 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2606 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2607 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2608 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2609 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2610 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2611 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2612 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2613 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2614 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2615 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2616 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2617 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2618 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2619 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2620 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2621 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2622 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2623 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2624 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2625 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2626 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2627 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2628 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2629 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2630 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2631 case EL_LANDMINE: return GFX_LANDMINE;
2632 case EL_ENVELOPE: return GFX_ENVELOPE;
2633 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2634 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2635 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2636 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2637 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2638 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2639 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2640 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2641 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2642 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2643 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2644 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2645 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2646 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2647 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2648 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2649 case EL_MOLE_UP: return GFX_MOLE_UP;
2650 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2651 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2652 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2653 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2654 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2655 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2656 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2657 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2658 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2659 case EL_BALLOON: return GFX_BALLOON;
2660 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2661 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2662 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2663 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2664 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2665 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2666 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2667 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2668 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2669 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2670 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2671 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2672 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2673 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2674 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2675 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2676 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2677 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2678 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2679 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2680 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2681 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2682 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2683 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2684 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2685 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2686 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2687 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2688 case EL_SPRING: return GFX_SPRING;
2689 case EL_SPRING_MOVING: return GFX_SPRING;
2690 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2691 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2692 case EL_BD_WALL: return GFX_BD_WALL;
2693 case EL_BD_ROCK: return GFX_BD_ROCK;
2694 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2695 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2699 if (IS_CHAR(element))
2700 return GFX_CHAR_START + (element - EL_CHAR_START);
2701 else if (element >= EL_SP_START && element <= EL_SP_END)
2703 int nr_element = element - EL_SP_START;
2704 int gfx_per_line = 8;
2706 (nr_element / gfx_per_line) * SP_PER_LINE +
2707 (nr_element % gfx_per_line);
2709 return GFX_START_ROCKSSP + nr_graphic;