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_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;
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 void DrawGraphicAnimationExt(int x, int y, int graphic,
710 int frames, int delay, int mode, int mask_mode)
712 int phase = getGraphicAnimationPhase(frames, delay, mode);
714 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
716 if (mask_mode == USE_MASKING)
717 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
719 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
723 void DrawGraphicAnimation(int x, int y, int graphic,
724 int frames, int delay, int mode)
726 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
729 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
730 int frames, int delay, int mode)
732 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
735 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
738 int frames, int delay,
741 int phase = getGraphicAnimationPhase(frames, delay, mode);
743 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
746 void getGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
748 if (graphic >= 0 && graphic_info[graphic].bitmap != NULL)
750 *bitmap = graphic_info[graphic].bitmap;
751 *x = graphic_info[graphic].src_x;
752 *y = graphic_info[graphic].src_y;
754 else if (graphic >= GFX_START_ROCKSELEMENTS &&
755 graphic <= GFX_END_ROCKSELEMENTS)
757 graphic -= GFX_START_ROCKSELEMENTS;
758 *bitmap = pix[PIX_ELEMENTS];
759 *x = (graphic % GFX_PER_LINE) * TILEX;
760 *y = (graphic / GFX_PER_LINE) * TILEY;
762 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
764 graphic -= GFX_START_ROCKSHEROES;
765 *bitmap = pix[PIX_HEROES];
766 *x = (graphic % HEROES_PER_LINE) * TILEX;
767 *y = (graphic / HEROES_PER_LINE) * TILEY;
769 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
771 graphic -= GFX_START_ROCKSSP;
772 *bitmap = pix[PIX_SP];
773 *x = (graphic % SP_PER_LINE) * TILEX;
774 *y = (graphic / SP_PER_LINE) * TILEY;
776 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
778 graphic -= GFX_START_ROCKSDC;
779 *bitmap = pix[PIX_DC];
780 *x = (graphic % DC_PER_LINE) * TILEX;
781 *y = (graphic / DC_PER_LINE) * TILEY;
783 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
785 graphic -= GFX_START_ROCKSMORE;
786 *bitmap = pix[PIX_MORE];
787 *x = (graphic % MORE_PER_LINE) * TILEX;
788 *y = (graphic / MORE_PER_LINE) * TILEY;
790 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
792 graphic -= GFX_START_ROCKSFONT;
793 *bitmap = pix[PIX_BIGFONT];
794 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
795 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
796 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
800 *bitmap = pix[PIX_SP];
806 void DrawGraphic(int x, int y, int graphic)
809 if (!IN_SCR_FIELD(x,y))
811 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
812 printf("DrawGraphic(): This should never happen!\n");
817 DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
821 void DrawGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic)
826 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
827 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
830 void DrawGraphicThruMask(int x, int y, int graphic)
833 if (!IN_SCR_FIELD(x,y))
835 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
836 printf("DrawGraphicThruMask(): This should never happen!\n");
841 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
845 void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
852 if (graphic == GFX_LEERRAUM)
855 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
856 drawing_gc = src_bitmap->stored_clip_gc;
858 if (tile_clipmask[tile] != None)
860 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
861 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
862 BlitBitmapMasked(src_bitmap, d,
863 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
869 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
873 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
874 BlitBitmapMasked(src_bitmap, d,
875 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
879 void DrawMiniGraphic(int x, int y, int graphic)
881 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
882 MarkTileDirty(x/2, y/2);
885 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
887 if (graphic >= GFX_START_ROCKSELEMENTS && graphic <= GFX_END_ROCKSELEMENTS)
889 graphic -= GFX_START_ROCKSELEMENTS;
890 *bitmap = pix[PIX_ELEMENTS];
891 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
892 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
894 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
896 graphic -= GFX_START_ROCKSSP;
897 *bitmap = pix[PIX_SP];
898 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
899 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
901 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
903 graphic -= GFX_START_ROCKSDC;
904 *bitmap = pix[PIX_DC];
905 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
906 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
908 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
910 graphic -= GFX_START_ROCKSMORE;
911 *bitmap = pix[PIX_MORE];
912 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
913 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
915 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
917 graphic -= GFX_START_ROCKSFONT;
918 *bitmap = pix[PIX_SMALLFONT];
919 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
920 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
921 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
925 *bitmap = pix[PIX_SP];
931 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
936 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
937 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
940 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
941 int cut_mode, int mask_mode)
943 int width = TILEX, height = TILEY;
945 int src_x, src_y, dest_x, dest_y;
952 DrawGraphic(x, y, graphic);
956 if (dx || dy) /* Verschiebung der Grafik? */
958 if (x < BX1) /* Element kommt von links ins Bild */
965 else if (x > BX2) /* Element kommt von rechts ins Bild */
971 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
977 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
979 else if (dx) /* allg. Bewegung in x-Richtung */
980 MarkTileDirty(x + SIGN(dx), y);
982 if (y < BY1) /* Element kommt von oben ins Bild */
984 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
992 else if (y > BY2) /* Element kommt von unten ins Bild */
998 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1004 else if (dy > 0 && cut_mode == CUT_ABOVE)
1006 if (y == BY2) /* Element unterhalb des Bildes */
1012 MarkTileDirty(x, y + 1);
1013 } /* Element verläßt unten das Bild */
1014 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1016 else if (dy) /* allg. Bewegung in y-Richtung */
1017 MarkTileDirty(x, y + SIGN(dy));
1020 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
1021 drawing_gc = src_bitmap->stored_clip_gc;
1026 dest_x = FX + x * TILEX + dx;
1027 dest_y = FY + y * TILEY + dy;
1030 if (!IN_SCR_FIELD(x,y))
1032 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1033 printf("DrawGraphicShifted(): This should never happen!\n");
1038 if (mask_mode == USE_MASKING)
1040 if (tile_clipmask[tile] != None)
1042 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1043 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1044 BlitBitmapMasked(src_bitmap, drawto_field,
1045 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1051 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1055 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1056 BlitBitmapMasked(src_bitmap, drawto_field,
1057 src_x, src_y, width, height, dest_x, dest_y);
1061 BlitBitmap(src_bitmap, drawto_field,
1062 src_x, src_y, width, height, dest_x, dest_y);
1067 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1070 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1073 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1074 int cut_mode, int mask_mode)
1076 int ux = LEVELX(x), uy = LEVELY(y);
1077 int graphic = el2gfx(element);
1078 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1079 int phase4 = phase8 / 2;
1080 int phase2 = phase8 / 4;
1081 int dir = MovDir[ux][uy];
1083 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1085 graphic += 4 * !phase2;
1089 else if (dir == MV_LEFT)
1091 else if (dir == MV_DOWN)
1094 else if (element == EL_SP_SNIKSNAK)
1097 graphic = GFX_SP_SNIKSNAK_LEFT;
1098 else if (dir == MV_RIGHT)
1099 graphic = GFX_SP_SNIKSNAK_RIGHT;
1100 else if (dir == MV_UP)
1101 graphic = GFX_SP_SNIKSNAK_UP;
1103 graphic = GFX_SP_SNIKSNAK_DOWN;
1105 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1107 else if (element == EL_SP_ELECTRON)
1109 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1111 else if (element == EL_MOLE || element == EL_PINGUIN ||
1112 element == EL_SCHWEIN || element == EL_DRACHE)
1115 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1116 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1117 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1118 else if (dir == MV_RIGHT)
1119 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1120 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1121 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1122 else if (dir == MV_UP)
1123 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1124 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1125 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1127 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1128 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1129 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1133 else if (element == EL_SONDE)
1135 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1137 else if (element == EL_SALZSAEURE)
1139 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1141 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1145 else if (element == EL_BALLOON)
1149 else if ((element == EL_FELSBROCKEN ||
1150 element == EL_SP_ZONK ||
1151 element == EL_BD_ROCK ||
1152 element == EL_SP_INFOTRON ||
1156 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1158 if (element == EL_FELSBROCKEN ||
1159 element == EL_SP_ZONK ||
1160 element == EL_BD_ROCK)
1163 graphic += (4 - phase4) % 4;
1164 else if (dir == MV_RIGHT)
1167 graphic += phase2 * 2;
1169 else if (element != EL_SP_INFOTRON)
1173 else if (element == EL_MAGIC_WALL_EMPTY ||
1174 element == EL_MAGIC_WALL_EMPTYING ||
1175 element == EL_MAGIC_WALL_BD_EMPTY ||
1176 element == EL_MAGIC_WALL_BD_EMPTYING ||
1177 element == EL_MAGIC_WALL_FULL ||
1178 element == EL_MAGIC_WALL_BD_FULL)
1180 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1182 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1184 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1185 graphic += (x + 2 * y + 4) % 4;
1187 else if (element == EL_MAUER_LEBT)
1189 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1191 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1192 links_massiv = TRUE;
1193 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1194 rechts_massiv = TRUE;
1196 if (links_massiv && rechts_massiv)
1197 graphic = GFX_MAUERWERK;
1198 else if (links_massiv)
1199 graphic = GFX_MAUER_R;
1200 else if (rechts_massiv)
1201 graphic = GFX_MAUER_L;
1203 else if ((element == EL_INVISIBLE_STEEL ||
1204 element == EL_UNSICHTBAR ||
1205 element == EL_SAND_INVISIBLE) && game.light_time_left)
1207 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1208 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1209 GFX_SAND_INVISIBLE_ON);
1213 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1214 else if (mask_mode == USE_MASKING)
1215 DrawGraphicThruMask(x, y, graphic);
1217 DrawGraphic(x, y, graphic);
1220 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1221 int cut_mode, int mask_mode)
1223 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1224 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1225 cut_mode, mask_mode);
1228 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1231 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1234 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1237 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1240 void DrawScreenElementThruMask(int x, int y, int element)
1242 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1245 void DrawLevelElementThruMask(int x, int y, int element)
1247 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1250 void DrawLevelFieldThruMask(int x, int y)
1252 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1255 void ErdreichAnbroeckeln(int x, int y)
1259 int i, width, height, cx,cy;
1260 int ux = LEVELX(x), uy = LEVELY(y);
1261 int element, graphic;
1263 static int xy[4][2] =
1271 if (!IN_LEV_FIELD(ux, uy))
1274 element = Feld[ux][uy];
1276 if (element == EL_ERDREICH ||
1277 element == EL_LANDMINE ||
1278 element == EL_TRAP_INACTIVE ||
1279 element == EL_TRAP_ACTIVE)
1281 if (!IN_SCR_FIELD(x, y))
1284 graphic = GFX_ERDENRAND;
1286 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
1292 uxx = ux + xy[i][0];
1293 uyy = uy + xy[i][1];
1294 if (!IN_LEV_FIELD(uxx, uyy))
1297 element = Feld[uxx][uyy];
1299 if (element == EL_ERDREICH ||
1300 element == EL_LANDMINE ||
1301 element == EL_TRAP_INACTIVE ||
1302 element == EL_TRAP_ACTIVE)
1305 if (i == 1 || i == 2)
1309 cx = (i == 2 ? TILEX - snip : 0);
1317 cy = (i == 3 ? TILEY - snip : 0);
1320 BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
1321 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1324 MarkTileDirty(x, y);
1328 graphic = GFX_ERDENRAND;
1330 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
1334 int xx, yy, uxx, uyy;
1338 uxx = ux + xy[i][0];
1339 uyy = uy + xy[i][1];
1341 if (!IN_LEV_FIELD(uxx, uyy) ||
1342 (Feld[uxx][uyy] != EL_ERDREICH &&
1343 Feld[uxx][uyy] != EL_LANDMINE &&
1344 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1345 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1346 !IN_SCR_FIELD(xx, yy))
1349 if (i == 1 || i == 2)
1353 cx = (i == 1 ? TILEX - snip : 0);
1361 cy = (i==0 ? TILEY-snip : 0);
1364 BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
1365 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1367 MarkTileDirty(xx, yy);
1372 void DrawScreenElement(int x, int y, int element)
1374 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1375 ErdreichAnbroeckeln(x, y);
1378 void DrawLevelElement(int x, int y, int element)
1380 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1381 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1384 void DrawScreenField(int x, int y)
1386 int ux = LEVELX(x), uy = LEVELY(y);
1387 int element, content;
1389 if (!IN_LEV_FIELD(ux, uy))
1391 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1392 element = EL_LEERRAUM;
1394 element = BorderElement;
1396 DrawScreenElement(x, y, element);
1400 element = Feld[ux][uy];
1401 content = Store[ux][uy];
1403 if (IS_MOVING(ux, uy))
1405 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1406 boolean cut_mode = NO_CUTTING;
1408 if (element == EL_QUICKSAND_EMPTYING ||
1409 element == EL_MAGIC_WALL_EMPTYING ||
1410 element == EL_MAGIC_WALL_BD_EMPTYING ||
1411 element == EL_AMOEBA_DRIPPING)
1412 cut_mode = CUT_ABOVE;
1413 else if (element == EL_QUICKSAND_FILLING ||
1414 element == EL_MAGIC_WALL_FILLING ||
1415 element == EL_MAGIC_WALL_BD_FILLING)
1416 cut_mode = CUT_BELOW;
1418 if (cut_mode == CUT_ABOVE)
1419 DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1421 DrawScreenElement(x, y, EL_LEERRAUM);
1424 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1425 else if (cut_mode == NO_CUTTING)
1426 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1428 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1430 if (content == EL_SALZSAEURE)
1431 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1433 else if (IS_BLOCKED(ux, uy))
1438 boolean cut_mode = NO_CUTTING;
1439 int element_old, content_old;
1441 Blocked2Moving(ux, uy, &oldx, &oldy);
1444 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1445 MovDir[oldx][oldy] == MV_RIGHT);
1447 element_old = Feld[oldx][oldy];
1448 content_old = Store[oldx][oldy];
1450 if (element_old == EL_QUICKSAND_EMPTYING ||
1451 element_old == EL_MAGIC_WALL_EMPTYING ||
1452 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1453 element_old == EL_AMOEBA_DRIPPING)
1454 cut_mode = CUT_ABOVE;
1456 DrawScreenElement(x, y, EL_LEERRAUM);
1459 DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1461 else if (cut_mode == NO_CUTTING)
1462 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1465 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
1468 else if (IS_DRAWABLE(element))
1469 DrawScreenElement(x, y, element);
1471 DrawScreenElement(x, y, EL_LEERRAUM);
1474 void DrawLevelField(int x, int y)
1476 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1477 DrawScreenField(SCREENX(x), SCREENY(y));
1478 else if (IS_MOVING(x, y))
1482 Moving2Blocked(x, y, &newx, &newy);
1483 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1484 DrawScreenField(SCREENX(newx), SCREENY(newy));
1486 else if (IS_BLOCKED(x, y))
1490 Blocked2Moving(x, y, &oldx, &oldy);
1491 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1492 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1496 void DrawMiniElement(int x, int y, int element)
1502 DrawMiniGraphic(x, y, -1);
1506 graphic = el2gfx(element);
1507 DrawMiniGraphic(x, y, graphic);
1510 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1512 int x = sx + scroll_x, y = sy + scroll_y;
1514 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1515 DrawMiniElement(sx, sy, EL_LEERRAUM);
1516 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1517 DrawMiniElement(sx, sy, Feld[x][y]);
1520 int steel_type, steel_position;
1523 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1524 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1525 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1526 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1527 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1528 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1531 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1532 steel_position = (x == -1 && y == -1 ? 0 :
1533 x == lev_fieldx && y == -1 ? 1 :
1534 x == -1 && y == lev_fieldy ? 2 :
1535 x == lev_fieldx && y == lev_fieldy ? 3 :
1536 x == -1 || x == lev_fieldx ? 4 :
1537 y == -1 || y == lev_fieldy ? 5 : -1);
1539 if (steel_position != -1)
1540 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1544 void DrawMicroElement(int xpos, int ypos, int element)
1548 if (element == EL_LEERRAUM)
1551 graphic = el2gfx(element);
1553 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1555 graphic -= GFX_START_ROCKSSP;
1556 BlitBitmap(pix[PIX_SP], drawto,
1557 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1558 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1559 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1561 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1563 graphic -= GFX_START_ROCKSDC;
1564 BlitBitmap(pix[PIX_DC], drawto,
1565 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1566 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1567 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1569 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1571 graphic -= GFX_START_ROCKSMORE;
1572 BlitBitmap(pix[PIX_MORE], drawto,
1573 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1574 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1575 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1578 BlitBitmap(pix[PIX_ELEMENTS], drawto,
1579 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1580 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1581 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1590 for(x=BX1; x<=BX2; x++)
1591 for(y=BY1; y<=BY2; y++)
1592 DrawScreenField(x, y);
1594 redraw_mask |= REDRAW_FIELD;
1597 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1601 for(x=0; x<size_x; x++)
1602 for(y=0; y<size_y; y++)
1603 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1605 redraw_mask |= REDRAW_FIELD;
1608 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1612 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1614 if (lev_fieldx < STD_LEV_FIELDX)
1615 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1616 if (lev_fieldy < STD_LEV_FIELDY)
1617 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1619 xpos += MICRO_TILEX;
1620 ypos += MICRO_TILEY;
1622 for(x=-1; x<=STD_LEV_FIELDX; x++)
1624 for(y=-1; y<=STD_LEV_FIELDY; y++)
1626 int lx = from_x + x, ly = from_y + y;
1628 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1629 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1631 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1632 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1637 redraw_mask |= REDRAW_MICROLEVEL;
1640 #define MICROLABEL_EMPTY 0
1641 #define MICROLABEL_LEVEL_NAME 1
1642 #define MICROLABEL_CREATED_BY 2
1643 #define MICROLABEL_LEVEL_AUTHOR 3
1644 #define MICROLABEL_IMPORTED_FROM 4
1645 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1647 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1649 static void DrawMicroLevelLabelExt(int mode)
1651 char label_text[MAX_MICROLABEL_SIZE + 1];
1653 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1655 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1656 mode == MICROLABEL_CREATED_BY ? "created by" :
1657 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1658 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1659 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1660 leveldir_current->imported_from : ""),
1661 MAX_MICROLABEL_SIZE);
1662 label_text[MAX_MICROLABEL_SIZE] = '\0';
1664 if (strlen(label_text) > 0)
1666 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1667 int lypos = MICROLABEL_YPOS;
1669 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1672 redraw_mask |= REDRAW_MICROLEVEL;
1675 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1677 static unsigned long scroll_delay = 0;
1678 static unsigned long label_delay = 0;
1679 static int from_x, from_y, scroll_direction;
1680 static int label_state, label_counter;
1684 from_x = from_y = 0;
1685 scroll_direction = MV_RIGHT;
1689 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1690 DrawMicroLevelLabelExt(label_state);
1692 /* initialize delay counters */
1693 DelayReached(&scroll_delay, 0);
1694 DelayReached(&label_delay, 0);
1699 /* scroll micro level, if needed */
1700 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1701 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1703 switch (scroll_direction)
1709 scroll_direction = MV_UP;
1713 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1716 scroll_direction = MV_DOWN;
1723 scroll_direction = MV_RIGHT;
1727 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1730 scroll_direction = MV_LEFT;
1737 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1740 /* redraw micro level label, if needed */
1741 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1742 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1743 strcmp(level.author, leveldir_current->name) != 0 &&
1744 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1746 int max_label_counter = 23;
1748 if (leveldir_current->imported_from != NULL)
1749 max_label_counter += 14;
1751 label_counter = (label_counter + 1) % max_label_counter;
1752 label_state = (label_counter >= 0 && label_counter <= 7 ?
1753 MICROLABEL_LEVEL_NAME :
1754 label_counter >= 9 && label_counter <= 12 ?
1755 MICROLABEL_CREATED_BY :
1756 label_counter >= 14 && label_counter <= 21 ?
1757 MICROLABEL_LEVEL_AUTHOR :
1758 label_counter >= 23 && label_counter <= 26 ?
1759 MICROLABEL_IMPORTED_FROM :
1760 label_counter >= 28 && label_counter <= 35 ?
1761 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1762 DrawMicroLevelLabelExt(label_state);
1766 int REQ_in_range(int x, int y)
1768 if (y > DY+249 && y < DY+278)
1770 if (x > DX+1 && x < DX+48)
1772 else if (x > DX+51 && x < DX+98)
1778 #define MAX_REQUEST_LINES 13
1779 #define MAX_REQUEST_LINE_LEN 7
1781 boolean Request(char *text, unsigned int req_state)
1783 int mx, my, ty, result = -1;
1784 unsigned int old_door_state;
1786 #if defined(PLATFORM_UNIX)
1787 /* pause network game while waiting for request to answer */
1788 if (options.network &&
1789 game_status == PLAYING &&
1790 req_state & REQUEST_WAIT_FOR)
1791 SendToServer_PausePlaying();
1794 old_door_state = GetDoorState();
1798 CloseDoor(DOOR_CLOSE_1);
1800 /* save old door content */
1801 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1802 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1803 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1805 /* clear door drawing field */
1806 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1808 /* write text for request */
1809 for(ty=0; ty < MAX_REQUEST_LINES; ty++)
1811 char text_line[MAX_REQUEST_LINE_LEN + 1];
1817 for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
1820 if (!tc || tc == ' ')
1831 strncpy(text_line, text, tl);
1834 DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
1835 text_line, FS_SMALL, FC_YELLOW);
1837 text += tl + (tc == ' ' ? 1 : 0);
1840 if (req_state & REQ_ASK)
1842 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1843 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1845 else if (req_state & REQ_CONFIRM)
1847 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1849 else if (req_state & REQ_PLAYER)
1851 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1852 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1853 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1854 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1857 /* copy request gadgets to door backbuffer */
1858 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1859 DX, DY, DXSIZE, DYSIZE,
1860 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1862 OpenDoor(DOOR_OPEN_1);
1868 if (!(req_state & REQUEST_WAIT_FOR))
1871 if (game_status != MAINMENU)
1874 button_status = MB_RELEASED;
1876 request_gadget_id = -1;
1888 case EVENT_BUTTONPRESS:
1889 case EVENT_BUTTONRELEASE:
1890 case EVENT_MOTIONNOTIFY:
1892 if (event.type == EVENT_MOTIONNOTIFY)
1894 if (!PointerInWindow(window))
1895 continue; /* window and pointer are on different screens */
1900 motion_status = TRUE;
1901 mx = ((MotionEvent *) &event)->x;
1902 my = ((MotionEvent *) &event)->y;
1906 motion_status = FALSE;
1907 mx = ((ButtonEvent *) &event)->x;
1908 my = ((ButtonEvent *) &event)->y;
1909 if (event.type == EVENT_BUTTONPRESS)
1910 button_status = ((ButtonEvent *) &event)->button;
1912 button_status = MB_RELEASED;
1915 /* this sets 'request_gadget_id' */
1916 HandleGadgets(mx, my, button_status);
1918 switch(request_gadget_id)
1920 case TOOL_CTRL_ID_YES:
1923 case TOOL_CTRL_ID_NO:
1926 case TOOL_CTRL_ID_CONFIRM:
1927 result = TRUE | FALSE;
1930 case TOOL_CTRL_ID_PLAYER_1:
1933 case TOOL_CTRL_ID_PLAYER_2:
1936 case TOOL_CTRL_ID_PLAYER_3:
1939 case TOOL_CTRL_ID_PLAYER_4:
1950 case EVENT_KEYPRESS:
1951 switch(GetEventKey((KeyEvent *)&event, TRUE))
1964 if (req_state & REQ_PLAYER)
1968 case EVENT_KEYRELEASE:
1969 ClearPlayerAction();
1973 HandleOtherEvents(&event);
1977 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1979 int joy = AnyJoystick();
1981 if (joy & JOY_BUTTON_1)
1983 else if (joy & JOY_BUTTON_2)
1989 /* don't eat all CPU time */
1993 if (game_status != MAINMENU)
1998 if (!(req_state & REQ_STAY_OPEN))
2000 CloseDoor(DOOR_CLOSE_1);
2002 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2004 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2005 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2006 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2007 OpenDoor(DOOR_OPEN_1);
2013 #if defined(PLATFORM_UNIX)
2014 /* continue network game after request */
2015 if (options.network &&
2016 game_status == PLAYING &&
2017 req_state & REQUEST_WAIT_FOR)
2018 SendToServer_ContinuePlaying();
2024 unsigned int OpenDoor(unsigned int door_state)
2026 unsigned int new_door_state;
2028 if (door_state & DOOR_COPY_BACK)
2030 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2031 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2032 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2033 door_state &= ~DOOR_COPY_BACK;
2036 new_door_state = MoveDoor(door_state);
2038 return(new_door_state);
2041 unsigned int CloseDoor(unsigned int door_state)
2043 unsigned int new_door_state;
2045 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2046 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2047 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2048 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2050 new_door_state = MoveDoor(door_state);
2052 return(new_door_state);
2055 unsigned int GetDoorState()
2057 return MoveDoor(DOOR_GET_STATE);
2060 unsigned int SetDoorState(unsigned int door_state)
2062 return MoveDoor(door_state | DOOR_SET_STATE);
2065 unsigned int MoveDoor(unsigned int door_state)
2067 static int door1 = DOOR_OPEN_1;
2068 static int door2 = DOOR_CLOSE_2;
2069 static unsigned long door_delay = 0;
2070 int x, start, stepsize = 2;
2071 unsigned long door_delay_value = stepsize * 5;
2073 if (door_state == DOOR_GET_STATE)
2074 return(door1 | door2);
2076 if (door_state & DOOR_SET_STATE)
2078 if (door_state & DOOR_ACTION_1)
2079 door1 = door_state & DOOR_ACTION_1;
2080 if (door_state & DOOR_ACTION_2)
2081 door2 = door_state & DOOR_ACTION_2;
2083 return(door1 | door2);
2086 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2087 door_state &= ~DOOR_OPEN_1;
2088 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2089 door_state &= ~DOOR_CLOSE_1;
2090 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2091 door_state &= ~DOOR_OPEN_2;
2092 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2093 door_state &= ~DOOR_CLOSE_2;
2095 if (setup.quick_doors)
2098 door_delay_value = 0;
2099 StopSound(SND_MENU_DOOR_OPENING);
2100 StopSound(SND_MENU_DOOR_CLOSING);
2103 if (door_state & DOOR_ACTION)
2105 if (!(door_state & DOOR_NO_DELAY))
2107 /* opening door sound has priority over simultaneously closing door */
2108 if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
2109 PlaySoundStereo(SND_MENU_DOOR_OPENING, SOUND_MAX_RIGHT);
2110 else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
2111 PlaySoundStereo(SND_MENU_DOOR_CLOSING, SOUND_MAX_RIGHT);
2114 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2116 for(x=start; x<=DXSIZE; x+=stepsize)
2118 Bitmap *bitmap = pix[PIX_DOOR];
2119 GC gc = bitmap->stored_clip_gc;
2121 WaitUntilDelayReached(&door_delay, door_delay_value);
2123 if (door_state & DOOR_ACTION_1)
2125 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2126 int j = (DXSIZE - i) / 3;
2128 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2129 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2130 DXSIZE,DYSIZE - i/2, DX, DY);
2132 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2134 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2135 BlitBitmapMasked(bitmap, drawto,
2136 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2137 DX + DXSIZE - i, DY + j);
2138 BlitBitmapMasked(bitmap, drawto,
2139 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2140 DX + DXSIZE - i, DY + 140 + j);
2141 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2142 BlitBitmapMasked(bitmap, drawto,
2143 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2145 BlitBitmapMasked(bitmap, drawto,
2146 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2149 BlitBitmapMasked(bitmap, drawto,
2150 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2152 BlitBitmapMasked(bitmap, drawto,
2153 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2155 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2156 BlitBitmapMasked(bitmap, drawto,
2157 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2158 DX + DXSIZE - i, DY + 77 + j);
2159 BlitBitmapMasked(bitmap, drawto,
2160 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2161 DX + DXSIZE - i, DY + 203 + j);
2163 redraw_mask |= REDRAW_DOOR_1;
2166 if (door_state & DOOR_ACTION_2)
2168 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2169 int j = (VXSIZE - i) / 3;
2171 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2172 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2173 VXSIZE, VYSIZE - i/2, VX, VY);
2175 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2177 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2178 BlitBitmapMasked(bitmap, drawto,
2179 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2180 VX + VXSIZE-i, VY+j);
2181 SetClipOrigin(bitmap, gc,
2182 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2183 BlitBitmapMasked(bitmap, drawto,
2184 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2187 BlitBitmapMasked(bitmap, drawto,
2188 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2189 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2190 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2191 BlitBitmapMasked(bitmap, drawto,
2192 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2194 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2196 redraw_mask |= REDRAW_DOOR_2;
2201 if (game_status == MAINMENU)
2206 if (setup.quick_doors)
2208 StopSound(SND_MENU_DOOR_OPENING);
2209 StopSound(SND_MENU_DOOR_CLOSING);
2212 if (door_state & DOOR_ACTION_1)
2213 door1 = door_state & DOOR_ACTION_1;
2214 if (door_state & DOOR_ACTION_2)
2215 door2 = door_state & DOOR_ACTION_2;
2217 return (door1 | door2);
2220 void DrawSpecialEditorDoor()
2222 /* draw bigger toolbox window */
2223 BlitBitmap(pix[PIX_DOOR], drawto,
2224 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2226 redraw_mask |= REDRAW_ALL;
2229 void UndrawSpecialEditorDoor()
2231 /* draw normal tape recorder window */
2232 BlitBitmap(pix[PIX_BACK], drawto,
2233 562, 344, 108, 56, EX - 4, EY - 12);
2235 redraw_mask |= REDRAW_ALL;
2239 int ReadPixel(DrawBuffer *bitmap, int x, int y)
2241 XImage *pixel_image;
2242 unsigned long pixel_value;
2244 pixel_image = XGetImage(display, bitmap->drawable,
2245 x, y, 1, 1, AllPlanes, ZPixmap);
2246 pixel_value = XGetPixel(pixel_image, 0, 0);
2248 XDestroyImage(pixel_image);
2254 /* ---------- new tool button stuff ---------------------------------------- */
2256 /* graphic position values for tool buttons */
2257 #define TOOL_BUTTON_YES_XPOS 2
2258 #define TOOL_BUTTON_YES_YPOS 250
2259 #define TOOL_BUTTON_YES_GFX_YPOS 0
2260 #define TOOL_BUTTON_YES_XSIZE 46
2261 #define TOOL_BUTTON_YES_YSIZE 28
2262 #define TOOL_BUTTON_NO_XPOS 52
2263 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2264 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2265 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2266 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2267 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2268 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2269 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2270 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2271 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2272 #define TOOL_BUTTON_PLAYER_XSIZE 30
2273 #define TOOL_BUTTON_PLAYER_YSIZE 30
2274 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2275 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2276 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2277 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2278 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2279 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2280 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2281 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2282 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2283 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2284 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2285 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2286 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2287 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2288 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2289 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2290 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2291 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2292 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2293 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2302 } toolbutton_info[NUM_TOOL_BUTTONS] =
2305 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2306 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2307 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2312 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2313 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2314 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2319 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2320 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2321 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2322 TOOL_CTRL_ID_CONFIRM,
2326 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2327 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2328 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2329 TOOL_CTRL_ID_PLAYER_1,
2333 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2334 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2335 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2336 TOOL_CTRL_ID_PLAYER_2,
2340 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2341 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2342 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2343 TOOL_CTRL_ID_PLAYER_3,
2347 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2348 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2349 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2350 TOOL_CTRL_ID_PLAYER_4,
2355 void CreateToolButtons()
2359 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2361 Bitmap *gd_bitmap = pix[PIX_DOOR];
2362 Bitmap *deco_bitmap = None;
2363 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2364 struct GadgetInfo *gi;
2365 unsigned long event_mask;
2366 int gd_xoffset, gd_yoffset;
2367 int gd_x1, gd_x2, gd_y;
2370 event_mask = GD_EVENT_RELEASED;
2372 gd_xoffset = toolbutton_info[i].xpos;
2373 gd_yoffset = toolbutton_info[i].ypos;
2374 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2375 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2376 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2378 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2380 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2381 &deco_bitmap, &deco_x, &deco_y);
2382 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2383 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2386 gi = CreateGadget(GDI_CUSTOM_ID, id,
2387 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2388 GDI_X, DX + toolbutton_info[i].x,
2389 GDI_Y, DY + toolbutton_info[i].y,
2390 GDI_WIDTH, toolbutton_info[i].width,
2391 GDI_HEIGHT, toolbutton_info[i].height,
2392 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2393 GDI_STATE, GD_BUTTON_UNPRESSED,
2394 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2395 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2396 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2397 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2398 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2399 GDI_DECORATION_SHIFTING, 1, 1,
2400 GDI_EVENT_MASK, event_mask,
2401 GDI_CALLBACK_ACTION, HandleToolButtons,
2405 Error(ERR_EXIT, "cannot create gadget");
2407 tool_gadget[id] = gi;
2411 static void UnmapToolButtons()
2415 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2416 UnmapGadget(tool_gadget[i]);
2419 static void HandleToolButtons(struct GadgetInfo *gi)
2421 request_gadget_id = gi->custom_id;
2424 int get_next_element(int element)
2428 case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
2429 case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
2430 case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
2431 case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
2432 case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
2433 case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
2434 case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
2436 default: return element;
2440 int el2gfx_OLD(int element)
2444 case EL_LEERRAUM: return -1;
2445 case EL_ERDREICH: return GFX_ERDREICH;
2446 case EL_MAUERWERK: return GFX_MAUERWERK;
2447 case EL_FELSBODEN: return GFX_FELSBODEN;
2448 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2449 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2450 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2451 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2452 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2453 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2454 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2455 case EL_SPIELER1: return GFX_SPIELER1;
2456 case EL_SPIELER2: return GFX_SPIELER2;
2457 case EL_SPIELER3: return GFX_SPIELER3;
2458 case EL_SPIELER4: return GFX_SPIELER4;
2459 case EL_KAEFER: return GFX_KAEFER;
2460 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2461 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2462 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2463 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2464 case EL_FLIEGER: return GFX_FLIEGER;
2465 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2466 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2467 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2468 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2469 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2470 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2471 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2472 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2473 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2474 case EL_FIREFLY: return GFX_FIREFLY;
2475 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2476 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2477 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2478 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2479 case EL_MAMPFER: return GFX_MAMPFER;
2480 case EL_ROBOT: return GFX_ROBOT;
2481 case EL_BETON: return GFX_BETON;
2482 case EL_DIAMANT: return GFX_DIAMANT;
2483 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2484 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2485 case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
2486 case EL_TROPFEN: return GFX_TROPFEN;
2487 case EL_BOMBE: return GFX_BOMBE;
2488 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2489 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2490 case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
2491 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2492 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2493 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2494 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2495 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2496 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2497 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2498 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2499 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2500 case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
2501 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2502 case EL_LIFE: return GFX_LIFE;
2503 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2504 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2505 case EL_BADEWANNE: return GFX_BADEWANNE;
2506 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2507 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2508 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2509 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2510 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2511 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2512 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2513 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2514 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2515 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2516 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2517 case EL_PFORTE1: return GFX_PFORTE1;
2518 case EL_PFORTE2: return GFX_PFORTE2;
2519 case EL_PFORTE3: return GFX_PFORTE3;
2520 case EL_PFORTE4: return GFX_PFORTE4;
2521 case EL_PFORTE1X: return GFX_PFORTE1X;
2522 case EL_PFORTE2X: return GFX_PFORTE2X;
2523 case EL_PFORTE3X: return GFX_PFORTE3X;
2524 case EL_PFORTE4X: return GFX_PFORTE4X;
2525 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2526 case EL_PACMAN: return GFX_PACMAN;
2527 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2528 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2529 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2530 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2531 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2532 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2533 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2534 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2535 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2536 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2537 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2538 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2539 case EL_MAUER_X: return GFX_MAUER_X;
2540 case EL_MAUER_Y: return GFX_MAUER_Y;
2541 case EL_MAUER_XY: return GFX_MAUER_XY;
2542 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2543 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2544 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2545 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2546 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2547 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2548 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2549 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2550 case EL_MAMPFER2: return GFX_MAMPFER2;
2551 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2552 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2553 case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
2554 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2555 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2556 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2557 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2558 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2559 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2560 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2561 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2562 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2563 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2564 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2565 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2566 case EL_MOLE: return GFX_MOLE;
2567 case EL_PINGUIN: return GFX_PINGUIN;
2568 case EL_SCHWEIN: return GFX_SCHWEIN;
2569 case EL_DRACHE: return GFX_DRACHE;
2570 case EL_SONDE: return GFX_SONDE;
2571 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2572 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2573 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2574 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2575 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2576 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2577 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2578 case EL_SP_ZONK: return GFX_SP_ZONK;
2579 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2580 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2581 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2582 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2583 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2584 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2585 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2586 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2587 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2588 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2589 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2590 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2591 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2592 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2593 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2594 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2595 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2596 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2597 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2598 case EL_PEARL: return GFX_PEARL;
2599 case EL_CRYSTAL: return GFX_CRYSTAL;
2600 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2601 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2602 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2603 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2604 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2605 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2606 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2607 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2608 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2609 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2610 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2611 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2612 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2613 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2614 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2615 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2616 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2617 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2618 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2619 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2620 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2621 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2622 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2623 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2624 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2625 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2626 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2627 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2628 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2629 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2630 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2631 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2632 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2633 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2634 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2635 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2636 case EL_LANDMINE: return GFX_LANDMINE;
2637 case EL_ENVELOPE: return GFX_ENVELOPE;
2638 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2639 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2640 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2641 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2642 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2643 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2644 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2645 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2646 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2647 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2648 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2649 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2650 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2651 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2652 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2653 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2654 case EL_MOLE_UP: return GFX_MOLE_UP;
2655 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2656 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2657 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2658 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2659 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2660 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2661 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2662 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2663 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2664 case EL_BALLOON: return GFX_BALLOON;
2665 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2666 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2667 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2668 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2669 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2670 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2671 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2672 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2673 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2674 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2675 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2676 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2677 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2678 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2679 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2680 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2681 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2682 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2683 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2684 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2685 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2686 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2687 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2688 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2689 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2690 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2691 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2692 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2693 case EL_SPRING: return GFX_SPRING;
2694 case EL_SPRING_MOVING: return GFX_SPRING;
2695 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2696 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2697 case EL_BD_WALL: return GFX_BD_WALL;
2698 case EL_BD_ROCK: return GFX_BD_ROCK;
2699 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2700 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2704 if (IS_CHAR(element))
2705 return GFX_CHAR_START + (element - EL_CHAR_START);
2706 else if (element >= EL_SP_START && element <= EL_SP_END)
2708 int nr_element = element - EL_SP_START;
2709 int gfx_per_line = 8;
2711 (nr_element / gfx_per_line) * SP_PER_LINE +
2712 (nr_element % gfx_per_line);
2714 return GFX_START_ROCKSSP + nr_graphic;
2722 int el2gfx(int element)
2724 int graphic_NEW = element_info[element].graphic;
2727 int graphic_OLD = el2gfx_OLD(element);
2729 if (element >= MAX_ELEMENTS)
2731 Error(ERR_WARN, "el2gfx: element == %d >= MAX_ELEMENTS", element);
2734 if (graphic_NEW != graphic_OLD)
2736 Error(ERR_WARN, "el2gfx: graphic_NEW (%d) != graphic_OLD (%d)",
2737 graphic_NEW, graphic_OLD);