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 #ifdef USE_SDL_LIBRARY
334 if (window && pix[PIX_SMALLFONT])
336 ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
337 DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
338 ypos, text, FS_SMALL, color);
342 if (display && window && pix[PIX_SMALLFONT])
344 ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
345 DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
346 ypos, text, FS_SMALL, color);
352 void DrawTextFCentered(int y, int font_type, char *format, ...)
354 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
355 int font_width = getFontWidth(FS_SMALL, font_type);
358 va_start(ap, format);
359 vsprintf(buffer, format, ap);
362 DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
363 buffer, FS_SMALL, font_type);
366 void DrawTextF(int x, int y, int font_type, char *format, ...)
368 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
371 va_start(ap, format);
372 vsprintf(buffer, format, ap);
375 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
378 void DrawText(int x, int y, char *text, int font_size, int font_type)
380 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
383 redraw_mask |= REDRAW_FIELD;
385 redraw_mask |= REDRAW_DOOR_1;
388 void DrawTextExt(DrawBuffer d, GC gc, int x, int y,
389 char *text, int font_size, int font_type)
391 int font_width, font_height, font_start;
393 boolean print_inverse = FALSE;
395 if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
396 font_size = FS_SMALL;
397 if (font_type < FC_RED || font_type > FC_SPECIAL3)
400 font_width = getFontWidth(font_size, font_type);
401 font_height = getFontHeight(font_size, font_type);
403 font_bitmap = (font_size == FS_BIG ? PIX_BIGFONT :
404 font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
406 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
407 font_size == FS_MEDIUM ? FONT6_YSIZE :
409 FONT_LINES_PER_FONT);
411 if (font_type == FC_SPECIAL3)
412 font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
418 if (c == '~' && font_size == FS_SMALL)
420 print_inverse = TRUE;
424 if (c >= 'a' && c <= 'z')
426 else if (c == 'ä' || c == 'Ä')
428 else if (c == 'ö' || c == 'Ö')
430 else if (c == 'ü' || c == 'Ü')
433 if (c >= 32 && c <= 95)
435 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
436 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
437 int dest_x = x, dest_y = y;
441 BlitBitmap(pix[font_bitmap], d,
442 FONT_CHARS_PER_LINE * font_width,
443 3 * font_height + font_start,
444 font_width, font_height, x, y);
446 SetClipOrigin(clip_gc[font_bitmap], dest_x - src_x, dest_y - src_y);
447 BlitBitmapMasked(pix_masked[font_bitmap], d,
448 0, 0, font_width, font_height, dest_x, dest_y);
451 BlitBitmap(pix[font_bitmap], d,
452 src_x, src_y, font_width, font_height, dest_x, dest_y);
459 void DrawAllPlayers()
463 for(i=0; i<MAX_PLAYERS; i++)
464 if (stored_player[i].active)
465 DrawPlayer(&stored_player[i]);
468 void DrawPlayerField(int x, int y)
470 if (!IS_PLAYER(x, y))
473 DrawPlayer(PLAYERINFO(x, y));
476 void DrawPlayer(struct PlayerInfo *player)
478 int jx = player->jx, jy = player->jy;
479 int last_jx = player->last_jx, last_jy = player->last_jy;
480 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
481 int sx = SCREENX(jx), sy = SCREENY(jy);
482 int sxx = 0, syy = 0;
483 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
485 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
487 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
491 if (!IN_LEV_FIELD(jx,jy))
493 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
494 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
495 printf("DrawPlayerField(): This should never happen!\n");
500 if (element == EL_EXPLODING)
503 /* draw things in the field the player is leaving, if needed */
505 if (player_is_moving)
507 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
509 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
510 DrawLevelFieldThruMask(last_jx, last_jy);
512 else if (last_element == EL_DYNAMITE_ACTIVE)
513 DrawDynamite(last_jx, last_jy);
515 DrawLevelField(last_jx, last_jy);
517 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
521 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
522 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
524 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
527 DrawLevelField(next_jx, next_jy);
531 if (!IN_SCR_FIELD(sx, sy))
534 if (setup.direct_draw)
535 SetDrawtoField(DRAW_BUFFERED);
537 /* draw things behind the player, if needed */
540 DrawLevelElement(jx, jy, Store[jx][jy]);
541 else if (!IS_ACTIVE_BOMB(element))
542 DrawLevelField(jx, jy);
544 /* draw player himself */
546 if (game.emulation == EMU_SUPAPLEX)
548 static int last_dir = MV_LEFT;
549 int action = (player->programmed_action ? player->programmed_action :
551 boolean action_moving =
553 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
554 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
556 graphic = GFX_SP_MURPHY;
560 if (player->MovDir == MV_LEFT)
561 graphic = GFX_MURPHY_PUSH_LEFT;
562 else if (player->MovDir == MV_RIGHT)
563 graphic = GFX_MURPHY_PUSH_RIGHT;
564 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
565 graphic = GFX_MURPHY_PUSH_LEFT;
566 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
567 graphic = GFX_MURPHY_PUSH_RIGHT;
569 else if (player->snapped)
571 if (player->MovDir == MV_LEFT)
572 graphic = GFX_MURPHY_SNAP_LEFT;
573 else if (player->MovDir == MV_RIGHT)
574 graphic = GFX_MURPHY_SNAP_RIGHT;
575 else if (player->MovDir == MV_UP)
576 graphic = GFX_MURPHY_SNAP_UP;
577 else if (player->MovDir == MV_DOWN)
578 graphic = GFX_MURPHY_SNAP_DOWN;
580 else if (action_moving)
582 if (player->MovDir == MV_LEFT)
583 graphic = GFX_MURPHY_GO_LEFT;
584 else if (player->MovDir == MV_RIGHT)
585 graphic = GFX_MURPHY_GO_RIGHT;
586 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
587 graphic = GFX_MURPHY_GO_LEFT;
588 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
589 graphic = GFX_MURPHY_GO_RIGHT;
591 graphic = GFX_MURPHY_GO_LEFT;
593 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
596 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
597 last_dir = player->MovDir;
601 if (player->MovDir == MV_LEFT)
603 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
604 else if (player->MovDir == MV_RIGHT)
606 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
607 else if (player->MovDir == MV_UP)
608 graphic = GFX_SPIELER1_UP;
609 else /* MV_DOWN || MV_NO_MOVING */
610 graphic = GFX_SPIELER1_DOWN;
612 graphic += player->index_nr * 3 * HEROES_PER_LINE;
613 graphic += player->Frame;
618 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
619 sxx = player->GfxPos;
621 syy = player->GfxPos;
624 if (!setup.soft_scrolling && ScreenMovPos)
627 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
629 if (SHIELD_ON(player))
631 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
632 GFX2_SHIELD_PASSIVE);
634 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
635 3, 8, ANIM_OSCILLATE);
638 if (player->Pushing && player->GfxPos)
640 int px = SCREENX(next_jx), py = SCREENY(next_jy);
642 if (element == EL_SOKOBAN_FELD_LEER ||
643 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
644 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
648 int element = Feld[next_jx][next_jy];
649 int graphic = el2gfx(element);
651 if ((element == EL_FELSBROCKEN ||
652 element == EL_SP_ZONK ||
653 element == EL_BD_ROCK) && sxx)
655 int phase = (player->GfxPos / (TILEX / 4));
657 if (player->MovDir == MV_LEFT)
660 graphic += (phase + 4) % 4;
663 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
667 /* draw things in front of player (active dynamite or dynabombs) */
669 if (IS_ACTIVE_BOMB(element))
671 graphic = el2gfx(element);
673 if (element == EL_DYNAMITE_ACTIVE)
675 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
680 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
684 if (game.emulation == EMU_SUPAPLEX)
685 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
687 DrawGraphicThruMask(sx, sy, graphic + phase);
690 if (player_is_moving && last_element == EL_EXPLODING)
692 int phase = Frame[last_jx][last_jy];
696 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
697 GFX_EXPLOSION + ((phase - 1) / delay - 1));
700 /* draw elements that stay over the player */
701 /* handle the field the player is leaving ... */
702 if (player_is_moving && IS_OVER_PLAYER(last_element))
703 DrawLevelField(last_jx, last_jy);
704 /* ... and the field the player is entering */
705 if (IS_OVER_PLAYER(element))
706 DrawLevelField(jx, jy);
708 if (setup.direct_draw)
710 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
711 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
712 int x_size = TILEX * (1 + ABS(jx - last_jx));
713 int y_size = TILEY * (1 + ABS(jy - last_jy));
715 BlitBitmap(drawto_field, window,
716 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
717 SetDrawtoField(DRAW_DIRECT);
720 MarkTileDirty(sx,sy);
723 static int getGraphicAnimationPhase(int frames, int delay, int mode)
727 if (mode == ANIM_OSCILLATE)
729 int max_anim_frames = 2 * frames - 2;
730 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
731 phase = (phase < frames ? phase : max_anim_frames - phase);
734 phase = (FrameCounter % (delay * frames)) / delay;
736 if (mode == ANIM_REVERSE)
742 void DrawGraphicAnimationExt(int x, int y, int graphic,
743 int frames, int delay, int mode, int mask_mode)
745 int phase = getGraphicAnimationPhase(frames, delay, mode);
747 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
749 if (mask_mode == USE_MASKING)
750 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
752 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
756 void DrawGraphicAnimation(int x, int y, int graphic,
757 int frames, int delay, int mode)
759 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
762 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
763 int frames, int delay, int mode)
765 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
768 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
771 int frames, int delay,
774 int phase = getGraphicAnimationPhase(frames, delay, mode);
776 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
779 void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
781 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
783 graphic -= GFX_START_ROCKSSCREEN;
784 *bitmap_nr = PIX_BACK;
785 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
786 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
788 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
790 graphic -= GFX_START_ROCKSHEROES;
791 *bitmap_nr = PIX_HEROES;
792 *x = (graphic % HEROES_PER_LINE) * TILEX;
793 *y = (graphic / HEROES_PER_LINE) * TILEY;
795 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
797 graphic -= GFX_START_ROCKSSP;
799 *x = (graphic % SP_PER_LINE) * TILEX;
800 *y = (graphic / SP_PER_LINE) * TILEY;
802 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
804 graphic -= GFX_START_ROCKSDC;
806 *x = (graphic % DC_PER_LINE) * TILEX;
807 *y = (graphic / DC_PER_LINE) * TILEY;
809 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
811 graphic -= GFX_START_ROCKSMORE;
812 *bitmap_nr = PIX_MORE;
813 *x = (graphic % MORE_PER_LINE) * TILEX;
814 *y = (graphic / MORE_PER_LINE) * TILEY;
816 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
818 graphic -= GFX_START_ROCKSFONT;
819 *bitmap_nr = PIX_BIGFONT;
820 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
821 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
822 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
832 void DrawGraphic(int x, int y, int graphic)
835 if (!IN_SCR_FIELD(x,y))
837 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
838 printf("DrawGraphic(): This should never happen!\n");
843 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
847 void DrawGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
852 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
853 BlitBitmap(pix[bitmap_nr], d, src_x, src_y, TILEX, TILEY, x, y);
856 void DrawGraphicThruMask(int x, int y, int graphic)
859 if (!IN_SCR_FIELD(x,y))
861 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
862 printf("DrawGraphicThruMask(): This should never happen!\n");
867 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
871 void DrawGraphicThruMaskExt(DrawBuffer d, int dest_x, int dest_y, int graphic)
879 if (graphic == GFX_LEERRAUM)
882 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
883 src_bitmap = pix_masked[bitmap_nr];
884 drawing_gc = clip_gc[bitmap_nr];
886 if (tile_clipmask[tile] != None)
888 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
889 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
890 BlitBitmapMasked(src_bitmap, d,
891 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
896 #ifndef USE_SDL_LIBRARY
897 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
901 SetClipOrigin(drawing_gc, dest_x-src_x, dest_y-src_y);
902 BlitBitmapMasked(src_bitmap, d,
903 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
907 void DrawMiniGraphic(int x, int y, int graphic)
909 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
910 MarkTileDirty(x/2, y/2);
913 void getMiniGraphicSource(int graphic, Bitmap *bitmap, int *x, int *y)
915 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
917 graphic -= GFX_START_ROCKSSCREEN;
918 *bitmap = pix[PIX_BACK];
919 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
920 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
922 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
924 graphic -= GFX_START_ROCKSSP;
925 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
926 *bitmap = pix[PIX_SP];
927 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
928 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
930 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
932 graphic -= GFX_START_ROCKSDC;
933 *bitmap = pix[PIX_DC];
934 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
935 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
937 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
939 graphic -= GFX_START_ROCKSMORE;
940 *bitmap = pix[PIX_MORE];
941 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
942 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
944 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
946 graphic -= GFX_START_ROCKSFONT;
947 *bitmap = pix[PIX_SMALLFONT];
948 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
949 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
950 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
954 *bitmap = pix[PIX_SP];
960 void DrawMiniGraphicExt(DrawBuffer d, GC gc, int x, int y, int graphic)
965 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
966 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
969 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
970 int cut_mode, int mask_mode)
972 int width = TILEX, height = TILEY;
974 int src_x, src_y, dest_x, dest_y;
981 DrawGraphic(x, y, graphic);
985 if (dx || dy) /* Verschiebung der Grafik? */
987 if (x < BX1) /* Element kommt von links ins Bild */
994 else if (x > BX2) /* Element kommt von rechts ins Bild */
1000 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1006 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1008 else if (dx) /* allg. Bewegung in x-Richtung */
1009 MarkTileDirty(x + SIGN(dx), y);
1011 if (y < BY1) /* Element kommt von oben ins Bild */
1013 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1021 else if (y > BY2) /* Element kommt von unten ins Bild */
1027 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1033 else if (dy > 0 && cut_mode == CUT_ABOVE)
1035 if (y == BY2) /* Element unterhalb des Bildes */
1041 MarkTileDirty(x, y + 1);
1042 } /* Element verläßt unten das Bild */
1043 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1045 else if (dy) /* allg. Bewegung in y-Richtung */
1046 MarkTileDirty(x, y + SIGN(dy));
1049 getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
1050 drawing_gc = clip_gc[bitmap_nr];
1055 dest_x = FX + x * TILEX + dx;
1056 dest_y = FY + y * TILEY + dy;
1059 if (!IN_SCR_FIELD(x,y))
1061 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1062 printf("DrawGraphicShifted(): This should never happen!\n");
1067 if (mask_mode == USE_MASKING)
1069 if (tile_clipmask[tile] != None)
1071 SetClipMask(tile_clip_gc, tile_clipmask[tile]);
1072 SetClipOrigin(tile_clip_gc, dest_x, dest_y);
1073 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1074 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1079 #ifndef USE_SDL_LIBRARY
1080 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1084 SetClipOrigin(drawing_gc, dest_x - src_x, dest_y - src_y);
1085 BlitBitmapMasked(pix_masked[bitmap_nr], drawto_field,
1086 src_x, src_y, width, height, dest_x, dest_y);
1090 BlitBitmap(pix[bitmap_nr], drawto_field,
1091 src_x, src_y, width, height, dest_x, dest_y);
1096 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1099 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1102 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1103 int cut_mode, int mask_mode)
1105 int ux = LEVELX(x), uy = LEVELY(y);
1106 int graphic = el2gfx(element);
1107 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1108 int phase4 = phase8 / 2;
1109 int phase2 = phase8 / 4;
1110 int dir = MovDir[ux][uy];
1112 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1114 graphic += 4 * !phase2;
1118 else if (dir == MV_LEFT)
1120 else if (dir == MV_DOWN)
1123 else if (element == EL_SP_SNIKSNAK)
1126 graphic = GFX_SP_SNIKSNAK_LEFT;
1127 else if (dir == MV_RIGHT)
1128 graphic = GFX_SP_SNIKSNAK_RIGHT;
1129 else if (dir == MV_UP)
1130 graphic = GFX_SP_SNIKSNAK_UP;
1132 graphic = GFX_SP_SNIKSNAK_DOWN;
1134 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1136 else if (element == EL_SP_ELECTRON)
1138 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1140 else if (element == EL_MOLE || element == EL_PINGUIN ||
1141 element == EL_SCHWEIN || element == EL_DRACHE)
1144 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1145 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1146 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1147 else if (dir == MV_RIGHT)
1148 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1149 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1150 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1151 else if (dir == MV_UP)
1152 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1153 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1154 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1156 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1157 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1158 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1162 else if (element == EL_SONDE)
1164 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1166 else if (element == EL_SALZSAEURE)
1168 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1170 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1174 else if (element == EL_BALLOON)
1178 else if ((element == EL_FELSBROCKEN ||
1179 element == EL_SP_ZONK ||
1180 element == EL_BD_ROCK ||
1181 IS_GEM(element)) && !cut_mode)
1183 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1185 if (element == EL_FELSBROCKEN ||
1186 element == EL_SP_ZONK ||
1187 element == EL_BD_ROCK)
1190 graphic += (4 - phase4) % 4;
1191 else if (dir == MV_RIGHT)
1194 graphic += phase2 * 2;
1196 else if (element != EL_SP_INFOTRON)
1200 else if (element == EL_MAGIC_WALL_EMPTY ||
1201 element == EL_MAGIC_WALL_BD_EMPTY ||
1202 element == EL_MAGIC_WALL_FULL ||
1203 element == EL_MAGIC_WALL_BD_FULL)
1205 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1207 else if (IS_AMOEBOID(element))
1209 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1210 graphic += (x + 2 * y + 4) % 4;
1212 else if (element == EL_MAUER_LEBT)
1214 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1216 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1217 links_massiv = TRUE;
1218 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1219 rechts_massiv = TRUE;
1221 if (links_massiv && rechts_massiv)
1222 graphic = GFX_MAUERWERK;
1223 else if (links_massiv)
1224 graphic = GFX_MAUER_R;
1225 else if (rechts_massiv)
1226 graphic = GFX_MAUER_L;
1228 else if ((element == EL_INVISIBLE_STEEL ||
1229 element == EL_UNSICHTBAR ||
1230 element == EL_SAND_INVISIBLE) && game.light_time_left)
1232 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1233 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1234 GFX_SAND_INVISIBLE_ON);
1238 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1239 else if (mask_mode == USE_MASKING)
1240 DrawGraphicThruMask(x, y, graphic);
1242 DrawGraphic(x, y, graphic);
1245 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1246 int cut_mode, int mask_mode)
1248 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1249 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1250 cut_mode, mask_mode);
1253 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1256 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1259 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1262 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1265 void DrawScreenElementThruMask(int x, int y, int element)
1267 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1270 void DrawLevelElementThruMask(int x, int y, int element)
1272 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1275 void DrawLevelFieldThruMask(int x, int y)
1277 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1280 void ErdreichAnbroeckeln(int x, int y)
1282 int i, width, height, cx,cy;
1283 int ux = LEVELX(x), uy = LEVELY(y);
1284 int element, graphic;
1286 static int xy[4][2] =
1294 if (!IN_LEV_FIELD(ux, uy))
1297 element = Feld[ux][uy];
1299 if (element == EL_ERDREICH ||
1300 element == EL_LANDMINE ||
1301 element == EL_TRAP_INACTIVE ||
1302 element == EL_TRAP_ACTIVE)
1304 if (!IN_SCR_FIELD(x, y))
1307 graphic = GFX_ERDENRAND;
1313 uxx = ux + xy[i][0];
1314 uyy = uy + xy[i][1];
1315 if (!IN_LEV_FIELD(uxx, uyy))
1318 element = Feld[uxx][uyy];
1320 if (element == EL_ERDREICH ||
1321 element == EL_LANDMINE ||
1322 element == EL_TRAP_INACTIVE ||
1323 element == EL_TRAP_ACTIVE)
1326 if (i == 1 || i == 2)
1330 cx = (i == 2 ? TILEX - snip : 0);
1338 cy = (i == 3 ? TILEY - snip : 0);
1341 BlitBitmap(pix[PIX_BACK], drawto_field,
1342 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1343 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1344 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1347 MarkTileDirty(x, y);
1351 graphic = GFX_ERDENRAND;
1355 int xx, yy, uxx, uyy;
1359 uxx = ux + xy[i][0];
1360 uyy = uy + xy[i][1];
1362 if (!IN_LEV_FIELD(uxx, uyy) ||
1363 (Feld[uxx][uyy] != EL_ERDREICH &&
1364 Feld[uxx][uyy] != EL_LANDMINE &&
1365 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1366 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1367 !IN_SCR_FIELD(xx, yy))
1370 if (i == 1 || i == 2)
1374 cx = (i == 1 ? TILEX - snip : 0);
1382 cy = (i==0 ? TILEY-snip : 0);
1385 BlitBitmap(pix[PIX_BACK], drawto_field,
1386 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1387 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1388 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1390 MarkTileDirty(xx, yy);
1395 void DrawScreenElement(int x, int y, int element)
1397 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1398 ErdreichAnbroeckeln(x, y);
1401 void DrawLevelElement(int x, int y, int element)
1403 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1404 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1407 void DrawScreenField(int x, int y)
1409 int ux = LEVELX(x), uy = LEVELY(y);
1412 if (!IN_LEV_FIELD(ux, uy))
1414 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1415 element = EL_LEERRAUM;
1417 element = BorderElement;
1419 DrawScreenElement(x, y, element);
1423 element = Feld[ux][uy];
1425 if (IS_MOVING(ux, uy))
1427 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1428 boolean cut_mode = NO_CUTTING;
1430 if (Store[ux][uy] == EL_MORAST_LEER ||
1431 Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
1432 Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
1433 Store[ux][uy] == EL_AMOEBE_NASS)
1434 cut_mode = CUT_ABOVE;
1435 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1436 Store[ux][uy] == EL_MAGIC_WALL_FULL ||
1437 Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
1438 cut_mode = CUT_BELOW;
1440 if (cut_mode == CUT_ABOVE)
1441 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1443 DrawScreenElement(x, y, EL_LEERRAUM);
1446 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1448 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1450 if (Store[ux][uy] == EL_SALZSAEURE)
1451 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1453 else if (IS_BLOCKED(ux, uy))
1458 boolean cut_mode = NO_CUTTING;
1460 Blocked2Moving(ux, uy, &oldx, &oldy);
1463 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1464 MovDir[oldx][oldy] == MV_RIGHT);
1466 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1467 Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
1468 Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
1469 Store[oldx][oldy] == EL_AMOEBE_NASS)
1470 cut_mode = CUT_ABOVE;
1472 DrawScreenElement(x, y, EL_LEERRAUM);
1473 element = Feld[oldx][oldy];
1476 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1478 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1480 else if (IS_DRAWABLE(element))
1481 DrawScreenElement(x, y, element);
1483 DrawScreenElement(x, y, EL_LEERRAUM);
1486 void DrawLevelField(int x, int y)
1488 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1489 DrawScreenField(SCREENX(x), SCREENY(y));
1490 else if (IS_MOVING(x, y))
1494 Moving2Blocked(x, y, &newx, &newy);
1495 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1496 DrawScreenField(SCREENX(newx), SCREENY(newy));
1498 else if (IS_BLOCKED(x, y))
1502 Blocked2Moving(x, y, &oldx, &oldy);
1503 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1504 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1508 void DrawMiniElement(int x, int y, int element)
1514 DrawMiniGraphic(x, y, -1);
1518 graphic = el2gfx(element);
1519 DrawMiniGraphic(x, y, graphic);
1522 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1524 int x = sx + scroll_x, y = sy + scroll_y;
1526 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1527 DrawMiniElement(sx, sy, EL_LEERRAUM);
1528 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1529 DrawMiniElement(sx, sy, Feld[x][y]);
1532 int steel_type, steel_position;
1535 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1536 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1537 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1538 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1539 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1540 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1543 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1544 steel_position = (x == -1 && y == -1 ? 0 :
1545 x == lev_fieldx && y == -1 ? 1 :
1546 x == -1 && y == lev_fieldy ? 2 :
1547 x == lev_fieldx && y == lev_fieldy ? 3 :
1548 x == -1 || x == lev_fieldx ? 4 :
1549 y == -1 || y == lev_fieldy ? 5 : -1);
1551 if (steel_position != -1)
1552 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1556 void DrawMicroElement(int xpos, int ypos, int element)
1560 if (element == EL_LEERRAUM)
1563 graphic = el2gfx(element);
1565 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1567 graphic -= GFX_START_ROCKSSP;
1568 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1569 BlitBitmap(pix[PIX_SP], drawto,
1570 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1571 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1572 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1574 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1576 graphic -= GFX_START_ROCKSDC;
1577 BlitBitmap(pix[PIX_DC], drawto,
1578 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1579 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1580 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1582 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1584 graphic -= GFX_START_ROCKSMORE;
1585 BlitBitmap(pix[PIX_MORE], drawto,
1586 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
1587 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
1588 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1591 BlitBitmap(pix[PIX_BACK], drawto,
1592 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1593 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1594 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1603 for(x=BX1; x<=BX2; x++)
1604 for(y=BY1; y<=BY2; y++)
1605 DrawScreenField(x, y);
1607 redraw_mask |= REDRAW_FIELD;
1610 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1614 for(x=0; x<size_x; x++)
1615 for(y=0; y<size_y; y++)
1616 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1618 redraw_mask |= REDRAW_FIELD;
1621 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1625 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1627 if (lev_fieldx < STD_LEV_FIELDX)
1628 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1629 if (lev_fieldy < STD_LEV_FIELDY)
1630 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1632 xpos += MICRO_TILEX;
1633 ypos += MICRO_TILEY;
1635 for(x=-1; x<=STD_LEV_FIELDX; x++)
1637 for(y=-1; y<=STD_LEV_FIELDY; y++)
1639 int lx = from_x + x, ly = from_y + y;
1641 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1642 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1644 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1645 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1650 redraw_mask |= REDRAW_MICROLEVEL;
1653 #define MICROLABEL_EMPTY 0
1654 #define MICROLABEL_LEVEL_NAME 1
1655 #define MICROLABEL_CREATED_BY 2
1656 #define MICROLABEL_LEVEL_AUTHOR 3
1657 #define MICROLABEL_IMPORTED_FROM 4
1658 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1660 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1662 static void DrawMicroLevelLabelExt(int mode)
1664 char label_text[MAX_MICROLABEL_SIZE + 1];
1666 ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1668 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1669 mode == MICROLABEL_CREATED_BY ? "created by" :
1670 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1671 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1672 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1673 leveldir_current->imported_from : ""),
1674 MAX_MICROLABEL_SIZE);
1675 label_text[MAX_MICROLABEL_SIZE] = '\0';
1677 if (strlen(label_text) > 0)
1679 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1680 int lypos = MICROLABEL_YPOS;
1682 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1685 redraw_mask |= REDRAW_MICROLEVEL;
1688 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1690 static unsigned long scroll_delay = 0;
1691 static unsigned long label_delay = 0;
1692 static int from_x, from_y, scroll_direction;
1693 static int label_state, label_counter;
1697 from_x = from_y = 0;
1698 scroll_direction = MV_RIGHT;
1702 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1703 DrawMicroLevelLabelExt(label_state);
1705 /* initialize delay counters */
1706 DelayReached(&scroll_delay, 0);
1707 DelayReached(&label_delay, 0);
1712 /* scroll micro level, if needed */
1713 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1714 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1716 switch (scroll_direction)
1722 scroll_direction = MV_UP;
1726 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1729 scroll_direction = MV_DOWN;
1736 scroll_direction = MV_RIGHT;
1740 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1743 scroll_direction = MV_LEFT;
1750 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1753 /* redraw micro level label, if needed */
1754 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1755 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1756 strcmp(level.author, leveldir_current->name) != 0 &&
1757 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1759 int max_label_counter = 23;
1761 if (leveldir_current->imported_from != NULL)
1762 max_label_counter += 14;
1764 label_counter = (label_counter + 1) % max_label_counter;
1765 label_state = (label_counter >= 0 && label_counter <= 7 ?
1766 MICROLABEL_LEVEL_NAME :
1767 label_counter >= 9 && label_counter <= 12 ?
1768 MICROLABEL_CREATED_BY :
1769 label_counter >= 14 && label_counter <= 21 ?
1770 MICROLABEL_LEVEL_AUTHOR :
1771 label_counter >= 23 && label_counter <= 26 ?
1772 MICROLABEL_IMPORTED_FROM :
1773 label_counter >= 28 && label_counter <= 35 ?
1774 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1775 DrawMicroLevelLabelExt(label_state);
1779 int REQ_in_range(int x, int y)
1781 if (y > DY+249 && y < DY+278)
1783 if (x > DX+1 && x < DX+48)
1785 else if (x > DX+51 && x < DX+98)
1791 boolean Request(char *text, unsigned int req_state)
1793 int mx, my, ty, result = -1;
1794 unsigned int old_door_state;
1797 /* pause network game while waiting for request to answer */
1798 if (options.network &&
1799 game_status == PLAYING &&
1800 req_state & REQUEST_WAIT_FOR)
1801 SendToServer_PausePlaying();
1804 old_door_state = GetDoorState();
1808 CloseDoor(DOOR_CLOSE_1);
1810 /* save old door content */
1811 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
1812 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1813 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1815 /* clear door drawing field */
1816 ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
1818 /* write text for request */
1819 for(ty=0; ty<13; ty++)
1827 for(tl=0,tx=0; tx<7; tl++,tx++)
1830 if (!tc || tc == 32)
1841 DrawTextExt(drawto, gc,
1842 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1843 txt, FS_SMALL, FC_YELLOW);
1844 text += tl + (tc == 32 ? 1 : 0);
1847 if (req_state & REQ_ASK)
1849 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1850 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1852 else if (req_state & REQ_CONFIRM)
1854 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1856 else if (req_state & REQ_PLAYER)
1858 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1859 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1860 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1861 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1864 /* copy request gadgets to door backbuffer */
1865 BlitBitmap(drawto, pix[PIX_DB_DOOR],
1866 DX, DY, DXSIZE, DYSIZE,
1867 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1869 OpenDoor(DOOR_OPEN_1);
1875 if (!(req_state & REQUEST_WAIT_FOR))
1878 if (game_status != MAINMENU)
1881 button_status = MB_RELEASED;
1883 request_gadget_id = -1;
1895 case EVENT_BUTTONPRESS:
1896 case EVENT_BUTTONRELEASE:
1897 case EVENT_MOTIONNOTIFY:
1899 if (event.type == EVENT_MOTIONNOTIFY)
1903 if (!QueryPointer(window, &win_x, &win_y))
1904 continue; /* window and pointer are on different screens */
1909 motion_status = TRUE;
1910 mx = ((MotionEvent *) &event)->x;
1911 my = ((MotionEvent *) &event)->y;
1915 motion_status = FALSE;
1916 mx = ((ButtonEvent *) &event)->x;
1917 my = ((ButtonEvent *) &event)->y;
1918 if (event.type == EVENT_BUTTONPRESS)
1919 button_status = ((ButtonEvent *) &event)->button;
1921 button_status = MB_RELEASED;
1924 /* this sets 'request_gadget_id' */
1925 HandleGadgets(mx, my, button_status);
1927 switch(request_gadget_id)
1929 case TOOL_CTRL_ID_YES:
1932 case TOOL_CTRL_ID_NO:
1935 case TOOL_CTRL_ID_CONFIRM:
1936 result = TRUE | FALSE;
1939 case TOOL_CTRL_ID_PLAYER_1:
1942 case TOOL_CTRL_ID_PLAYER_2:
1945 case TOOL_CTRL_ID_PLAYER_3:
1948 case TOOL_CTRL_ID_PLAYER_4:
1959 case EVENT_KEYPRESS:
1960 switch(XLookupKeysym((KeyEvent *)&event,
1961 ((KeyEvent *)&event)->state))
1974 if (req_state & REQ_PLAYER)
1978 case EVENT_KEYRELEASE:
1979 key_joystick_mapping = 0;
1983 HandleOtherEvents(&event);
1987 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1989 int joy = AnyJoystick();
1991 if (joy & JOY_BUTTON_1)
1993 else if (joy & JOY_BUTTON_2)
1999 /* don't eat all CPU time */
2003 if (game_status != MAINMENU)
2008 if (!(req_state & REQ_STAY_OPEN))
2010 CloseDoor(DOOR_CLOSE_1);
2012 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2014 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2015 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2016 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2017 OpenDoor(DOOR_OPEN_1);
2024 /* continue network game after request */
2025 if (options.network &&
2026 game_status == PLAYING &&
2027 req_state & REQUEST_WAIT_FOR)
2028 SendToServer_ContinuePlaying();
2034 unsigned int OpenDoor(unsigned int door_state)
2036 unsigned int new_door_state;
2038 if (door_state & DOOR_COPY_BACK)
2040 BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
2041 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2042 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2043 door_state &= ~DOOR_COPY_BACK;
2046 new_door_state = MoveDoor(door_state);
2048 return(new_door_state);
2051 unsigned int CloseDoor(unsigned int door_state)
2053 unsigned int new_door_state;
2055 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2056 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2057 BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
2058 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2060 new_door_state = MoveDoor(door_state);
2062 return(new_door_state);
2065 unsigned int GetDoorState()
2067 return(MoveDoor(DOOR_GET_STATE));
2070 unsigned int MoveDoor(unsigned int door_state)
2072 static int door1 = DOOR_OPEN_1;
2073 static int door2 = DOOR_CLOSE_2;
2074 static unsigned long door_delay = 0;
2075 int x, start, stepsize = 2;
2076 unsigned long door_delay_value = stepsize * 5;
2078 if (door_state == DOOR_GET_STATE)
2079 return(door1 | door2);
2081 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2082 door_state &= ~DOOR_OPEN_1;
2083 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2084 door_state &= ~DOOR_CLOSE_1;
2085 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2086 door_state &= ~DOOR_OPEN_2;
2087 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2088 door_state &= ~DOOR_CLOSE_2;
2090 if (setup.quick_doors)
2093 door_delay_value = 0;
2094 StopSound(SND_OEFFNEN);
2097 if (door_state & DOOR_ACTION)
2099 if (!(door_state & DOOR_NO_DELAY))
2100 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2102 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2104 for(x=start; x<=DXSIZE; x+=stepsize)
2106 WaitUntilDelayReached(&door_delay, door_delay_value);
2108 if (door_state & DOOR_ACTION_1)
2110 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2111 int j = (DXSIZE - i) / 3;
2113 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2114 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2115 DXSIZE,DYSIZE - i/2, DX, DY);
2117 ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2119 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2120 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2121 DXSIZE, DOOR_GFX_PAGEY1, i, 77,
2122 DX + DXSIZE - i, DY + j);
2123 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2124 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
2125 DX + DXSIZE - i, DY + 140 + j);
2126 SetClipOrigin(clip_gc[PIX_DOOR],
2127 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2128 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2129 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
2131 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2132 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
2135 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2136 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2138 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2139 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2141 SetClipOrigin(clip_gc[PIX_DOOR], DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2142 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2143 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2144 DX + DXSIZE - i, DY + 77 + j);
2145 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2146 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2147 DX + DXSIZE - i, DY + 203 + j);
2149 redraw_mask |= REDRAW_DOOR_1;
2152 if (door_state & DOOR_ACTION_2)
2154 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2155 int j = (VXSIZE - i) / 3;
2157 BlitBitmap(pix[PIX_DB_DOOR], drawto,
2158 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2159 VXSIZE, VYSIZE - i/2, VX, VY);
2161 ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2163 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2164 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2165 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
2166 VX + VXSIZE-i, VY+j);
2167 SetClipOrigin(clip_gc[PIX_DOOR],
2168 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2169 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2170 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
2173 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2174 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2175 i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
2176 SetClipOrigin(clip_gc[PIX_DOOR], VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2177 BlitBitmapMasked(pix_masked[PIX_DOOR], drawto,
2178 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
2180 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2182 redraw_mask |= REDRAW_DOOR_2;
2187 if (game_status == MAINMENU)
2192 if (setup.quick_doors)
2193 StopSound(SND_OEFFNEN);
2195 if (door_state & DOOR_ACTION_1)
2196 door1 = door_state & DOOR_ACTION_1;
2197 if (door_state & DOOR_ACTION_2)
2198 door2 = door_state & DOOR_ACTION_2;
2200 return (door1 | door2);
2203 void DrawSpecialEditorDoor()
2205 /* draw bigger toolbox window */
2206 BlitBitmap(pix[PIX_DOOR], drawto,
2207 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2209 redraw_mask |= REDRAW_ALL;
2212 void UndrawSpecialEditorDoor()
2214 /* draw normal tape recorder window */
2215 BlitBitmap(pix[PIX_BACK], drawto,
2216 562, 344, 108, 56, EX - 4, EY - 12);
2218 redraw_mask |= REDRAW_ALL;
2221 #ifndef USE_SDL_LIBRARY
2222 int ReadPixel(DrawBuffer d, int x, int y)
2224 XImage *pixel_image;
2225 unsigned long pixel_value;
2227 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
2228 pixel_value = XGetPixel(pixel_image, 0, 0);
2230 XDestroyImage(pixel_image);
2236 /* ---------- new tool button stuff ---------------------------------------- */
2238 /* graphic position values for tool buttons */
2239 #define TOOL_BUTTON_YES_XPOS 2
2240 #define TOOL_BUTTON_YES_YPOS 250
2241 #define TOOL_BUTTON_YES_GFX_YPOS 0
2242 #define TOOL_BUTTON_YES_XSIZE 46
2243 #define TOOL_BUTTON_YES_YSIZE 28
2244 #define TOOL_BUTTON_NO_XPOS 52
2245 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2246 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2247 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2248 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2249 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2250 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2251 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2252 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2253 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2254 #define TOOL_BUTTON_PLAYER_XSIZE 30
2255 #define TOOL_BUTTON_PLAYER_YSIZE 30
2256 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2257 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2258 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2259 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2260 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2261 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2262 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2263 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2264 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2265 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2266 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2267 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2268 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2269 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2270 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2271 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2272 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2273 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2274 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2275 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2284 } toolbutton_info[NUM_TOOL_BUTTONS] =
2287 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2288 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2289 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2294 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2295 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2296 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2301 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2302 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2303 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2304 TOOL_CTRL_ID_CONFIRM,
2308 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2309 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2310 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2311 TOOL_CTRL_ID_PLAYER_1,
2315 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2316 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2317 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2318 TOOL_CTRL_ID_PLAYER_2,
2322 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2323 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2324 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2325 TOOL_CTRL_ID_PLAYER_3,
2329 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2330 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2331 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2332 TOOL_CTRL_ID_PLAYER_4,
2337 static void DoNotDisplayInfoText(void *ptr)
2342 void CreateToolButtons()
2346 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2348 Bitmap gd_bitmap = pix[PIX_DOOR];
2349 Bitmap deco_bitmap = None;
2350 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2351 struct GadgetInfo *gi;
2352 unsigned long event_mask;
2353 int gd_xoffset, gd_yoffset;
2354 int gd_x1, gd_x2, gd_y;
2357 event_mask = GD_EVENT_RELEASED;
2359 gd_xoffset = toolbutton_info[i].xpos;
2360 gd_yoffset = toolbutton_info[i].ypos;
2361 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2362 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2363 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2365 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2367 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2368 &deco_bitmap, &deco_x, &deco_y);
2369 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2370 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2373 gi = CreateGadget(GDI_CUSTOM_ID, id,
2374 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2375 GDI_X, DX + toolbutton_info[i].x,
2376 GDI_Y, DY + toolbutton_info[i].y,
2377 GDI_WIDTH, toolbutton_info[i].width,
2378 GDI_HEIGHT, toolbutton_info[i].height,
2379 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2380 GDI_STATE, GD_BUTTON_UNPRESSED,
2381 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
2382 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
2383 GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
2384 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2385 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2386 GDI_DECORATION_SHIFTING, 1, 1,
2387 GDI_EVENT_MASK, event_mask,
2388 GDI_CALLBACK_ACTION, HandleToolButtons,
2389 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2393 Error(ERR_EXIT, "cannot create gadget");
2395 tool_gadget[id] = gi;
2399 static void UnmapToolButtons()
2403 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2404 UnmapGadget(tool_gadget[i]);
2407 static void HandleToolButtons(struct GadgetInfo *gi)
2409 request_gadget_id = gi->custom_id;
2412 int el2gfx(int element)
2416 case EL_LEERRAUM: return -1;
2417 case EL_ERDREICH: return GFX_ERDREICH;
2418 case EL_MAUERWERK: return GFX_MAUERWERK;
2419 case EL_FELSBODEN: return GFX_FELSBODEN;
2420 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2421 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2422 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2423 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2424 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2425 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2426 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2427 case EL_SPIELER1: return GFX_SPIELER1;
2428 case EL_SPIELER2: return GFX_SPIELER2;
2429 case EL_SPIELER3: return GFX_SPIELER3;
2430 case EL_SPIELER4: return GFX_SPIELER4;
2431 case EL_KAEFER: return GFX_KAEFER;
2432 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2433 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2434 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2435 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2436 case EL_FLIEGER: return GFX_FLIEGER;
2437 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2438 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2439 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2440 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2441 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2442 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2443 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2444 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2445 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2446 case EL_FIREFLY: return GFX_FIREFLY;
2447 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2448 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2449 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2450 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2451 case EL_MAMPFER: return GFX_MAMPFER;
2452 case EL_ROBOT: return GFX_ROBOT;
2453 case EL_BETON: return GFX_BETON;
2454 case EL_DIAMANT: return GFX_DIAMANT;
2455 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2456 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2457 case EL_TROPFEN: return GFX_TROPFEN;
2458 case EL_BOMBE: return GFX_BOMBE;
2459 case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
2460 case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
2461 case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
2462 case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
2463 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2464 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2465 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2466 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2467 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2468 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2469 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2470 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2471 case EL_LIFE: return GFX_LIFE;
2472 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2473 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2474 case EL_BADEWANNE: return GFX_BADEWANNE;
2475 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2476 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2477 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2478 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2479 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2480 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2481 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2482 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2483 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2484 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2485 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2486 case EL_PFORTE1: return GFX_PFORTE1;
2487 case EL_PFORTE2: return GFX_PFORTE2;
2488 case EL_PFORTE3: return GFX_PFORTE3;
2489 case EL_PFORTE4: return GFX_PFORTE4;
2490 case EL_PFORTE1X: return GFX_PFORTE1X;
2491 case EL_PFORTE2X: return GFX_PFORTE2X;
2492 case EL_PFORTE3X: return GFX_PFORTE3X;
2493 case EL_PFORTE4X: return GFX_PFORTE4X;
2494 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2495 case EL_PACMAN: return GFX_PACMAN;
2496 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2497 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2498 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2499 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2500 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2501 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2502 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2503 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2504 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2505 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2506 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2507 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2508 case EL_MAUER_X: return GFX_MAUER_X;
2509 case EL_MAUER_Y: return GFX_MAUER_Y;
2510 case EL_MAUER_XY: return GFX_MAUER_XY;
2511 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2512 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2513 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2514 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2515 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2516 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2517 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2518 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2519 case EL_MAMPFER2: return GFX_MAMPFER2;
2520 case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
2521 case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
2522 case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
2523 case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
2524 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2525 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2526 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2527 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2528 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2529 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2530 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2531 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2532 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2533 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2534 case EL_MOLE: return GFX_MOLE;
2535 case EL_PINGUIN: return GFX_PINGUIN;
2536 case EL_SCHWEIN: return GFX_SCHWEIN;
2537 case EL_DRACHE: return GFX_DRACHE;
2538 case EL_SONDE: return GFX_SONDE;
2539 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2540 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2541 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2542 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2543 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2544 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2545 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2546 case EL_SP_ZONK: return GFX_SP_ZONK;
2547 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2548 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2549 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2550 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2551 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2552 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2553 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2554 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2555 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2556 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2557 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2558 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2559 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2560 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2561 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2562 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2563 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2564 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2565 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2566 case EL_PEARL: return GFX_PEARL;
2567 case EL_CRYSTAL: return GFX_CRYSTAL;
2568 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2569 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2570 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2571 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2572 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2573 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2574 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2575 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2576 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2577 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2578 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2579 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2580 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2581 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2582 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2583 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2584 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2585 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2586 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2587 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2588 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2589 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2590 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2591 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2592 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2593 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2594 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2595 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2596 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2597 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2598 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2599 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2600 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2601 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2602 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2603 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2604 case EL_LANDMINE: return GFX_LANDMINE;
2605 case EL_ENVELOPE: return GFX_ENVELOPE;
2606 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2607 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2608 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2609 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2610 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2611 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2612 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2613 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2614 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2615 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2616 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2617 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2618 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2619 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2620 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2621 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2622 case EL_MOLE_UP: return GFX_MOLE_UP;
2623 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2624 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2625 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2626 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2627 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2628 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2629 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2630 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2631 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2632 case EL_BALLOON: return GFX_BALLOON;
2633 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2634 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2635 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2636 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2637 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2638 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2639 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2640 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2641 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2642 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2643 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2644 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2645 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2646 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2647 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2648 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2649 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2650 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2651 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2652 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2653 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2654 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2655 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2656 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2657 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2658 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2659 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2660 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2661 case EL_SPRING: return GFX_SPRING;
2662 case EL_SPRING_MOVING: return GFX_SPRING;
2663 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2664 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2665 case EL_BD_WALL: return GFX_BD_WALL;
2666 case EL_BD_ROCK: return GFX_BD_ROCK;
2667 case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
2668 case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
2672 if (IS_CHAR(element))
2673 return GFX_CHAR_START + (element - EL_CHAR_START);
2674 else if (element >= EL_SP_START && element <= EL_SP_END)
2676 int nr_element = element - EL_SP_START;
2677 int gfx_per_line = 8;
2679 (nr_element / gfx_per_line) * SP_PER_LINE +
2680 (nr_element % gfx_per_line);
2682 return GFX_START_ROCKSSP + nr_graphic;