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;
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, Bitmap **bitmap, int *x, int *y)
747 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
749 graphic -= GFX_START_ROCKSSCREEN;
750 *bitmap = pix[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 = pix[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;
764 *bitmap = pix[PIX_SP];
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;
771 *bitmap = pix[PIX_DC];
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 = pix[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 = pix[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);
792 *bitmap = pix[PIX_SP];
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 *dst_bitmap, int x, int y, int graphic)
818 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
819 BlitBitmap(src_bitmap, dst_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)
844 if (graphic == GFX_LEERRAUM)
847 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
848 drawing_gc = src_bitmap->stored_clip_gc;
850 if (tile_clipmask[tile] != None)
852 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
853 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
854 BlitBitmapMasked(src_bitmap, d,
855 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
861 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
865 SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
866 BlitBitmapMasked(src_bitmap, d,
867 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
871 void DrawMiniGraphic(int x, int y, int graphic)
873 DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
874 MarkTileDirty(x/2, y/2);
877 void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
879 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
881 graphic -= GFX_START_ROCKSSCREEN;
882 *bitmap = pix[PIX_BACK];
883 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
884 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
886 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
888 graphic -= GFX_START_ROCKSSP;
889 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
890 *bitmap = pix[PIX_SP];
891 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
892 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
894 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
896 graphic -= GFX_START_ROCKSDC;
897 *bitmap = pix[PIX_DC];
898 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
899 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
901 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
903 graphic -= GFX_START_ROCKSMORE;
904 *bitmap = pix[PIX_MORE];
905 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
906 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
908 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
910 graphic -= GFX_START_ROCKSFONT;
911 *bitmap = pix[PIX_SMALLFONT];
912 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
913 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
914 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
918 *bitmap = pix[PIX_SP];
924 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
929 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
930 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
933 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
934 int cut_mode, int mask_mode)
936 int width = TILEX, height = TILEY;
938 int src_x, src_y, dest_x, dest_y;
945 DrawGraphic(x, y, graphic);
949 if (dx || dy) /* Verschiebung der Grafik? */
951 if (x < BX1) /* Element kommt von links ins Bild */
958 else if (x > BX2) /* Element kommt von rechts ins Bild */
964 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
970 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
972 else if (dx) /* allg. Bewegung in x-Richtung */
973 MarkTileDirty(x + SIGN(dx), y);
975 if (y < BY1) /* Element kommt von oben ins Bild */
977 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
985 else if (y > BY2) /* Element kommt von unten ins Bild */
991 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
997 else if (dy > 0 && cut_mode == CUT_ABOVE)
999 if (y == BY2) /* Element unterhalb des Bildes */
1005 MarkTileDirty(x, y + 1);
1006 } /* Element verläßt unten das Bild */
1007 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1009 else if (dy) /* allg. Bewegung in y-Richtung */
1010 MarkTileDirty(x, y + SIGN(dy));
1013 getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
1014 drawing_gc = src_bitmap->stored_clip_gc;
1019 dest_x = FX + x * TILEX + dx;
1020 dest_y = FY + y * TILEY + dy;
1023 if (!IN_SCR_FIELD(x,y))
1025 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1026 printf("DrawGraphicShifted(): This should never happen!\n");
1031 if (mask_mode == USE_MASKING)
1033 if (tile_clipmask[tile] != None)
1035 SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
1036 SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
1037 BlitBitmapMasked(src_bitmap, drawto_field,
1038 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1044 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1048 SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
1049 BlitBitmapMasked(src_bitmap, drawto_field,
1050 src_x, src_y, width, height, dest_x, dest_y);
1054 BlitBitmap(src_bitmap, drawto_field,
1055 src_x, src_y, width, height, dest_x, dest_y);
1060 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1063 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1066 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1067 int cut_mode, int mask_mode)
1069 int ux = LEVELX(x), uy = LEVELY(y);
1070 int graphic = el2gfx(element);
1071 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1072 int phase4 = phase8 / 2;
1073 int phase2 = phase8 / 4;
1074 int dir = MovDir[ux][uy];
1076 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1078 graphic += 4 * !phase2;
1082 else if (dir == MV_LEFT)
1084 else if (dir == MV_DOWN)
1087 else if (element == EL_SP_SNIKSNAK)
1090 graphic = GFX_SP_SNIKSNAK_LEFT;
1091 else if (dir == MV_RIGHT)
1092 graphic = GFX_SP_SNIKSNAK_RIGHT;
1093 else if (dir == MV_UP)
1094 graphic = GFX_SP_SNIKSNAK_UP;
1096 graphic = GFX_SP_SNIKSNAK_DOWN;
1098 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1100 else if (element == EL_SP_ELECTRON)
1102 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1104 else if (element == EL_MOLE || element == EL_PINGUIN ||
1105 element == EL_SCHWEIN || element == EL_DRACHE)
1108 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1109 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1110 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1111 else if (dir == MV_RIGHT)
1112 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1113 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1114 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1115 else if (dir == MV_UP)
1116 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1117 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1118 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1120 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1121 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1122 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1126 else if (element == EL_SONDE)
1128 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1130 else if (element == EL_SALZSAEURE)
1132 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1134 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1138 else if (element == EL_BALLOON)
1142 else if ((element == EL_FELSBROCKEN ||
1143 element == EL_SP_ZONK ||
1144 element == EL_BD_ROCK ||
1145 element == EL_SP_INFOTRON ||
1149 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1151 if (element == EL_FELSBROCKEN ||
1152 element == EL_SP_ZONK ||
1153 element == EL_BD_ROCK)
1156 graphic += (4 - phase4) % 4;
1157 else if (dir == MV_RIGHT)
1160 graphic += phase2 * 2;
1162 else if (element != EL_SP_INFOTRON)
1166 else if (element == EL_MAGIC_WALL_EMPTY ||
1167 element == EL_MAGIC_WALL_EMPTYING ||
1168 element == EL_MAGIC_WALL_BD_EMPTY ||
1169 element == EL_MAGIC_WALL_BD_EMPTYING ||
1170 element == EL_MAGIC_WALL_FULL ||
1171 element == EL_MAGIC_WALL_BD_FULL)
1173 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1175 else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
1177 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1178 graphic += (x + 2 * y + 4) % 4;
1180 else if (element == EL_MAUER_LEBT)
1182 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1184 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1185 links_massiv = TRUE;
1186 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1187 rechts_massiv = TRUE;
1189 if (links_massiv && rechts_massiv)
1190 graphic = GFX_MAUERWERK;
1191 else if (links_massiv)
1192 graphic = GFX_MAUER_R;
1193 else if (rechts_massiv)
1194 graphic = GFX_MAUER_L;
1196 else if ((element == EL_INVISIBLE_STEEL ||
1197 element == EL_UNSICHTBAR ||
1198 element == EL_SAND_INVISIBLE) && game.light_time_left)
1200 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1201 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1202 GFX_SAND_INVISIBLE_ON);
1206 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1207 else if (mask_mode == USE_MASKING)
1208 DrawGraphicThruMask(x, y, graphic);
1210 DrawGraphic(x, y, graphic);
1213 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1214 int cut_mode, int mask_mode)
1216 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1217 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1218 cut_mode, mask_mode);
1221 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1224 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1227 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1230 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1233 void DrawScreenElementThruMask(int x, int y, int element)
1235 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1238 void DrawLevelElementThruMask(int x, int y, int element)
1240 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1243 void DrawLevelFieldThruMask(int x, int y)
1245 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1248 void ErdreichAnbroeckeln(int x, int y)
1250 int i, width, height, cx,cy;
1251 int ux = LEVELX(x), uy = LEVELY(y);
1252 int element, graphic;
1254 static int xy[4][2] =
1262 if (!IN_LEV_FIELD(ux, uy))
1265 element = Feld[ux][uy];
1267 if (element == EL_ERDREICH ||
1268 element == EL_LANDMINE ||
1269 element == EL_TRAP_INACTIVE ||
1270 element == EL_TRAP_ACTIVE)
1272 if (!IN_SCR_FIELD(x, y))
1275 graphic = GFX_ERDENRAND;
1281 uxx = ux + xy[i][0];
1282 uyy = uy + xy[i][1];
1283 if (!IN_LEV_FIELD(uxx, uyy))
1286 element = Feld[uxx][uyy];
1288 if (element == EL_ERDREICH ||
1289 element == EL_LANDMINE ||
1290 element == EL_TRAP_INACTIVE ||
1291 element == EL_TRAP_ACTIVE)
1294 if (i == 1 || i == 2)
1298 cx = (i == 2 ? TILEX - snip : 0);
1306 cy = (i == 3 ? TILEY - snip : 0);
1309 BlitBitmap(pix[PIX_BACK], drawto_field,
1310 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1311 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1312 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1315 MarkTileDirty(x, y);
1319 graphic = GFX_ERDENRAND;
1323 int xx, yy, uxx, uyy;
1327 uxx = ux + xy[i][0];
1328 uyy = uy + xy[i][1];
1330 if (!IN_LEV_FIELD(uxx, uyy) ||
1331 (Feld[uxx][uyy] != EL_ERDREICH &&
1332 Feld[uxx][uyy] != EL_LANDMINE &&
1333 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1334 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1335 !IN_SCR_FIELD(xx, yy))
1338 if (i == 1 || i == 2)
1342 cx = (i == 1 ? TILEX - snip : 0);
1350 cy = (i==0 ? TILEY-snip : 0);
1353 BlitBitmap(pix[PIX_BACK], drawto_field,
1354 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1355 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1356 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1358 MarkTileDirty(xx, yy);
1363 void DrawScreenElement(int x, int y, int element)
1365 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1366 ErdreichAnbroeckeln(x, y);
1369 void DrawLevelElement(int x, int y, int element)
1371 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1372 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1375 void DrawScreenField(int x, int y)
1377 int ux = LEVELX(x), uy = LEVELY(y);
1378 int element, content;
1380 if (!IN_LEV_FIELD(ux, uy))
1382 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1383 element = EL_LEERRAUM;
1385 element = BorderElement;
1387 DrawScreenElement(x, y, element);
1391 element = Feld[ux][uy];
1392 content = Store[ux][uy];
1394 if (IS_MOVING(ux, uy))
1396 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1397 boolean cut_mode = NO_CUTTING;
1399 if (element == EL_QUICKSAND_EMPTYING ||
1400 element == EL_MAGIC_WALL_EMPTYING ||
1401 element == EL_MAGIC_WALL_BD_EMPTYING ||
1402 element == EL_AMOEBA_DRIPPING)
1403 cut_mode = CUT_ABOVE;
1404 else if (element == EL_QUICKSAND_FILLING ||
1405 element == EL_MAGIC_WALL_FILLING ||
1406 element == EL_MAGIC_WALL_BD_FILLING)
1407 cut_mode = CUT_BELOW;
1409 if (cut_mode == CUT_ABOVE)
1410 DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
1412 DrawScreenElement(x, y, EL_LEERRAUM);
1415 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1416 else if (cut_mode == NO_CUTTING)
1417 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1419 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
1421 if (content == EL_SALZSAEURE)
1422 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1424 else if (IS_BLOCKED(ux, uy))
1429 boolean cut_mode = NO_CUTTING;
1430 int element_old, content_old;
1432 Blocked2Moving(ux, uy, &oldx, &oldy);
1435 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1436 MovDir[oldx][oldy] == MV_RIGHT);
1438 element_old = Feld[oldx][oldy];
1439 content_old = Store[oldx][oldy];
1441 if (element_old == EL_QUICKSAND_EMPTYING ||
1442 element_old == EL_MAGIC_WALL_EMPTYING ||
1443 element_old == EL_MAGIC_WALL_BD_EMPTYING ||
1444 element_old == EL_AMOEBA_DRIPPING)
1445 cut_mode = CUT_ABOVE;
1447 DrawScreenElement(x, y, EL_LEERRAUM);
1450 DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
1452 else if (cut_mode == NO_CUTTING)
1453 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
1456 DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
1459 else if (IS_DRAWABLE(element))
1460 DrawScreenElement(x, y, element);
1462 DrawScreenElement(x, y, EL_LEERRAUM);
1465 void DrawLevelField(int x, int y)
1467 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1468 DrawScreenField(SCREENX(x), SCREENY(y));
1469 else if (IS_MOVING(x, y))
1473 Moving2Blocked(x, y, &newx, &newy);
1474 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1475 DrawScreenField(SCREENX(newx), SCREENY(newy));
1477 else if (IS_BLOCKED(x, y))
1481 Blocked2Moving(x, y, &oldx, &oldy);
1482 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1483 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1487 void DrawMiniElement(int x, int y, int element)
1493 DrawMiniGraphic(x, y, -1);
1497 graphic = el2gfx(element);
1498 DrawMiniGraphic(x, y, graphic);
1501 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1503 int x = sx + scroll_x, y = sy + scroll_y;
1505 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1506 DrawMiniElement(sx, sy, EL_LEERRAUM);
1507 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1508 DrawMiniElement(sx, sy, Feld[x][y]);
1511 int steel_type, steel_position;
1514 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1515 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1516 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1517 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1518 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1519 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1522 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1523 steel_position = (x == -1 && y == -1 ? 0 :
1524 x == lev_fieldx && y == -1 ? 1 :
1525 x == -1 && y == lev_fieldy ? 2 :
1526 x == lev_fieldx && y == lev_fieldy ? 3 :
1527 x == -1 || x == lev_fieldx ? 4 :
1528 y == -1 || y == lev_fieldy ? 5 : -1);
1530 if (steel_position != -1)
1531 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1535 void DrawMicroElement(int xpos, int ypos, int element)
1539 if (element == EL_LEERRAUM)
1542 graphic = el2gfx(element);
1544 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1546 graphic -= GFX_START_ROCKSSP;
1547 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1548 BlitBitmap(pix[PIX_SP], drawto,
1549 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1550 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1551 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1553 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1555 graphic -= GFX_START_ROCKSDC;
1556 BlitBitmap(pix[PIX_DC], drawto,
1557 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1558 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1559 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1561 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1563 graphic -= GFX_START_ROCKSMORE;
1564 BlitBitmap(pix[PIX_MORE], drawto,
1565 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1566 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1567 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1570 BlitBitmap(pix[PIX_BACK], drawto,
1571 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1572 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1573 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1582 for(x=BX1; x<=BX2; x++)
1583 for(y=BY1; y<=BY2; y++)
1584 DrawScreenField(x, y);
1586 redraw_mask |= REDRAW_FIELD;
1589 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1593 for(x=0; x<size_x; x++)
1594 for(y=0; y<size_y; y++)
1595 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1597 redraw_mask |= REDRAW_FIELD;
1600 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1604 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1606 if (lev_fieldx < STD_LEV_FIELDX)
1607 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1608 if (lev_fieldy < STD_LEV_FIELDY)
1609 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1611 xpos += MICRO_TILEX;
1612 ypos += MICRO_TILEY;
1614 for(x=-1; x<=STD_LEV_FIELDX; x++)
1616 for(y=-1; y<=STD_LEV_FIELDY; y++)
1618 int lx = from_x + x, ly = from_y + y;
1620 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1621 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1623 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1624 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1629 redraw_mask |= REDRAW_MICROLEVEL;
1632 #define MICROLABEL_EMPTY 0
1633 #define MICROLABEL_LEVEL_NAME 1
1634 #define MICROLABEL_CREATED_BY 2
1635 #define MICROLABEL_LEVEL_AUTHOR 3
1636 #define MICROLABEL_IMPORTED_FROM 4
1637 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1639 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1641 static void DrawMicroLevelLabelExt(int mode)
1643 char label_text[MAX_MICROLABEL_SIZE + 1];
1645 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1647 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1648 mode == MICROLABEL_CREATED_BY ? "created by" :
1649 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1650 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1651 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1652 leveldir_current->imported_from : ""),
1653 MAX_MICROLABEL_SIZE);
1654 label_text[MAX_MICROLABEL_SIZE] = '\0';
1656 if (strlen(label_text) > 0)
1658 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1659 int lypos = MICROLABEL_YPOS;
1661 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1664 redraw_mask |= REDRAW_MICROLEVEL;
1667 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1669 static unsigned long scroll_delay = 0;
1670 static unsigned long label_delay = 0;
1671 static int from_x, from_y, scroll_direction;
1672 static int label_state, label_counter;
1676 from_x = from_y = 0;
1677 scroll_direction = MV_RIGHT;
1681 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1682 DrawMicroLevelLabelExt(label_state);
1684 /* initialize delay counters */
1685 DelayReached(&scroll_delay, 0);
1686 DelayReached(&label_delay, 0);
1691 /* scroll micro level, if needed */
1692 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1693 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1695 switch (scroll_direction)
1701 scroll_direction = MV_UP;
1705 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1708 scroll_direction = MV_DOWN;
1715 scroll_direction = MV_RIGHT;
1719 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1722 scroll_direction = MV_LEFT;
1729 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1732 /* redraw micro level label, if needed */
1733 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1734 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1735 strcmp(level.author, leveldir_current->name) != 0 &&
1736 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1738 int max_label_counter = 23;
1740 if (leveldir_current->imported_from != NULL)
1741 max_label_counter += 14;
1743 label_counter = (label_counter + 1) % max_label_counter;
1744 label_state = (label_counter >= 0 && label_counter <= 7 ?
1745 MICROLABEL_LEVEL_NAME :
1746 label_counter >= 9 && label_counter <= 12 ?
1747 MICROLABEL_CREATED_BY :
1748 label_counter >= 14 && label_counter <= 21 ?
1749 MICROLABEL_LEVEL_AUTHOR :
1750 label_counter >= 23 && label_counter <= 26 ?
1751 MICROLABEL_IMPORTED_FROM :
1752 label_counter >= 28 && label_counter <= 35 ?
1753 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1754 DrawMicroLevelLabelExt(label_state);
1758 int REQ_in_range(int x, int y)
1760 if (y > DY+249 && y < DY+278)
1762 if (x > DX+1 && x < DX+48)
1764 else if (x > DX+51 && x < DX+98)
1770 #define MAX_REQUEST_LINES 13
1771 #define MAX_REQUEST_LINE_LEN 7
1773 boolean Request(char *text, unsigned int req_state)
1775 int mx, my, ty, result = -1;
1776 unsigned int old_door_state;
1778 #if defined(PLATFORM_UNIX)
1779 /* pause network game while waiting for request to answer */
1780 if (options.network &&
1781 game_status == PLAYING &&
1782 req_state & REQUEST_WAIT_FOR)
1783 SendToServer_PausePlaying();
1786 old_door_state = GetDoorState();
1790 CloseDoor(DOOR_CLOSE_1);
1792 /* save old door content */
1793 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1794 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1795 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1797 /* clear door drawing field */
1798 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1800 /* write text for request */
1801 for(ty=0; ty < MAX_REQUEST_LINES; ty++)
1803 char text_line[MAX_REQUEST_LINE_LEN + 1];
1809 for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
1812 if (!tc || tc == ' ')
1823 strncpy(text_line, text, tl);
1826 DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
1827 text_line, FS_SMALL, FC_YELLOW);
1829 text += tl + (tc == ' ' ? 1 : 0);
1832 if (req_state & REQ_ASK)
1834 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1835 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1837 else if (req_state & REQ_CONFIRM)
1839 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1841 else if (req_state & REQ_PLAYER)
1843 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1844 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1845 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1846 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1849 /* copy request gadgets to door backbuffer */
1850 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1851 DX, DY, DXSIZE, DYSIZE,
1852 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1854 OpenDoor(DOOR_OPEN_1);
1860 if (!(req_state & REQUEST_WAIT_FOR))
1863 if (game_status != MAINMENU)
1866 button_status = MB_RELEASED;
1868 request_gadget_id = -1;
1880 case EVENT_BUTTONPRESS:
1881 case EVENT_BUTTONRELEASE:
1882 case EVENT_MOTIONNOTIFY:
1884 if (event.type == EVENT_MOTIONNOTIFY)
1886 if (!PointerInWindow(window))
1887 continue; /* window and pointer are on different screens */
1892 motion_status = TRUE;
1893 mx = ((MotionEvent *) &event)->x;
1894 my = ((MotionEvent *) &event)->y;
1898 motion_status = FALSE;
1899 mx = ((ButtonEvent *) &event)->x;
1900 my = ((ButtonEvent *) &event)->y;
1901 if (event.type == EVENT_BUTTONPRESS)
1902 button_status = ((ButtonEvent *) &event)->button;
1904 button_status = MB_RELEASED;
1907 /* this sets 'request_gadget_id' */
1908 HandleGadgets(mx, my, button_status);
1910 switch(request_gadget_id)
1912 case TOOL_CTRL_ID_YES:
1915 case TOOL_CTRL_ID_NO:
1918 case TOOL_CTRL_ID_CONFIRM:
1919 result = TRUE | FALSE;
1922 case TOOL_CTRL_ID_PLAYER_1:
1925 case TOOL_CTRL_ID_PLAYER_2:
1928 case TOOL_CTRL_ID_PLAYER_3:
1931 case TOOL_CTRL_ID_PLAYER_4:
1942 case EVENT_KEYPRESS:
1943 switch(GetEventKey((KeyEvent *)&event, TRUE))
1956 if (req_state & REQ_PLAYER)
1960 case EVENT_KEYRELEASE:
1961 ClearPlayerAction();
1965 HandleOtherEvents(&event);
1969 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1971 int joy = AnyJoystick();
1973 if (joy & JOY_BUTTON_1)
1975 else if (joy & JOY_BUTTON_2)
1981 /* don't eat all CPU time */
1985 if (game_status != MAINMENU)
1990 if (!(req_state & REQ_STAY_OPEN))
1992 CloseDoor(DOOR_CLOSE_1);
1994 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1996 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1997 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1998 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1999 OpenDoor(DOOR_OPEN_1);
2005 #if defined(PLATFORM_UNIX)
2006 /* continue network game after request */
2007 if (options.network &&
2008 game_status == PLAYING &&
2009 req_state & REQUEST_WAIT_FOR)
2010 SendToServer_ContinuePlaying();
2016 unsigned int OpenDoor(unsigned int door_state)
2018 unsigned int new_door_state;
2020 if (door_state & DOOR_COPY_BACK)
2022 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2023 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2024 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2025 door_state &= ~DOOR_COPY_BACK;
2028 new_door_state = MoveDoor(door_state);
2030 return(new_door_state);
2033 unsigned int CloseDoor(unsigned int door_state)
2035 unsigned int new_door_state;
2037 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2038 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2039 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2040 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2042 new_door_state = MoveDoor(door_state);
2044 return(new_door_state);
2047 unsigned int GetDoorState()
2049 return MoveDoor(DOOR_GET_STATE);
2052 unsigned int SetDoorState(unsigned int door_state)
2054 return MoveDoor(door_state | DOOR_SET_STATE);
2057 unsigned int MoveDoor(unsigned int door_state)
2059 static int door1 = DOOR_OPEN_1;
2060 static int door2 = DOOR_CLOSE_2;
2061 static unsigned long door_delay = 0;
2062 int x, start, stepsize = 2;
2063 unsigned long door_delay_value = stepsize * 5;
2065 if (door_state == DOOR_GET_STATE)
2066 return(door1 | door2);
2068 if (door_state & DOOR_SET_STATE)
2070 if (door_state & DOOR_ACTION_1)
2071 door1 = door_state & DOOR_ACTION_1;
2072 if (door_state & DOOR_ACTION_2)
2073 door2 = door_state & DOOR_ACTION_2;
2075 return(door1 | door2);
2078 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2079 door_state &= ~DOOR_OPEN_1;
2080 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2081 door_state &= ~DOOR_CLOSE_1;
2082 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2083 door_state &= ~DOOR_OPEN_2;
2084 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2085 door_state &= ~DOOR_CLOSE_2;
2087 if (setup.quick_doors)
2090 door_delay_value = 0;
2091 StopSound(SND_MENU_DOOR_OPENING);
2092 StopSound(SND_MENU_DOOR_CLOSING);
2095 if (door_state & DOOR_ACTION)
2097 if (!(door_state & DOOR_NO_DELAY))
2099 /* opening door sound has priority over simultaneously closing door */
2100 if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
2101 PlaySoundStereo(SND_MENU_DOOR_OPENING, SOUND_MAX_RIGHT);
2102 else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
2103 PlaySoundStereo(SND_MENU_DOOR_CLOSING, SOUND_MAX_RIGHT);
2106 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2108 for(x=start; x<=DXSIZE; x+=stepsize)
2110 Bitmap *bitmap = pix[PIX_DOOR];
2111 GC gc = bitmap->stored_clip_gc;
2113 WaitUntilDelayReached(&door_delay, door_delay_value);
2115 if (door_state & DOOR_ACTION_1)
2117 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2118 int j = (DXSIZE - i) / 3;
2120 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2121 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2122 DXSIZE,DYSIZE - i/2, DX, DY);
2124 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2126 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2127 BlitBitmapMasked(bitmap, drawto,
2128 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2129 DX + DXSIZE - i, DY + j);
2130 BlitBitmapMasked(bitmap, drawto,
2131 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2132 DX + DXSIZE - i, DY + 140 + j);
2133 SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2134 BlitBitmapMasked(bitmap, drawto,
2135 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2137 BlitBitmapMasked(bitmap, drawto,
2138 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2141 BlitBitmapMasked(bitmap, drawto,
2142 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2144 BlitBitmapMasked(bitmap, drawto,
2145 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2147 SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2148 BlitBitmapMasked(bitmap, drawto,
2149 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2150 DX + DXSIZE - i, DY + 77 + j);
2151 BlitBitmapMasked(bitmap, drawto,
2152 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2153 DX + DXSIZE - i, DY + 203 + j);
2155 redraw_mask |= REDRAW_DOOR_1;
2158 if (door_state & DOOR_ACTION_2)
2160 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2161 int j = (VXSIZE - i) / 3;
2163 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2164 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2165 VXSIZE, VYSIZE - i/2, VX, VY);
2167 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2169 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2170 BlitBitmapMasked(bitmap, drawto,
2171 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2172 VX + VXSIZE-i, VY+j);
2173 SetClipOrigin(bitmap, gc,
2174 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2175 BlitBitmapMasked(bitmap, drawto,
2176 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2179 BlitBitmapMasked(bitmap, drawto,
2180 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2181 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2182 SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2183 BlitBitmapMasked(bitmap, drawto,
2184 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2186 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2188 redraw_mask |= REDRAW_DOOR_2;
2193 if (game_status == MAINMENU)
2198 if (setup.quick_doors)
2200 StopSound(SND_MENU_DOOR_OPENING);
2201 StopSound(SND_MENU_DOOR_CLOSING);
2204 if (door_state & DOOR_ACTION_1)
2205 door1 = door_state & DOOR_ACTION_1;
2206 if (door_state & DOOR_ACTION_2)
2207 door2 = door_state & DOOR_ACTION_2;
2209 return (door1 | door2);
2212 void DrawSpecialEditorDoor()
2214 /* draw bigger toolbox window */
2215 BlitBitmap(pix[PIX_DOOR], drawto,
2216 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2218 redraw_mask |= REDRAW_ALL;
2221 void UndrawSpecialEditorDoor()
2223 /* draw normal tape recorder window */
2224 BlitBitmap(pix[PIX_BACK], drawto,
2225 562, 344, 108, 56, EX - 4, EY - 12);
2227 redraw_mask |= REDRAW_ALL;
2231 int ReadPixel(DrawBuffer *bitmap, int x, int y)
2233 XImage *pixel_image;
2234 unsigned long pixel_value;
2236 pixel_image = XGetImage(display, bitmap->drawable,
2237 x, y, 1, 1, AllPlanes, ZPixmap);
2238 pixel_value = XGetPixel(pixel_image, 0, 0);
2240 XDestroyImage(pixel_image);
2246 /* ---------- new tool button stuff ---------------------------------------- */
2248 /* graphic position values for tool buttons */
2249 #define TOOL_BUTTON_YES_XPOS 2
2250 #define TOOL_BUTTON_YES_YPOS 250
2251 #define TOOL_BUTTON_YES_GFX_YPOS 0
2252 #define TOOL_BUTTON_YES_XSIZE 46
2253 #define TOOL_BUTTON_YES_YSIZE 28
2254 #define TOOL_BUTTON_NO_XPOS 52
2255 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2256 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2257 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2258 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2259 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2260 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2261 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2262 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2263 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2264 #define TOOL_BUTTON_PLAYER_XSIZE 30
2265 #define TOOL_BUTTON_PLAYER_YSIZE 30
2266 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2267 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2268 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2269 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2270 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2271 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2272 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2273 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2274 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2275 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2276 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2277 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2278 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2279 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2280 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2281 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2282 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2283 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2284 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2285 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2294 } toolbutton_info[NUM_TOOL_BUTTONS] =
2297 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2298 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2299 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2304 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2305 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2306 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2311 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2312 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2313 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2314 TOOL_CTRL_ID_CONFIRM,
2318 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2319 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2320 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2321 TOOL_CTRL_ID_PLAYER_1,
2325 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2326 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2327 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2328 TOOL_CTRL_ID_PLAYER_2,
2332 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2333 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2334 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2335 TOOL_CTRL_ID_PLAYER_3,
2339 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2340 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2341 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2342 TOOL_CTRL_ID_PLAYER_4,
2347 void CreateToolButtons()
2351 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2353 Bitmap *gd_bitmap = pix[PIX_DOOR];
2354 Bitmap *deco_bitmap = None;
2355 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2356 struct GadgetInfo *gi;
2357 unsigned long event_mask;
2358 int gd_xoffset, gd_yoffset;
2359 int gd_x1, gd_x2, gd_y;
2362 event_mask = GD_EVENT_RELEASED;
2364 gd_xoffset = toolbutton_info[i].xpos;
2365 gd_yoffset = toolbutton_info[i].ypos;
2366 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2367 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2368 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2370 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2372 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2373 &deco_bitmap, &deco_x, &deco_y);
2374 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2375 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2378 gi = CreateGadget(GDI_CUSTOM_ID, id,
2379 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2380 GDI_X, DX + toolbutton_info[i].x,
2381 GDI_Y, DY + toolbutton_info[i].y,
2382 GDI_WIDTH, toolbutton_info[i].width,
2383 GDI_HEIGHT, toolbutton_info[i].height,
2384 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2385 GDI_STATE, GD_BUTTON_UNPRESSED,
2386 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2387 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2388 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2389 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2390 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2391 GDI_DECORATION_SHIFTING, 1, 1,
2392 GDI_EVENT_MASK, event_mask,
2393 GDI_CALLBACK_ACTION, HandleToolButtons,
2397 Error(ERR_EXIT, "cannot create gadget");
2399 tool_gadget[id] = gi;
2403 static void UnmapToolButtons()
2407 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2408 UnmapGadget(tool_gadget[i]);
2411 static void HandleToolButtons(struct GadgetInfo *gi)
2413 request_gadget_id = gi->custom_id;
2416 int get_next_element(int element)
2420 case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
2421 case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
2422 case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
2423 case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
2424 case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
2425 case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
2426 case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
2428 default: return element;
2432 int el2gfx_OLD(int element)
2436 case EL_LEERRAUM: return -1;
2437 case EL_ERDREICH: return GFX_ERDREICH;
2438 case EL_MAUERWERK: return GFX_MAUERWERK;
2439 case EL_FELSBODEN: return GFX_FELSBODEN;
2440 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2441 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2442 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2443 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2444 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2445 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2446 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2447 case EL_SPIELER1: return GFX_SPIELER1;
2448 case EL_SPIELER2: return GFX_SPIELER2;
2449 case EL_SPIELER3: return GFX_SPIELER3;
2450 case EL_SPIELER4: return GFX_SPIELER4;
2451 case EL_KAEFER: return GFX_KAEFER;
2452 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2453 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2454 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2455 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2456 case EL_FLIEGER: return GFX_FLIEGER;
2457 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2458 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2459 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2460 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2461 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2462 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2463 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2464 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2465 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2466 case EL_FIREFLY: return GFX_FIREFLY;
2467 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2468 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2469 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2470 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2471 case EL_MAMPFER: return GFX_MAMPFER;
2472 case EL_ROBOT: return GFX_ROBOT;
2473 case EL_BETON: return GFX_BETON;
2474 case EL_DIAMANT: return GFX_DIAMANT;
2475 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2476 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2477 case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
2478 case EL_TROPFEN: return GFX_TROPFEN;
2479 case EL_BOMBE: return GFX_BOMBE;
2480 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2481 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2482 case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
2483 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2484 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2485 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2486 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2487 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2488 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2489 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2490 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2491 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2492 case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
2493 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2494 case EL_LIFE: return GFX_LIFE;
2495 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2496 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2497 case EL_BADEWANNE: return GFX_BADEWANNE;
2498 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2499 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2500 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2501 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2502 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2503 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2504 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2505 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2506 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2507 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2508 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2509 case EL_PFORTE1: return GFX_PFORTE1;
2510 case EL_PFORTE2: return GFX_PFORTE2;
2511 case EL_PFORTE3: return GFX_PFORTE3;
2512 case EL_PFORTE4: return GFX_PFORTE4;
2513 case EL_PFORTE1X: return GFX_PFORTE1X;
2514 case EL_PFORTE2X: return GFX_PFORTE2X;
2515 case EL_PFORTE3X: return GFX_PFORTE3X;
2516 case EL_PFORTE4X: return GFX_PFORTE4X;
2517 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2518 case EL_PACMAN: return GFX_PACMAN;
2519 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2520 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2521 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2522 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2523 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2524 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2525 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2526 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2527 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2528 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2529 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2530 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2531 case EL_MAUER_X: return GFX_MAUER_X;
2532 case EL_MAUER_Y: return GFX_MAUER_Y;
2533 case EL_MAUER_XY: return GFX_MAUER_XY;
2534 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2535 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2536 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2537 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2538 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2539 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2540 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2541 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2542 case EL_MAMPFER2: return GFX_MAMPFER2;
2543 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2544 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2545 case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
2546 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2547 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2548 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2549 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2550 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2551 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2552 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2553 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2554 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2555 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2556 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2557 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2558 case EL_MOLE: return GFX_MOLE;
2559 case EL_PINGUIN: return GFX_PINGUIN;
2560 case EL_SCHWEIN: return GFX_SCHWEIN;
2561 case EL_DRACHE: return GFX_DRACHE;
2562 case EL_SONDE: return GFX_SONDE;
2563 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2564 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2565 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2566 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2567 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2568 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2569 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2570 case EL_SP_ZONK: return GFX_SP_ZONK;
2571 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2572 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2573 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2574 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2575 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2576 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2577 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2578 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2579 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2580 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2581 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2582 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2583 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2584 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2585 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2586 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2587 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2588 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2589 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2590 case EL_PEARL: return GFX_PEARL;
2591 case EL_CRYSTAL: return GFX_CRYSTAL;
2592 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2593 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2594 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2595 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2596 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2597 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2598 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2599 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2600 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2601 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2602 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2603 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2604 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2605 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2606 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2607 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2608 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2609 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2610 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2611 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2612 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2613 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2614 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2615 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2616 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2617 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2618 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2619 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2620 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2621 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2622 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2623 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2624 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2625 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2626 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2627 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2628 case EL_LANDMINE: return GFX_LANDMINE;
2629 case EL_ENVELOPE: return GFX_ENVELOPE;
2630 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2631 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2632 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2633 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2634 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2635 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2636 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2637 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2638 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2639 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2640 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2641 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2642 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2643 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2644 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2645 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2646 case EL_MOLE_UP: return GFX_MOLE_UP;
2647 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2648 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2649 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2650 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2651 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2652 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2653 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2654 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2655 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2656 case EL_BALLOON: return GFX_BALLOON;
2657 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2658 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2659 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2660 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2661 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2662 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2663 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2664 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2665 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2666 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2667 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2668 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2669 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2670 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2671 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2672 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2673 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2674 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2675 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2676 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2677 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2678 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2679 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2680 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2681 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2682 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2683 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2684 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2685 case EL_SPRING: return GFX_SPRING;
2686 case EL_SPRING_MOVING: return GFX_SPRING;
2687 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2688 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2689 case EL_BD_WALL: return GFX_BD_WALL;
2690 case EL_BD_ROCK: return GFX_BD_ROCK;
2691 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2692 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2696 if (IS_CHAR(element))
2697 return GFX_CHAR_START + (element - EL_CHAR_START);
2698 else if (element >= EL_SP_START && element <= EL_SP_END)
2700 int nr_element = element - EL_SP_START;
2701 int gfx_per_line = 8;
2703 (nr_element / gfx_per_line) * SP_PER_LINE +
2704 (nr_element % gfx_per_line);
2706 return GFX_START_ROCKSSP + nr_graphic;
2714 int el2gfx(int element)
2716 int graphic_OLD = el2gfx_OLD(element);
2717 int graphic_NEW = element_info[element].graphic;
2719 if (element >= MAX_ELEMENTS)
2721 Error(ERR_WARN, "el2gfx: element == %d >= MAX_ELEMENTS", element);
2724 if (graphic_NEW != graphic_OLD)
2726 Error(ERR_WARN, "el2gfx: graphic_NEW (%d) != graphic_OLD (%d)",
2727 graphic_NEW, graphic_OLD);