1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
17 #include <machine/joystick.h>
31 extern boolean wait_for_vsync;
34 /* tool button identifiers */
35 #define TOOL_CTRL_ID_YES 0
36 #define TOOL_CTRL_ID_NO 1
37 #define TOOL_CTRL_ID_CONFIRM 2
38 #define TOOL_CTRL_ID_PLAYER_1 3
39 #define TOOL_CTRL_ID_PLAYER_2 4
40 #define TOOL_CTRL_ID_PLAYER_3 5
41 #define TOOL_CTRL_ID_PLAYER_4 6
43 #define NUM_TOOL_BUTTONS 7
45 /* forward declaration for internal use */
46 static int getGraphicAnimationPhase(int, int, int);
47 static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
49 static void UnmapToolButtons();
50 static void HandleToolButtons(struct GadgetInfo *);
52 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
53 static int request_gadget_id = -1;
55 void SetDrawtoField(int mode)
57 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
68 drawto_field = fieldbuffer;
70 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
81 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
88 DrawBuffer buffer = (drawto_field == window ? backbuffer : drawto_field);
90 if (setup.direct_draw && game_status == PLAYING)
91 redraw_mask &= ~REDRAW_MAIN;
93 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
94 redraw_mask |= REDRAW_FIELD;
96 if (redraw_mask & REDRAW_FIELD)
97 redraw_mask &= ~REDRAW_TILES;
102 /* synchronize X11 graphics at this point; if we would synchronize the
103 display immediately after the buffer switching (after the XFlush),
104 this could mean that we have to wait for the graphics to complete,
105 although we could go on doing calculations for the next frame */
109 if (redraw_mask & REDRAW_ALL)
111 BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
115 if (redraw_mask & REDRAW_FIELD)
117 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
119 BlitBitmap(backbuffer, window,
120 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
124 int fx = FX, fy = FY;
126 if (setup.soft_scrolling)
128 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
129 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
132 if (setup.soft_scrolling ||
133 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
134 ABS(ScreenMovPos) == ScrollStepSize ||
135 redraw_tiles > REDRAWTILES_THRESHOLD)
137 BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
141 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
143 (setup.soft_scrolling ?
144 "setup.soft_scrolling" :
145 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
146 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
147 ABS(ScreenGfxPos) == ScrollStepSize ?
148 "ABS(ScreenGfxPos) == ScrollStepSize" :
149 "redraw_tiles > REDRAWTILES_THRESHOLD"));
154 redraw_mask &= ~REDRAW_MAIN;
157 if (redraw_mask & REDRAW_DOORS)
159 if (redraw_mask & REDRAW_DOOR_1)
160 BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
161 if (redraw_mask & REDRAW_DOOR_2)
163 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
164 BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
167 if (redraw_mask & REDRAW_VIDEO_1)
168 BlitBitmap(backbuffer, window,
169 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
170 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
171 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
172 if (redraw_mask & REDRAW_VIDEO_2)
173 BlitBitmap(backbuffer, window,
174 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
175 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
176 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
177 if (redraw_mask & REDRAW_VIDEO_3)
178 BlitBitmap(backbuffer, window,
179 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
180 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
181 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
184 if (redraw_mask & REDRAW_DOOR_3)
185 BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
186 redraw_mask &= ~REDRAW_DOORS;
189 if (redraw_mask & REDRAW_MICROLEVEL)
191 BlitBitmap(backbuffer, window,
192 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
193 MICROLEV_XPOS, MICROLEV_YPOS);
194 BlitBitmap(backbuffer, window,
195 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
196 SX, MICROLABEL_YPOS);
197 redraw_mask &= ~REDRAW_MICROLEVEL;
200 if (redraw_mask & REDRAW_TILES)
202 for(x=0; x<SCR_FIELDX; x++)
203 for(y=0; y<SCR_FIELDY; y++)
204 if (redraw[redraw_x1 + x][redraw_y1 + y])
205 BlitBitmap(buffer, window,
206 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
207 SX + x * TILEX, SY + y * TILEY);
212 for(x=0; x<MAX_BUF_XSIZE; x++)
213 for(y=0; y<MAX_BUF_YSIZE; y++)
222 long fading_delay = 300;
224 if (setup.fading && (redraw_mask & REDRAW_FIELD))
231 ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
234 for(i=0;i<2*FULL_SYSIZE;i++)
236 for(y=0;y<FULL_SYSIZE;y++)
238 BlitBitmap(backbuffer, window,
239 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
247 for(i=1;i<FULL_SYSIZE;i+=2)
248 BlitBitmap(backbuffer, window,
249 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
255 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
256 BlitBitmapMasked(backbuffer, window,
257 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
262 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
263 BlitBitmapMasked(backbuffer, window,
264 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
269 SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
270 BlitBitmapMasked(backbuffer, window,
271 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
276 SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
277 BlitBitmapMasked(backbuffer, window,
278 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
283 redraw_mask &= ~REDRAW_MAIN;
292 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
294 if (setup.soft_scrolling && game_status == PLAYING)
296 ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
297 SetDrawtoField(DRAW_BUFFERED);
300 SetDrawtoField(DRAW_BACKBUFFER);
302 if (setup.direct_draw && game_status == PLAYING)
304 ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
305 SetDrawtoField(DRAW_DIRECT);
308 redraw_mask |= REDRAW_FIELD;
311 int getFontWidth(int font_size, int font_type)
313 return (font_size == FS_BIG ? FONT1_XSIZE :
314 font_size == FS_MEDIUM ? FONT6_XSIZE :
315 font_type == FC_SPECIAL1 ? FONT3_XSIZE :
316 font_type == FC_SPECIAL2 ? FONT4_XSIZE :
317 font_type == FC_SPECIAL3 ? FONT5_XSIZE :
321 int getFontHeight(int font_size, int font_type)
323 return (font_size == FS_BIG ? FONT1_YSIZE :
324 font_size == FS_MEDIUM ? FONT6_YSIZE :
325 font_type == FC_SPECIAL1 ? FONT3_YSIZE :
326 font_type == FC_SPECIAL2 ? FONT4_YSIZE :
327 font_type == FC_SPECIAL3 ? FONT5_YSIZE :
331 void DrawInitText(char *text, int ypos, int color)
333 if (window && pix[PIX_SMALLFONT])
335 ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
336 DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
337 ypos, text, FS_SMALL, color);
342 void DrawTextFCentered(int y, int font_type, char *format, ...)
344 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
345 int font_width = getFontWidth(FS_SMALL, font_type);
348 va_start(ap, format);
349 vsprintf(buffer, format, ap);
352 DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
353 buffer, FS_SMALL, font_type);
356 void DrawTextF(int x, int y, int font_type, char *format, ...)
358 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
361 va_start(ap, format);
362 vsprintf(buffer, format, ap);
365 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
368 void DrawText(int x, int y, char *text, int font_size, int font_type)
370 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
373 redraw_mask |= REDRAW_FIELD;
375 redraw_mask |= REDRAW_DOOR_1;
378 void DrawTextExt(DrawBuffer d, GC gc, int x, int y,
379 char *text, int font_size, int font_type)
381 int font_width, font_height, font_start;
383 boolean print_inverse = FALSE;
385 if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
386 font_size = FS_SMALL;
387 if (font_type < FC_RED || font_type > FC_SPECIAL3)
390 font_width = getFontWidth(font_size, font_type);
391 font_height = getFontHeight(font_size, font_type);
393 font_bitmap = (font_size == FS_BIG ? PIX_BIGFONT :
394 font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
396 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
397 font_size == FS_MEDIUM ? FONT6_YSIZE :
399 FONT_LINES_PER_FONT);
401 if (font_type == FC_SPECIAL3)
402 font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
408 if (c == '~' && font_size == FS_SMALL)
410 print_inverse = TRUE;
414 if (c >= 'a' && c <= 'z')
416 else if (c == 'ä' || c == 'Ä')
418 else if (c == 'ö' || c == 'Ö')
420 else if (c == 'ü' || c == 'Ü')
423 if (c >= 32 && c <= 95)
425 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
426 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
427 int dest_x = x, dest_y = y;
431 BlitBitmap(pix[font_bitmap], d,
432 FONT_CHARS_PER_LINE * font_width,
433 3 * font_height + font_start,
434 font_width, font_height, x, y);
436 SetClipOrigin(clip_gc[font_bitmap], dest_x - src_x, dest_y - src_y);
437 BlitBitmapMasked(pix_masked[font_bitmap], d,
438 0, 0, font_width, font_height, dest_x, dest_y);
441 BlitBitmap(pix[font_bitmap], d,
442 src_x, src_y, font_width, font_height, dest_x, dest_y);
449 void DrawAllPlayers()
453 for(i=0; i<MAX_PLAYERS; i++)
454 if (stored_player[i].active)
455 DrawPlayer(&stored_player[i]);
458 void DrawPlayerField(int x, int y)
460 if (!IS_PLAYER(x, y))
463 DrawPlayer(PLAYERINFO(x, y));
466 void DrawPlayer(struct PlayerInfo *player)
468 int jx = player->jx, jy = player->jy;
469 int last_jx = player->last_jx, last_jy = player->last_jy;
470 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
471 int sx = SCREENX(jx), sy = SCREENY(jy);
472 int sxx = 0, syy = 0;
473 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
475 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
477 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
481 if (!IN_LEV_FIELD(jx,jy))
483 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
484 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
485 printf("DrawPlayerField(): This should never happen!\n");
490 if (element == EL_EXPLODING)
493 /* draw things in the field the player is leaving, if needed */
495 if (player_is_moving)
497 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
499 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
500 DrawLevelFieldThruMask(last_jx, last_jy);
502 else if (last_element == EL_DYNAMITE_ACTIVE)
503 DrawDynamite(last_jx, last_jy);
505 DrawLevelField(last_jx, last_jy);
507 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
511 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
512 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
514 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
517 DrawLevelField(next_jx, next_jy);
521 if (!IN_SCR_FIELD(sx, sy))
524 if (setup.direct_draw)
525 SetDrawtoField(DRAW_BUFFERED);
527 /* draw things behind the player, if needed */
530 DrawLevelElement(jx, jy, Store[jx][jy]);
531 else if (!IS_ACTIVE_BOMB(element))
532 DrawLevelField(jx, jy);
534 /* draw player himself */
536 if (game.emulation == EMU_SUPAPLEX)
538 static int last_dir = MV_LEFT;
539 int action = (player->programmed_action ? player->programmed_action :
541 boolean action_moving =
543 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
544 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
546 graphic = GFX_SP_MURPHY;
550 if (player->MovDir == MV_LEFT)
551 graphic = GFX_MURPHY_PUSH_LEFT;
552 else if (player->MovDir == MV_RIGHT)
553 graphic = GFX_MURPHY_PUSH_RIGHT;
554 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
555 graphic = GFX_MURPHY_PUSH_LEFT;
556 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
557 graphic = GFX_MURPHY_PUSH_RIGHT;
559 else if (player->snapped)
561 if (player->MovDir == MV_LEFT)
562 graphic = GFX_MURPHY_SNAP_LEFT;
563 else if (player->MovDir == MV_RIGHT)
564 graphic = GFX_MURPHY_SNAP_RIGHT;
565 else if (player->MovDir == MV_UP)
566 graphic = GFX_MURPHY_SNAP_UP;
567 else if (player->MovDir == MV_DOWN)
568 graphic = GFX_MURPHY_SNAP_DOWN;
570 else if (action_moving)
572 if (player->MovDir == MV_LEFT)
573 graphic = GFX_MURPHY_GO_LEFT;
574 else if (player->MovDir == MV_RIGHT)
575 graphic = GFX_MURPHY_GO_RIGHT;
576 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
577 graphic = GFX_MURPHY_GO_LEFT;
578 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
579 graphic = GFX_MURPHY_GO_RIGHT;
581 graphic = GFX_MURPHY_GO_LEFT;
583 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
586 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
587 last_dir = player->MovDir;
591 if (player->MovDir == MV_LEFT)
593 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
594 else if (player->MovDir == MV_RIGHT)
596 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
597 else if (player->MovDir == MV_UP)
598 graphic = GFX_SPIELER1_UP;
599 else /* MV_DOWN || MV_NO_MOVING */
600 graphic = GFX_SPIELER1_DOWN;
602 graphic += player->index_nr * 3 * HEROES_PER_LINE;
603 graphic += player->Frame;
608 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
609 sxx = player->GfxPos;
611 syy = player->GfxPos;
614 if (!setup.soft_scrolling && ScreenMovPos)
617 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
619 if (SHIELD_ON(player))
621 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
622 GFX2_SHIELD_PASSIVE);
624 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
625 3, 8, ANIM_OSCILLATE);
628 if (player->Pushing && player->GfxPos)
630 int px = SCREENX(next_jx), py = SCREENY(next_jy);
632 if (element == EL_SOKOBAN_FELD_LEER ||
633 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
634 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
638 int element = Feld[next_jx][next_jy];
639 int graphic = el2gfx(element);
641 if ((element == EL_FELSBROCKEN ||
642 element == EL_SP_ZONK ||
643 element == EL_BD_ROCK) && sxx)
645 int phase = (player->GfxPos / (TILEX / 4));
647 if (player->MovDir == MV_LEFT)
650 graphic += (phase + 4) % 4;
653 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
657 /* draw things in front of player (active dynamite or dynabombs) */
659 if (IS_ACTIVE_BOMB(element))
661 graphic = el2gfx(element);
663 if (element == EL_DYNAMITE_ACTIVE)
665 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
670 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
674 if (game.emulation == EMU_SUPAPLEX)
675 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
677 DrawGraphicThruMask(sx, sy, graphic + phase);
680 if (player_is_moving && last_element == EL_EXPLODING)
682 int phase = Frame[last_jx][last_jy];
686 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
687 GFX_EXPLOSION + ((phase - 1) / delay - 1));
690 /* draw elements that stay over the player */
691 /* handle the field the player is leaving ... */
692 if (player_is_moving && IS_OVER_PLAYER(last_element))
693 DrawLevelField(last_jx, last_jy);
694 /* ... and the field the player is entering */
695 if (IS_OVER_PLAYER(element))
696 DrawLevelField(jx, jy);
698 if (setup.direct_draw)
700 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
701 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
702 int x_size = TILEX * (1 + ABS(jx - last_jx));
703 int y_size = TILEY * (1 + ABS(jy - last_jy));
705 BlitBitmap(drawto_field, window,
706 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
707 SetDrawtoField(DRAW_DIRECT);
710 MarkTileDirty(sx,sy);
713 static int getGraphicAnimationPhase(int frames, int delay, int mode)
717 if (mode == ANIM_OSCILLATE)
719 int max_anim_frames = 2 * frames - 2;
720 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
721 phase = (phase < frames ? phase : max_anim_frames - phase);
724 phase = (FrameCounter % (delay * frames)) / delay;
726 if (mode == ANIM_REVERSE)
732 void DrawGraphicAnimationExt(int x, int y, int graphic,
733 int frames, int delay, int mode, int mask_mode)
735 int phase = getGraphicAnimationPhase(frames, delay, mode);
737 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
739 if (mask_mode == USE_MASKING)
740 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
742 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
746 void DrawGraphicAnimation(int x, int y, int graphic,
747 int frames, int delay, int mode)
749 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
752 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
753 int frames, int delay, int mode)
755 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
758 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
761 int frames, int delay,
764 int phase = getGraphicAnimationPhase(frames, delay, mode);
766 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
769 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
771 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
773 graphic -= GFX_START_ROCKSSCREEN;
774 *bitmap_nr = PIX_BACK;
775 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
776 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
778 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
780 graphic -= GFX_START_ROCKSHEROES;
781 *bitmap_nr = PIX_HEROES;
782 *x = (graphic % HEROES_PER_LINE) * TILEX;
783 *y = (graphic / HEROES_PER_LINE) * TILEY;
785 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
787 graphic -= GFX_START_ROCKSSP;
789 *x = (graphic % SP_PER_LINE) * TILEX;
790 *y = (graphic / SP_PER_LINE) * TILEY;
792 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
794 graphic -= GFX_START_ROCKSDC;
796 *x = (graphic % DC_PER_LINE) * TILEX;
797 *y = (graphic / DC_PER_LINE) * TILEY;
799 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
801 graphic -= GFX_START_ROCKSMORE;
802 *bitmap_nr = PIX_MORE;
803 *x = (graphic % MORE_PER_LINE) * TILEX;
804 *y = (graphic / MORE_PER_LINE) * TILEY;
806 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
808 graphic -= GFX_START_ROCKSFONT;
809 *bitmap_nr = PIX_BIGFONT;
810 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
811 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
812 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
822 void DrawGraphic(int x, int y, int graphic)
825 if (!IN_SCR_FIELD(x,y))
827 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
828 printf("DrawGraphic(): This should never happen!\n");
833 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
837 void DrawGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
842 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
843 BlitBitmap(pix[bitmap_nr], d, src_x, src_y, TILEX, TILEY, x, y);
846 void DrawGraphicThruMask(int x, int y, int graphic)
849 if (!IN_SCR_FIELD(x,y))
851 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
852 printf("DrawGraphicThruMask(): This should never happen!\n");
857 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
861 void DrawGraphicThruMaskExt(DrawBuffer d, int dest_x, int dest_y, int graphic)
869 if (graphic == GFX_LEERRAUM)
872 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
873 src_bitmap = pix_masked[bitmap_nr];
874 drawing_gc = clip_gc[bitmap_nr];
876 if (tile_clipmask[tile] != None)
878 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
879 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
880 BlitBitmapMasked(src_bitmap, d,
881 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
886 #ifndef USE_SDL_LIBRARY
887 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
891 SetClipOrigin(drawing_gc, dest_x-src_x, dest_y-src_y);
892 BlitBitmapMasked(src_bitmap, d,
893 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
897 void DrawMiniGraphic(int x, int y, int graphic)
899 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
900 MarkTileDirty(x/2, y/2);
903 void getMiniGraphicSource(int graphic, Bitmap *bitmap, int *x, int *y)
905 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
907 graphic -= GFX_START_ROCKSSCREEN;
908 *bitmap = pix[PIX_BACK];
909 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
910 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
912 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
914 graphic -= GFX_START_ROCKSSP;
915 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
916 *bitmap = pix[PIX_SP];
917 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
918 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
920 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
922 graphic -= GFX_START_ROCKSDC;
923 *bitmap = pix[PIX_DC];
924 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
925 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
927 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
929 graphic -= GFX_START_ROCKSMORE;
930 *bitmap = pix[PIX_MORE];
931 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
932 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
934 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
936 graphic -= GFX_START_ROCKSFONT;
937 *bitmap = pix[PIX_SMALLFONT];
938 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
939 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
940 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
944 *bitmap = pix[PIX_SP];
950 void DrawMiniGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
955 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
956 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
959 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
960 int cut_mode, int mask_mode)
962 int width = TILEX, height = TILEY;
964 int src_x, src_y, dest_x, dest_y;
971 DrawGraphic(x, y, graphic);
975 if (dx || dy) /* Verschiebung der Grafik? */
977 if (x < BX1) /* Element kommt von links ins Bild */
984 else if (x > BX2) /* Element kommt von rechts ins Bild */
990 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
996 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
998 else if (dx) /* allg. Bewegung in x-Richtung */
999 MarkTileDirty(x + SIGN(dx), y);
1001 if (y < BY1) /* Element kommt von oben ins Bild */
1003 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1011 else if (y > BY2) /* Element kommt von unten ins Bild */
1017 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1023 else if (dy > 0 && cut_mode == CUT_ABOVE)
1025 if (y == BY2) /* Element unterhalb des Bildes */
1031 MarkTileDirty(x, y + 1);
1032 } /* Element verläßt unten das Bild */
1033 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1035 else if (dy) /* allg. Bewegung in y-Richtung */
1036 MarkTileDirty(x, y + SIGN(dy));
1039 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1040 drawing_gc = clip_gc[bitmap_nr];
1045 dest_x = FX + x * TILEX + dx;
1046 dest_y = FY + y * TILEY + dy;
1049 if (!IN_SCR_FIELD(x,y))
1051 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1052 printf("DrawGraphicShifted(): This should never happen!\n");
1057 if (mask_mode == USE_MASKING)
1059 if (tile_clipmask[tile] != None)
1061 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
1062 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
1063 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1064 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1069 #ifndef USE_SDL_LIBRARY
1070 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1074 SetClipOrigin(drawing_gc, dest_x - src_x, dest_y - src_y);
1075 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1076 src_x, src_y, width, height, dest_x, dest_y);
1080 BlitBitmap(pix[bitmap_nr], drawto_field,
1081 src_x, src_y, width, height, dest_x, dest_y);
1086 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1089 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1092 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1093 int cut_mode, int mask_mode)
1095 int ux = LEVELX(x), uy = LEVELY(y);
1096 int graphic = el2gfx(element);
1097 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1098 int phase4 = phase8 / 2;
1099 int phase2 = phase8 / 4;
1100 int dir = MovDir[ux][uy];
1102 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1104 graphic += 4 * !phase2;
1108 else if (dir == MV_LEFT)
1110 else if (dir == MV_DOWN)
1113 else if (element == EL_SP_SNIKSNAK)
1116 graphic = GFX_SP_SNIKSNAK_LEFT;
1117 else if (dir == MV_RIGHT)
1118 graphic = GFX_SP_SNIKSNAK_RIGHT;
1119 else if (dir == MV_UP)
1120 graphic = GFX_SP_SNIKSNAK_UP;
1122 graphic = GFX_SP_SNIKSNAK_DOWN;
1124 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1126 else if (element == EL_SP_ELECTRON)
1128 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1130 else if (element == EL_MOLE || element == EL_PINGUIN ||
1131 element == EL_SCHWEIN || element == EL_DRACHE)
1134 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1135 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1136 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1137 else if (dir == MV_RIGHT)
1138 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1139 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1140 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1141 else if (dir == MV_UP)
1142 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1143 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1144 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1146 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1147 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1148 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1152 else if (element == EL_SONDE)
1154 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1156 else if (element == EL_SALZSAEURE)
1158 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1160 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1164 else if (element == EL_BALLOON)
1168 else if ((element == EL_FELSBROCKEN ||
1169 element == EL_SP_ZONK ||
1170 element == EL_BD_ROCK ||
1171 IS_GEM(element)) && !cut_mode)
1173 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1175 if (element == EL_FELSBROCKEN ||
1176 element == EL_SP_ZONK ||
1177 element == EL_BD_ROCK)
1180 graphic += (4 - phase4) % 4;
1181 else if (dir == MV_RIGHT)
1184 graphic += phase2 * 2;
1186 else if (element != EL_SP_INFOTRON)
1190 else if (element == EL_MAGIC_WALL_EMPTY ||
1191 element == EL_MAGIC_WALL_BD_EMPTY ||
1192 element == EL_MAGIC_WALL_FULL ||
1193 element == EL_MAGIC_WALL_BD_FULL)
1195 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1197 else if (IS_AMOEBOID(element))
1199 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1200 graphic += (x + 2 * y + 4) % 4;
1202 else if (element == EL_MAUER_LEBT)
1204 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1206 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1207 links_massiv = TRUE;
1208 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1209 rechts_massiv = TRUE;
1211 if (links_massiv && rechts_massiv)
1212 graphic = GFX_MAUERWERK;
1213 else if (links_massiv)
1214 graphic = GFX_MAUER_R;
1215 else if (rechts_massiv)
1216 graphic = GFX_MAUER_L;
1218 else if ((element == EL_INVISIBLE_STEEL ||
1219 element == EL_UNSICHTBAR ||
1220 element == EL_SAND_INVISIBLE) && game.light_time_left)
1222 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1223 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1224 GFX_SAND_INVISIBLE_ON);
1228 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1229 else if (mask_mode == USE_MASKING)
1230 DrawGraphicThruMask(x, y, graphic);
1232 DrawGraphic(x, y, graphic);
1235 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1236 int cut_mode, int mask_mode)
1238 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1239 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1240 cut_mode, mask_mode);
1243 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1246 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1249 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1252 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1255 void DrawScreenElementThruMask(int x, int y, int element)
1257 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1260 void DrawLevelElementThruMask(int x, int y, int element)
1262 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1265 void DrawLevelFieldThruMask(int x, int y)
1267 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1270 void ErdreichAnbroeckeln(int x, int y)
1272 int i, width, height, cx,cy;
1273 int ux = LEVELX(x), uy = LEVELY(y);
1274 int element, graphic;
1276 static int xy[4][2] =
1284 if (!IN_LEV_FIELD(ux, uy))
1287 element = Feld[ux][uy];
1289 if (element == EL_ERDREICH ||
1290 element == EL_LANDMINE ||
1291 element == EL_TRAP_INACTIVE ||
1292 element == EL_TRAP_ACTIVE)
1294 if (!IN_SCR_FIELD(x, y))
1297 graphic = GFX_ERDENRAND;
1303 uxx = ux + xy[i][0];
1304 uyy = uy + xy[i][1];
1305 if (!IN_LEV_FIELD(uxx, uyy))
1308 element = Feld[uxx][uyy];
1310 if (element == EL_ERDREICH ||
1311 element == EL_LANDMINE ||
1312 element == EL_TRAP_INACTIVE ||
1313 element == EL_TRAP_ACTIVE)
1316 if (i == 1 || i == 2)
1320 cx = (i == 2 ? TILEX - snip : 0);
1328 cy = (i == 3 ? TILEY - snip : 0);
1331 BlitBitmap(pix[PIX_BACK], drawto_field,
1332 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1333 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1334 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1337 MarkTileDirty(x, y);
1341 graphic = GFX_ERDENRAND;
1345 int xx, yy, uxx, uyy;
1349 uxx = ux + xy[i][0];
1350 uyy = uy + xy[i][1];
1352 if (!IN_LEV_FIELD(uxx, uyy) ||
1353 (Feld[uxx][uyy] != EL_ERDREICH &&
1354 Feld[uxx][uyy] != EL_LANDMINE &&
1355 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1356 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1357 !IN_SCR_FIELD(xx, yy))
1360 if (i == 1 || i == 2)
1364 cx = (i == 1 ? TILEX - snip : 0);
1372 cy = (i==0 ? TILEY-snip : 0);
1375 BlitBitmap(pix[PIX_BACK], drawto_field,
1376 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1377 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1378 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1380 MarkTileDirty(xx, yy);
1385 void DrawScreenElement(int x, int y, int element)
1387 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1388 ErdreichAnbroeckeln(x, y);
1391 void DrawLevelElement(int x, int y, int element)
1393 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1394 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1397 void DrawScreenField(int x, int y)
1399 int ux = LEVELX(x), uy = LEVELY(y);
1402 if (!IN_LEV_FIELD(ux, uy))
1404 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1405 element = EL_LEERRAUM;
1407 element = BorderElement;
1409 DrawScreenElement(x, y, element);
1413 element = Feld[ux][uy];
1415 if (IS_MOVING(ux, uy))
1417 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1418 boolean cut_mode = NO_CUTTING;
1420 if (Store[ux][uy] == EL_MORAST_LEER ||
1421 Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
1422 Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
1423 Store[ux][uy] == EL_AMOEBE_NASS)
1424 cut_mode = CUT_ABOVE;
1425 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1426 Store[ux][uy] == EL_MAGIC_WALL_FULL ||
1427 Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
1428 cut_mode = CUT_BELOW;
1430 if (cut_mode == CUT_ABOVE)
1431 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1433 DrawScreenElement(x, y, EL_LEERRAUM);
1436 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1438 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1440 if (Store[ux][uy] == EL_SALZSAEURE)
1441 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1443 else if (IS_BLOCKED(ux, uy))
1448 boolean cut_mode = NO_CUTTING;
1450 Blocked2Moving(ux, uy, &oldx, &oldy);
1453 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1454 MovDir[oldx][oldy] == MV_RIGHT);
1456 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1457 Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
1458 Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
1459 Store[oldx][oldy] == EL_AMOEBE_NASS)
1460 cut_mode = CUT_ABOVE;
1462 DrawScreenElement(x, y, EL_LEERRAUM);
1463 element = Feld[oldx][oldy];
1466 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1468 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1470 else if (IS_DRAWABLE(element))
1471 DrawScreenElement(x, y, element);
1473 DrawScreenElement(x, y, EL_LEERRAUM);
1476 void DrawLevelField(int x, int y)
1478 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1479 DrawScreenField(SCREENX(x), SCREENY(y));
1480 else if (IS_MOVING(x, y))
1484 Moving2Blocked(x, y, &newx, &newy);
1485 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1486 DrawScreenField(SCREENX(newx), SCREENY(newy));
1488 else if (IS_BLOCKED(x, y))
1492 Blocked2Moving(x, y, &oldx, &oldy);
1493 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1494 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1498 void DrawMiniElement(int x, int y, int element)
1504 DrawMiniGraphic(x, y, -1);
1508 graphic = el2gfx(element);
1509 DrawMiniGraphic(x, y, graphic);
1512 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1514 int x = sx + scroll_x, y = sy + scroll_y;
1516 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1517 DrawMiniElement(sx, sy, EL_LEERRAUM);
1518 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1519 DrawMiniElement(sx, sy, Feld[x][y]);
1522 int steel_type, steel_position;
1525 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1526 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1527 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1528 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1529 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1530 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1533 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1534 steel_position = (x == -1 && y == -1 ? 0 :
1535 x == lev_fieldx && y == -1 ? 1 :
1536 x == -1 && y == lev_fieldy ? 2 :
1537 x == lev_fieldx && y == lev_fieldy ? 3 :
1538 x == -1 || x == lev_fieldx ? 4 :
1539 y == -1 || y == lev_fieldy ? 5 : -1);
1541 if (steel_position != -1)
1542 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1546 void DrawMicroElement(int xpos, int ypos, int element)
1550 if (element == EL_LEERRAUM)
1553 graphic = el2gfx(element);
1555 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1557 graphic -= GFX_START_ROCKSSP;
1558 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1559 BlitBitmap(pix[PIX_SP], drawto,
1560 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1561 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1562 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1564 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1566 graphic -= GFX_START_ROCKSDC;
1567 BlitBitmap(pix[PIX_DC], drawto,
1568 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1569 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1570 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1572 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1574 graphic -= GFX_START_ROCKSMORE;
1575 BlitBitmap(pix[PIX_MORE], drawto,
1576 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1577 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1578 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1581 BlitBitmap(pix[PIX_BACK], drawto,
1582 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1583 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1584 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1593 for(x=BX1; x<=BX2; x++)
1594 for(y=BY1; y<=BY2; y++)
1595 DrawScreenField(x, y);
1597 redraw_mask |= REDRAW_FIELD;
1600 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1604 for(x=0; x<size_x; x++)
1605 for(y=0; y<size_y; y++)
1606 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1608 redraw_mask |= REDRAW_FIELD;
1611 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1615 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1617 if (lev_fieldx < STD_LEV_FIELDX)
1618 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1619 if (lev_fieldy < STD_LEV_FIELDY)
1620 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1622 xpos += MICRO_TILEX;
1623 ypos += MICRO_TILEY;
1625 for(x=-1; x<=STD_LEV_FIELDX; x++)
1627 for(y=-1; y<=STD_LEV_FIELDY; y++)
1629 int lx = from_x + x, ly = from_y + y;
1631 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1632 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1634 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1635 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1640 redraw_mask |= REDRAW_MICROLEVEL;
1643 #define MICROLABEL_EMPTY 0
1644 #define MICROLABEL_LEVEL_NAME 1
1645 #define MICROLABEL_CREATED_BY 2
1646 #define MICROLABEL_LEVEL_AUTHOR 3
1647 #define MICROLABEL_IMPORTED_FROM 4
1648 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1650 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1652 static void DrawMicroLevelLabelExt(int mode)
1654 char label_text[MAX_MICROLABEL_SIZE + 1];
1656 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1658 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1659 mode == MICROLABEL_CREATED_BY ? "created by" :
1660 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1661 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1662 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1663 leveldir_current->imported_from : ""),
1664 MAX_MICROLABEL_SIZE);
1665 label_text[MAX_MICROLABEL_SIZE] = '\0';
1667 if (strlen(label_text) > 0)
1669 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1670 int lypos = MICROLABEL_YPOS;
1672 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1675 redraw_mask |= REDRAW_MICROLEVEL;
1678 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1680 static unsigned long scroll_delay = 0;
1681 static unsigned long label_delay = 0;
1682 static int from_x, from_y, scroll_direction;
1683 static int label_state, label_counter;
1687 from_x = from_y = 0;
1688 scroll_direction = MV_RIGHT;
1692 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1693 DrawMicroLevelLabelExt(label_state);
1695 /* initialize delay counters */
1696 DelayReached(&scroll_delay, 0);
1697 DelayReached(&label_delay, 0);
1702 /* scroll micro level, if needed */
1703 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1704 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1706 switch (scroll_direction)
1712 scroll_direction = MV_UP;
1716 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1719 scroll_direction = MV_DOWN;
1726 scroll_direction = MV_RIGHT;
1730 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1733 scroll_direction = MV_LEFT;
1740 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1743 /* redraw micro level label, if needed */
1744 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1745 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1746 strcmp(level.author, leveldir_current->name) != 0 &&
1747 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1749 int max_label_counter = 23;
1751 if (leveldir_current->imported_from != NULL)
1752 max_label_counter += 14;
1754 label_counter = (label_counter + 1) % max_label_counter;
1755 label_state = (label_counter >= 0 && label_counter <= 7 ?
1756 MICROLABEL_LEVEL_NAME :
1757 label_counter >= 9 && label_counter <= 12 ?
1758 MICROLABEL_CREATED_BY :
1759 label_counter >= 14 && label_counter <= 21 ?
1760 MICROLABEL_LEVEL_AUTHOR :
1761 label_counter >= 23 && label_counter <= 26 ?
1762 MICROLABEL_IMPORTED_FROM :
1763 label_counter >= 28 && label_counter <= 35 ?
1764 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1765 DrawMicroLevelLabelExt(label_state);
1769 int REQ_in_range(int x, int y)
1771 if (y > DY+249 && y < DY+278)
1773 if (x > DX+1 && x < DX+48)
1775 else if (x > DX+51 && x < DX+98)
1781 boolean Request(char *text, unsigned int req_state)
1783 int mx, my, ty, result = -1;
1784 unsigned int old_door_state;
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<13; ty++)
1817 for(tl=0,tx=0; tx<7; tl++,tx++)
1820 if (!tc || tc == 32)
1831 DrawTextExt(drawto, gc,
1832 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1833 txt, FS_SMALL, FC_YELLOW);
1834 text += tl + (tc == 32 ? 1 : 0);
1837 if (req_state & REQ_ASK)
1839 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1840 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1842 else if (req_state & REQ_CONFIRM)
1844 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1846 else if (req_state & REQ_PLAYER)
1848 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1849 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1850 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1851 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1854 /* copy request gadgets to door backbuffer */
1855 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1856 DX, DY, DXSIZE, DYSIZE,
1857 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1859 OpenDoor(DOOR_OPEN_1);
1865 if (!(req_state & REQUEST_WAIT_FOR))
1868 if (game_status != MAINMENU)
1871 button_status = MB_RELEASED;
1873 request_gadget_id = -1;
1885 case EVENT_BUTTONPRESS:
1886 case EVENT_BUTTONRELEASE:
1887 case EVENT_MOTIONNOTIFY:
1889 if (event.type == EVENT_MOTIONNOTIFY)
1893 if (!QueryPointer(window, &win_x, &win_y))
1894 continue; /* window and pointer are on different screens */
1899 motion_status = TRUE;
1900 mx = ((MotionEvent *) &event)->x;
1901 my = ((MotionEvent *) &event)->y;
1905 motion_status = FALSE;
1906 mx = ((ButtonEvent *) &event)->x;
1907 my = ((ButtonEvent *) &event)->y;
1908 if (event.type == EVENT_BUTTONPRESS)
1909 button_status = ((ButtonEvent *) &event)->button;
1911 button_status = MB_RELEASED;
1914 /* this sets 'request_gadget_id' */
1915 HandleGadgets(mx, my, button_status);
1917 switch(request_gadget_id)
1919 case TOOL_CTRL_ID_YES:
1922 case TOOL_CTRL_ID_NO:
1925 case TOOL_CTRL_ID_CONFIRM:
1926 result = TRUE | FALSE;
1929 case TOOL_CTRL_ID_PLAYER_1:
1932 case TOOL_CTRL_ID_PLAYER_2:
1935 case TOOL_CTRL_ID_PLAYER_3:
1938 case TOOL_CTRL_ID_PLAYER_4:
1949 case EVENT_KEYPRESS:
1950 switch(GetEventKey((KeyEvent *)&event, TRUE))
1963 if (req_state & REQ_PLAYER)
1967 case EVENT_KEYRELEASE:
1968 key_joystick_mapping = 0;
1972 HandleOtherEvents(&event);
1976 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1978 int joy = AnyJoystick();
1980 if (joy & JOY_BUTTON_1)
1982 else if (joy & JOY_BUTTON_2)
1988 /* don't eat all CPU time */
1992 if (game_status != MAINMENU)
1997 if (!(req_state & REQ_STAY_OPEN))
1999 CloseDoor(DOOR_CLOSE_1);
2001 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2003 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2004 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2005 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2006 OpenDoor(DOOR_OPEN_1);
2013 /* continue network game after request */
2014 if (options.network &&
2015 game_status == PLAYING &&
2016 req_state & REQUEST_WAIT_FOR)
2017 SendToServer_ContinuePlaying();
2023 unsigned int OpenDoor(unsigned int door_state)
2025 unsigned int new_door_state;
2027 if (door_state & DOOR_COPY_BACK)
2029 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2030 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2031 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2032 door_state &= ~DOOR_COPY_BACK;
2035 new_door_state = MoveDoor(door_state);
2037 return(new_door_state);
2040 unsigned int CloseDoor(unsigned int door_state)
2042 unsigned int new_door_state;
2044 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2045 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2046 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2047 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2049 new_door_state = MoveDoor(door_state);
2051 return(new_door_state);
2054 unsigned int GetDoorState()
2056 return(MoveDoor(DOOR_GET_STATE));
2059 unsigned int MoveDoor(unsigned int door_state)
2061 static int door1 = DOOR_OPEN_1;
2062 static int door2 = DOOR_CLOSE_2;
2063 static unsigned long door_delay = 0;
2064 int x, start, stepsize = 2;
2065 unsigned long door_delay_value = stepsize * 5;
2067 if (door_state == DOOR_GET_STATE)
2068 return(door1 | door2);
2070 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2071 door_state &= ~DOOR_OPEN_1;
2072 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2073 door_state &= ~DOOR_CLOSE_1;
2074 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2075 door_state &= ~DOOR_OPEN_2;
2076 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2077 door_state &= ~DOOR_CLOSE_2;
2079 if (setup.quick_doors)
2082 door_delay_value = 0;
2083 StopSound(SND_OEFFNEN);
2086 if (door_state & DOOR_ACTION)
2088 if (!(door_state & DOOR_NO_DELAY))
2089 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2091 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2093 for(x=start; x<=DXSIZE; x+=stepsize)
2095 WaitUntilDelayReached(&door_delay, door_delay_value);
2097 if (door_state & DOOR_ACTION_1)
2099 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2100 int j = (DXSIZE - i) / 3;
2102 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2103 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2104 DXSIZE,DYSIZE - i/2, DX, DY);
2106 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2108 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2109 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2110 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2111 DX + DXSIZE - i, DY + j);
2112 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2113 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2114 DX + DXSIZE - i, DY + 140 + j);
2115 SetClipOrigin(clip_gc[PIX_DOOR],
2116 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2117 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2118 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2120 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2121 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2124 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2125 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2127 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2128 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2130 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2131 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2132 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2133 DX + DXSIZE - i, DY + 77 + j);
2134 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2135 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2136 DX + DXSIZE - i, DY + 203 + j);
2138 redraw_mask |= REDRAW_DOOR_1;
2141 if (door_state & DOOR_ACTION_2)
2143 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2144 int j = (VXSIZE - i) / 3;
2146 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2147 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2148 VXSIZE, VYSIZE - i/2, VX, VY);
2150 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2152 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2153 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2154 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2155 VX + VXSIZE-i, VY+j);
2156 SetClipOrigin(clip_gc[PIX_DOOR],
2157 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2158 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2159 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2162 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2163 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2164 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2165 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2166 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2167 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2169 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2171 redraw_mask |= REDRAW_DOOR_2;
2176 if (game_status == MAINMENU)
2181 if (setup.quick_doors)
2182 StopSound(SND_OEFFNEN);
2184 if (door_state & DOOR_ACTION_1)
2185 door1 = door_state & DOOR_ACTION_1;
2186 if (door_state & DOOR_ACTION_2)
2187 door2 = door_state & DOOR_ACTION_2;
2189 return (door1 | door2);
2192 void DrawSpecialEditorDoor()
2194 /* draw bigger toolbox window */
2195 BlitBitmap(pix[PIX_DOOR], drawto,
2196 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2198 redraw_mask |= REDRAW_ALL;
2201 void UndrawSpecialEditorDoor()
2203 /* draw normal tape recorder window */
2204 BlitBitmap(pix[PIX_BACK], drawto,
2205 562, 344, 108, 56, EX - 4, EY - 12);
2207 redraw_mask |= REDRAW_ALL;
2210 #ifndef USE_SDL_LIBRARY
2211 int ReadPixel(DrawBuffer d, int x, int y)
2213 XImage *pixel_image;
2214 unsigned long pixel_value;
2216 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
2217 pixel_value = XGetPixel(pixel_image, 0, 0);
2219 XDestroyImage(pixel_image);
2225 /* ---------- new tool button stuff ---------------------------------------- */
2227 /* graphic position values for tool buttons */
2228 #define TOOL_BUTTON_YES_XPOS 2
2229 #define TOOL_BUTTON_YES_YPOS 250
2230 #define TOOL_BUTTON_YES_GFX_YPOS 0
2231 #define TOOL_BUTTON_YES_XSIZE 46
2232 #define TOOL_BUTTON_YES_YSIZE 28
2233 #define TOOL_BUTTON_NO_XPOS 52
2234 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2235 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2236 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2237 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2238 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2239 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2240 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2241 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2242 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2243 #define TOOL_BUTTON_PLAYER_XSIZE 30
2244 #define TOOL_BUTTON_PLAYER_YSIZE 30
2245 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2246 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2247 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2248 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2249 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2250 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2251 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2252 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2253 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2254 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2255 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2256 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2257 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2258 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2259 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2260 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2261 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2262 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2263 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2264 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2273 } toolbutton_info[NUM_TOOL_BUTTONS] =
2276 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2277 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2278 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2283 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2284 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2285 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2290 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2291 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2292 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2293 TOOL_CTRL_ID_CONFIRM,
2297 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2298 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2299 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2300 TOOL_CTRL_ID_PLAYER_1,
2304 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2305 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2306 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2307 TOOL_CTRL_ID_PLAYER_2,
2311 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2312 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2313 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2314 TOOL_CTRL_ID_PLAYER_3,
2318 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2319 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2320 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2321 TOOL_CTRL_ID_PLAYER_4,
2326 static void DoNotDisplayInfoText(void *ptr)
2331 void CreateToolButtons()
2335 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2337 Bitmap gd_bitmap = pix[PIX_DOOR];
2338 Bitmap deco_bitmap = None;
2339 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2340 struct GadgetInfo *gi;
2341 unsigned long event_mask;
2342 int gd_xoffset, gd_yoffset;
2343 int gd_x1, gd_x2, gd_y;
2346 event_mask = GD_EVENT_RELEASED;
2348 gd_xoffset = toolbutton_info[i].xpos;
2349 gd_yoffset = toolbutton_info[i].ypos;
2350 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2351 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2352 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2354 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2356 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2357 &deco_bitmap, &deco_x, &deco_y);
2358 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2359 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2362 gi = CreateGadget(GDI_CUSTOM_ID, id,
2363 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2364 GDI_X, DX + toolbutton_info[i].x,
2365 GDI_Y, DY + toolbutton_info[i].y,
2366 GDI_WIDTH, toolbutton_info[i].width,
2367 GDI_HEIGHT, toolbutton_info[i].height,
2368 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2369 GDI_STATE, GD_BUTTON_UNPRESSED,
2370 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2371 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2372 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2373 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2374 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2375 GDI_DECORATION_SHIFTING, 1, 1,
2376 GDI_EVENT_MASK, event_mask,
2377 GDI_CALLBACK_ACTION, HandleToolButtons,
2378 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2382 Error(ERR_EXIT, "cannot create gadget");
2384 tool_gadget[id] = gi;
2388 static void UnmapToolButtons()
2392 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2393 UnmapGadget(tool_gadget[i]);
2396 static void HandleToolButtons(struct GadgetInfo *gi)
2398 request_gadget_id = gi->custom_id;
2401 int el2gfx(int element)
2405 case EL_LEERRAUM: return -1;
2406 case EL_ERDREICH: return GFX_ERDREICH;
2407 case EL_MAUERWERK: return GFX_MAUERWERK;
2408 case EL_FELSBODEN: return GFX_FELSBODEN;
2409 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2410 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2411 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2412 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2413 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2414 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2415 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2416 case EL_SPIELER1: return GFX_SPIELER1;
2417 case EL_SPIELER2: return GFX_SPIELER2;
2418 case EL_SPIELER3: return GFX_SPIELER3;
2419 case EL_SPIELER4: return GFX_SPIELER4;
2420 case EL_KAEFER: return GFX_KAEFER;
2421 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2422 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2423 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2424 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2425 case EL_FLIEGER: return GFX_FLIEGER;
2426 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2427 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2428 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2429 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2430 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2431 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2432 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2433 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2434 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2435 case EL_FIREFLY: return GFX_FIREFLY;
2436 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2437 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2438 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2439 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2440 case EL_MAMPFER: return GFX_MAMPFER;
2441 case EL_ROBOT: return GFX_ROBOT;
2442 case EL_BETON: return GFX_BETON;
2443 case EL_DIAMANT: return GFX_DIAMANT;
2444 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2445 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2446 case EL_TROPFEN: return GFX_TROPFEN;
2447 case EL_BOMBE: return GFX_BOMBE;
2448 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2449 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2450 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2451 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2452 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2453 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2454 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2455 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2456 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2457 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2458 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2459 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2460 case EL_LIFE: return GFX_LIFE;
2461 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2462 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2463 case EL_BADEWANNE: return GFX_BADEWANNE;
2464 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2465 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2466 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2467 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2468 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2469 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2470 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2471 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2472 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2473 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2474 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2475 case EL_PFORTE1: return GFX_PFORTE1;
2476 case EL_PFORTE2: return GFX_PFORTE2;
2477 case EL_PFORTE3: return GFX_PFORTE3;
2478 case EL_PFORTE4: return GFX_PFORTE4;
2479 case EL_PFORTE1X: return GFX_PFORTE1X;
2480 case EL_PFORTE2X: return GFX_PFORTE2X;
2481 case EL_PFORTE3X: return GFX_PFORTE3X;
2482 case EL_PFORTE4X: return GFX_PFORTE4X;
2483 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2484 case EL_PACMAN: return GFX_PACMAN;
2485 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2486 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2487 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2488 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2489 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2490 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2491 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2492 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2493 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2494 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2495 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2496 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2497 case EL_MAUER_X: return GFX_MAUER_X;
2498 case EL_MAUER_Y: return GFX_MAUER_Y;
2499 case EL_MAUER_XY: return GFX_MAUER_XY;
2500 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2501 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2502 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2503 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2504 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2505 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2506 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2507 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2508 case EL_MAMPFER2: return GFX_MAMPFER2;
2509 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2510 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2511 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2512 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2513 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2514 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2515 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2516 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2517 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2518 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2519 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2520 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2521 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2522 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2523 case EL_MOLE: return GFX_MOLE;
2524 case EL_PINGUIN: return GFX_PINGUIN;
2525 case EL_SCHWEIN: return GFX_SCHWEIN;
2526 case EL_DRACHE: return GFX_DRACHE;
2527 case EL_SONDE: return GFX_SONDE;
2528 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2529 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2530 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2531 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2532 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2533 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2534 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2535 case EL_SP_ZONK: return GFX_SP_ZONK;
2536 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2537 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2538 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2539 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2540 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2541 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2542 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2543 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2544 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2545 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2546 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2547 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2548 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2549 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2550 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2551 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2552 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2553 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2554 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2555 case EL_PEARL: return GFX_PEARL;
2556 case EL_CRYSTAL: return GFX_CRYSTAL;
2557 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2558 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2559 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2560 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2561 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2562 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2563 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2564 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2565 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2566 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2567 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2568 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2569 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2570 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2571 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2572 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2573 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2574 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2575 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2576 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2577 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2578 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2579 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2580 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2581 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2582 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2583 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2584 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2585 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2586 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2587 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2588 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2589 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2590 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2591 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2592 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2593 case EL_LANDMINE: return GFX_LANDMINE;
2594 case EL_ENVELOPE: return GFX_ENVELOPE;
2595 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2596 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2597 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2598 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2599 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2600 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2601 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2602 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2603 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2604 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2605 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2606 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2607 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2608 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2609 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2610 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2611 case EL_MOLE_UP: return GFX_MOLE_UP;
2612 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2613 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2614 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2615 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2616 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2617 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2618 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2619 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2620 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2621 case EL_BALLOON: return GFX_BALLOON;
2622 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2623 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2624 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2625 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2626 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2627 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2628 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2629 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2630 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2631 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2632 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2633 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2634 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2635 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2636 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2637 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2638 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2639 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2640 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2641 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2642 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2643 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2644 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2645 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2646 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2647 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2648 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2649 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2650 case EL_SPRING: return GFX_SPRING;
2651 case EL_SPRING_MOVING: return GFX_SPRING;
2652 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2653 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2654 case EL_BD_WALL: return GFX_BD_WALL;
2655 case EL_BD_ROCK: return GFX_BD_ROCK;
2656 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2657 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2661 if (IS_CHAR(element))
2662 return GFX_CHAR_START + (element - EL_CHAR_START);
2663 else if (element >= EL_SP_START && element <= EL_SP_END)
2665 int nr_element = element - EL_SP_START;
2666 int gfx_per_line = 8;
2668 (nr_element / gfx_per_line) * SP_PER_LINE +
2669 (nr_element % gfx_per_line);
2671 return GFX_START_ROCKSSP + nr_graphic;