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 Drawable 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 */
107 XSync(display, FALSE);
109 if (redraw_mask & REDRAW_ALL)
111 XCopyArea(display, backbuffer, window, gc,
112 0, 0, WIN_XSIZE, WIN_YSIZE,
117 if (redraw_mask & REDRAW_FIELD)
119 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
121 XCopyArea(display, backbuffer, window, gc,
122 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
127 int fx = FX, fy = FY;
129 if (setup.soft_scrolling)
131 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
132 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
135 if (setup.soft_scrolling ||
136 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
137 ABS(ScreenMovPos) == ScrollStepSize ||
138 redraw_tiles > REDRAWTILES_THRESHOLD)
140 XCopyArea(display, buffer, window, gc, fx, fy, SXSIZE, SYSIZE, SX, SY);
144 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
146 (setup.soft_scrolling ?
147 "setup.soft_scrolling" :
148 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
149 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
150 ABS(ScreenGfxPos) == ScrollStepSize ?
151 "ABS(ScreenGfxPos) == ScrollStepSize" :
152 "redraw_tiles > REDRAWTILES_THRESHOLD"));
157 redraw_mask &= ~REDRAW_MAIN;
160 if (redraw_mask & REDRAW_DOORS)
162 if (redraw_mask & REDRAW_DOOR_1)
163 XCopyArea(display, backbuffer, window, gc,
164 DX, DY, DXSIZE, DYSIZE,
166 if (redraw_mask & REDRAW_DOOR_2)
168 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
169 XCopyArea(display,backbuffer,window,gc,
170 VX,VY, VXSIZE,VYSIZE,
174 if (redraw_mask & REDRAW_VIDEO_1)
175 XCopyArea(display,backbuffer,window,gc,
176 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
177 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
178 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
179 if (redraw_mask & REDRAW_VIDEO_2)
180 XCopyArea(display,backbuffer,window,gc,
181 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
182 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
183 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
184 if (redraw_mask & REDRAW_VIDEO_3)
185 XCopyArea(display,backbuffer,window,gc,
186 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
187 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
188 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
191 if (redraw_mask & REDRAW_DOOR_3)
192 XCopyArea(display, backbuffer, window, gc,
193 EX, EY, EXSIZE, EYSIZE,
195 redraw_mask &= ~REDRAW_DOORS;
198 if (redraw_mask & REDRAW_MICROLEVEL)
200 XCopyArea(display,backbuffer,window,gc,
201 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
202 MICROLEV_XPOS, MICROLEV_YPOS);
203 XCopyArea(display,backbuffer,window,gc,
204 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
205 SX, MICROLABEL_YPOS);
206 redraw_mask &= ~REDRAW_MICROLEVEL;
209 if (redraw_mask & REDRAW_TILES)
211 for(x=0; x<SCR_FIELDX; x++)
212 for(y=0; y<SCR_FIELDY; y++)
213 if (redraw[redraw_x1 + x][redraw_y1 + y])
214 XCopyArea(display, buffer, window, gc,
215 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
216 SX + x * TILEX, SY + y * TILEY);
221 for(x=0; x<MAX_BUF_XSIZE; x++)
222 for(y=0; y<MAX_BUF_YSIZE; y++)
231 long fading_delay = 300;
233 if (setup.fading && (redraw_mask & REDRAW_FIELD))
240 XFillRectangle(display,window,gc,
241 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
244 for(i=0;i<2*FULL_SYSIZE;i++)
246 for(y=0;y<FULL_SYSIZE;y++)
248 XCopyArea(display,backbuffer,window,gc,
249 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
257 for(i=1;i<FULL_SYSIZE;i+=2)
258 XCopyArea(display,backbuffer,window,gc,
259 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
265 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
266 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
267 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
271 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
272 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
273 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
277 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
278 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
279 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
283 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
284 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
285 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
289 redraw_mask &= ~REDRAW_MAIN;
298 XFillRectangle(display, backbuffer, gc,
299 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
301 if (setup.soft_scrolling && game_status == PLAYING)
303 XFillRectangle(display, fieldbuffer, gc, 0, 0, FXSIZE, FYSIZE);
304 SetDrawtoField(DRAW_BUFFERED);
307 SetDrawtoField(DRAW_BACKBUFFER);
309 if (setup.direct_draw && game_status == PLAYING)
311 XFillRectangle(display, window, gc,
312 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
313 SetDrawtoField(DRAW_DIRECT);
316 redraw_mask |= REDRAW_FIELD;
319 int getFontWidth(int font_size, int font_type)
321 return (font_size == FS_BIG ? FONT1_XSIZE :
322 font_size == FS_MEDIUM ? FONT6_XSIZE :
323 font_type == FC_SPECIAL1 ? FONT3_XSIZE :
324 font_type == FC_SPECIAL2 ? FONT4_XSIZE :
325 font_type == FC_SPECIAL3 ? FONT5_XSIZE :
329 int getFontHeight(int font_size, int font_type)
331 return (font_size == FS_BIG ? FONT1_YSIZE :
332 font_size == FS_MEDIUM ? FONT6_YSIZE :
333 font_type == FC_SPECIAL1 ? FONT3_YSIZE :
334 font_type == FC_SPECIAL2 ? FONT4_YSIZE :
335 font_type == FC_SPECIAL3 ? FONT5_YSIZE :
339 void DrawInitText(char *text, int ypos, int color)
341 if (display && window && pix[PIX_SMALLFONT])
343 XFillRectangle(display, window, gc, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
344 DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
345 ypos,text,FS_SMALL,color);
350 void DrawTextFCentered(int y, int font_type, char *format, ...)
352 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
353 int font_width = getFontWidth(FS_SMALL, font_type);
356 va_start(ap, format);
357 vsprintf(buffer, format, ap);
360 DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
361 buffer, FS_SMALL, font_type);
364 void DrawTextF(int x, int y, int font_type, char *format, ...)
366 char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
369 va_start(ap, format);
370 vsprintf(buffer, format, ap);
373 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
376 void DrawText(int x, int y, char *text, int font_size, int font_type)
378 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
381 redraw_mask |= REDRAW_FIELD;
383 redraw_mask |= REDRAW_DOOR_1;
386 void DrawTextExt(Drawable d, GC gc, int x, int y,
387 char *text, int font_size, int font_type)
389 int font_width, font_height, font_start;
391 boolean print_inverse = FALSE;
393 if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
394 font_size = FS_SMALL;
395 if (font_type < FC_RED || font_type > FC_SPECIAL3)
398 font_width = getFontWidth(font_size, font_type);
399 font_height = getFontHeight(font_size, font_type);
401 font_pixmap = (font_size == FS_BIG ? PIX_BIGFONT :
402 font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
404 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
405 font_size == FS_MEDIUM ? FONT6_YSIZE :
407 FONT_LINES_PER_FONT);
409 if (font_type == FC_SPECIAL3)
410 font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
416 if (c == '~' && font_size == FS_SMALL)
418 print_inverse = TRUE;
422 if (c >= 'a' && c <= 'z')
424 else if (c == 'ä' || c == 'Ä')
426 else if (c == 'ö' || c == 'Ö')
428 else if (c == 'ü' || c == 'Ü')
431 if (c >= 32 && c <= 95)
433 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
434 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
435 int dest_x = x, dest_y = y;
439 XCopyArea(display, pix[font_pixmap], d, gc,
440 FONT_CHARS_PER_LINE * font_width,
441 3 * font_height + font_start,
442 font_width, font_height, x, y);
444 XSetClipOrigin(display, clip_gc[font_pixmap],
445 dest_x - src_x, dest_y - src_y);
446 XCopyArea(display, pix[font_pixmap], d, clip_gc[font_pixmap],
447 0, 0, font_width, font_height, dest_x, dest_y);
450 XCopyArea(display, pix[font_pixmap], d, gc,
451 src_x, src_y, font_width, font_height, dest_x, dest_y);
458 void DrawAllPlayers()
462 for(i=0; i<MAX_PLAYERS; i++)
463 if (stored_player[i].active)
464 DrawPlayer(&stored_player[i]);
467 void DrawPlayerField(int x, int y)
469 if (!IS_PLAYER(x, y))
472 DrawPlayer(PLAYERINFO(x, y));
475 void DrawPlayer(struct PlayerInfo *player)
477 int jx = player->jx, jy = player->jy;
478 int last_jx = player->last_jx, last_jy = player->last_jy;
479 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
480 int sx = SCREENX(jx), sy = SCREENY(jy);
481 int sxx = 0, syy = 0;
482 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
484 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
486 if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
490 if (!IN_LEV_FIELD(jx,jy))
492 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
493 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
494 printf("DrawPlayerField(): This should never happen!\n");
499 if (element == EL_EXPLODING)
502 /* draw things in the field the player is leaving, if needed */
504 if (player_is_moving)
506 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
508 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
509 DrawLevelFieldThruMask(last_jx, last_jy);
511 else if (last_element == EL_DYNAMITE_ACTIVE)
512 DrawDynamite(last_jx, last_jy);
514 DrawLevelField(last_jx, last_jy);
516 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
520 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
521 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
523 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
526 DrawLevelField(next_jx, next_jy);
530 if (!IN_SCR_FIELD(sx, sy))
533 if (setup.direct_draw)
534 SetDrawtoField(DRAW_BUFFERED);
536 /* draw things behind the player, if needed */
539 DrawLevelElement(jx, jy, Store[jx][jy]);
540 else if (!IS_ACTIVE_BOMB(element))
541 DrawLevelField(jx, jy);
543 /* draw player himself */
545 if (game.emulation == EMU_SUPAPLEX)
547 static int last_dir = MV_LEFT;
548 int action = (player->programmed_action ? player->programmed_action :
550 boolean action_moving =
552 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
553 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
555 graphic = GFX_SP_MURPHY;
559 if (player->MovDir == MV_LEFT)
560 graphic = GFX_MURPHY_PUSH_LEFT;
561 else if (player->MovDir == MV_RIGHT)
562 graphic = GFX_MURPHY_PUSH_RIGHT;
563 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
564 graphic = GFX_MURPHY_PUSH_LEFT;
565 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
566 graphic = GFX_MURPHY_PUSH_RIGHT;
568 else if (player->snapped)
570 if (player->MovDir == MV_LEFT)
571 graphic = GFX_MURPHY_SNAP_LEFT;
572 else if (player->MovDir == MV_RIGHT)
573 graphic = GFX_MURPHY_SNAP_RIGHT;
574 else if (player->MovDir == MV_UP)
575 graphic = GFX_MURPHY_SNAP_UP;
576 else if (player->MovDir == MV_DOWN)
577 graphic = GFX_MURPHY_SNAP_DOWN;
579 else if (action_moving)
581 if (player->MovDir == MV_LEFT)
582 graphic = GFX_MURPHY_GO_LEFT;
583 else if (player->MovDir == MV_RIGHT)
584 graphic = GFX_MURPHY_GO_RIGHT;
585 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
586 graphic = GFX_MURPHY_GO_LEFT;
587 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
588 graphic = GFX_MURPHY_GO_RIGHT;
590 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
593 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
594 last_dir = player->MovDir;
598 if (player->MovDir == MV_LEFT)
600 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
601 else if (player->MovDir == MV_RIGHT)
603 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
604 else if (player->MovDir == MV_UP)
605 graphic = GFX_SPIELER1_UP;
606 else /* MV_DOWN || MV_NO_MOVING */
607 graphic = GFX_SPIELER1_DOWN;
609 graphic += player->index_nr * 3 * HEROES_PER_LINE;
610 graphic += player->Frame;
615 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
616 sxx = player->GfxPos;
618 syy = player->GfxPos;
621 if (!setup.soft_scrolling && ScreenMovPos)
624 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
626 if (SHIELD_ON(player))
628 int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
629 GFX2_SHIELD_PASSIVE);
631 DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
632 3, 8, ANIM_OSCILLATE);
635 if (player->Pushing && player->GfxPos)
637 int px = SCREENX(next_jx), py = SCREENY(next_jy);
639 if (element == EL_SOKOBAN_FELD_LEER ||
640 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
641 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
645 int element = Feld[next_jx][next_jy];
646 int graphic = el2gfx(element);
648 if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK) && sxx)
650 int phase = (player->GfxPos / (TILEX / 4));
652 if (player->MovDir == MV_LEFT)
655 graphic += (phase + 4) % 4;
658 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
662 /* draw things in front of player (active dynamite or dynabombs) */
664 if (IS_ACTIVE_BOMB(element))
666 graphic = el2gfx(element);
668 if (element == EL_DYNAMITE_ACTIVE)
670 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
675 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
679 if (game.emulation == EMU_SUPAPLEX)
680 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
682 DrawGraphicThruMask(sx, sy, graphic + phase);
685 if (player_is_moving && last_element == EL_EXPLODING)
687 int phase = Frame[last_jx][last_jy];
691 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
692 GFX_EXPLOSION + ((phase - 1) / delay - 1));
695 /* draw elements that stay over the player */
696 /* handle the field the player is leaving ... */
697 if (player_is_moving && IS_OVER_PLAYER(last_element))
698 DrawLevelField(last_jx, last_jy);
699 /* ... and the field the player is entering */
700 if (IS_OVER_PLAYER(element))
701 DrawLevelField(jx, jy);
703 if (setup.direct_draw)
705 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
706 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
707 int x_size = TILEX * (1 + ABS(jx - last_jx));
708 int y_size = TILEY * (1 + ABS(jy - last_jy));
710 XCopyArea(display, drawto_field, window, gc,
711 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
712 SetDrawtoField(DRAW_DIRECT);
715 MarkTileDirty(sx,sy);
718 static int getGraphicAnimationPhase(int frames, int delay, int mode)
722 if (mode == ANIM_OSCILLATE)
724 int max_anim_frames = 2 * frames - 2;
725 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
726 phase = (phase < frames ? phase : max_anim_frames - phase);
729 phase = (FrameCounter % (delay * frames)) / delay;
731 if (mode == ANIM_REVERSE)
737 void DrawGraphicAnimationExt(int x, int y, int graphic,
738 int frames, int delay, int mode, int mask_mode)
740 int phase = getGraphicAnimationPhase(frames, delay, mode);
742 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
744 if (mask_mode == USE_MASKING)
745 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
747 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
751 void DrawGraphicAnimation(int x, int y, int graphic,
752 int frames, int delay, int mode)
754 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
757 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
758 int frames, int delay, int mode)
760 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
763 static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
766 int frames, int delay,
769 int phase = getGraphicAnimationPhase(frames, delay, mode);
771 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
774 void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y)
776 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
778 graphic -= GFX_START_ROCKSSCREEN;
779 *pixmap_nr = PIX_BACK;
780 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
781 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
783 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
785 graphic -= GFX_START_ROCKSHEROES;
786 *pixmap_nr = PIX_HEROES;
787 *x = (graphic % HEROES_PER_LINE) * TILEX;
788 *y = (graphic / HEROES_PER_LINE) * TILEY;
790 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
792 graphic -= GFX_START_ROCKSSP;
794 *x = (graphic % SP_PER_LINE) * TILEX;
795 *y = (graphic / SP_PER_LINE) * TILEY;
797 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
799 graphic -= GFX_START_ROCKSDC;
801 *x = (graphic % DC_PER_LINE) * TILEX;
802 *y = (graphic / DC_PER_LINE) * TILEY;
804 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
806 graphic -= GFX_START_ROCKSFONT;
807 *pixmap_nr = PIX_BIGFONT;
808 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
809 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
810 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
820 void DrawGraphic(int x, int y, int graphic)
823 if (!IN_SCR_FIELD(x,y))
825 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
826 printf("DrawGraphic(): This should never happen!\n");
831 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
835 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
840 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
841 XCopyArea(display, pix[pixmap_nr], d, gc,
842 src_x, src_y, TILEX, TILEY, x, y);
845 void DrawGraphicThruMask(int x, int y, int graphic)
848 if (!IN_SCR_FIELD(x,y))
850 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
851 printf("DrawGraphicThruMask(): This should never happen!\n");
856 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
860 void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
868 if (graphic == GFX_LEERRAUM)
871 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
872 src_pixmap = pix[pixmap_nr];
873 drawing_gc = clip_gc[pixmap_nr];
875 if (tile_clipmask[tile] != None)
877 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
878 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
879 XCopyArea(display, src_pixmap, d, tile_clip_gc,
880 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
885 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
888 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
889 XCopyArea(display, src_pixmap, d, drawing_gc,
890 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
894 void DrawMiniGraphic(int x, int y, int graphic)
896 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
897 MarkTileDirty(x/2, y/2);
900 void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y)
902 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
904 graphic -= GFX_START_ROCKSSCREEN;
905 *pixmap = pix[PIX_BACK];
906 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
907 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
909 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
911 graphic -= GFX_START_ROCKSSP;
912 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
913 *pixmap = pix[PIX_SP];
914 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
915 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
917 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
919 graphic -= GFX_START_ROCKSDC;
920 *pixmap = pix[PIX_DC];
921 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
922 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
924 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
926 graphic -= GFX_START_ROCKSFONT;
927 *pixmap = pix[PIX_SMALLFONT];
928 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
929 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
930 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
934 *pixmap = pix[PIX_SP];
940 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
945 getMiniGraphicSource(graphic, &pixmap, &src_x, &src_y);
946 XCopyArea(display, pixmap, d, gc,
947 src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
950 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
951 int cut_mode, int mask_mode)
953 int width = TILEX, height = TILEY;
955 int src_x, src_y, dest_x, dest_y;
963 DrawGraphic(x, y, graphic);
967 if (dx || dy) /* Verschiebung der Grafik? */
969 if (x < BX1) /* Element kommt von links ins Bild */
976 else if (x > BX2) /* Element kommt von rechts ins Bild */
982 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
988 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
990 else if (dx) /* allg. Bewegung in x-Richtung */
991 MarkTileDirty(x + SIGN(dx), y);
993 if (y < BY1) /* Element kommt von oben ins Bild */
995 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1003 else if (y > BY2) /* Element kommt von unten ins Bild */
1009 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1015 else if (dy > 0 && cut_mode == CUT_ABOVE)
1017 if (y == BY2) /* Element unterhalb des Bildes */
1023 MarkTileDirty(x, y + 1);
1024 } /* Element verläßt unten das Bild */
1025 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1027 else if (dy) /* allg. Bewegung in y-Richtung */
1028 MarkTileDirty(x, y + SIGN(dy));
1031 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
1032 src_pixmap = pix[pixmap_nr];
1033 drawing_gc = clip_gc[pixmap_nr];
1038 dest_x = FX + x * TILEX + dx;
1039 dest_y = FY + y * TILEY + dy;
1042 if (!IN_SCR_FIELD(x,y))
1044 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1045 printf("DrawGraphicShifted(): This should never happen!\n");
1050 if (mask_mode == USE_MASKING)
1052 if (tile_clipmask[tile] != None)
1054 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
1055 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
1056 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
1057 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1062 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1065 XSetClipOrigin(display, drawing_gc, dest_x - src_x, dest_y - src_y);
1066 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
1067 src_x, src_y, width, height, dest_x, dest_y);
1071 XCopyArea(display, src_pixmap, drawto_field, gc,
1072 src_x, src_y, width, height, dest_x, dest_y);
1077 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1080 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1083 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1084 int cut_mode, int mask_mode)
1086 int ux = LEVELX(x), uy = LEVELY(y);
1087 int graphic = el2gfx(element);
1088 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1089 int phase4 = phase8 / 2;
1090 int phase2 = phase8 / 4;
1091 int dir = MovDir[ux][uy];
1093 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1095 graphic += 4 * !phase2;
1099 else if (dir == MV_LEFT)
1101 else if (dir == MV_DOWN)
1104 else if (element == EL_SP_SNIKSNAK)
1107 graphic = GFX_SP_SNIKSNAK_LEFT;
1108 else if (dir == MV_RIGHT)
1109 graphic = GFX_SP_SNIKSNAK_RIGHT;
1110 else if (dir == MV_UP)
1111 graphic = GFX_SP_SNIKSNAK_UP;
1113 graphic = GFX_SP_SNIKSNAK_DOWN;
1115 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1117 else if (element == EL_SP_ELECTRON)
1119 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1121 else if (element == EL_MOLE || element == EL_PINGUIN ||
1122 element == EL_SCHWEIN || element == EL_DRACHE)
1125 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1126 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1127 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1128 else if (dir == MV_RIGHT)
1129 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1130 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1131 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1132 else if (dir == MV_UP)
1133 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1134 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1135 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1137 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1138 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1139 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1143 else if (element == EL_SONDE)
1145 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1147 else if (element == EL_SALZSAEURE)
1149 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1151 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1155 else if (element == EL_BALLOON)
1159 else if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK ||
1160 IS_GEM(element)) && !cut_mode)
1162 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1164 if (element == EL_FELSBROCKEN || element == EL_SP_ZONK)
1167 graphic += (4 - phase4) % 4;
1168 else if (dir == MV_RIGHT)
1171 graphic += phase2 * 2;
1173 else if (element != EL_SP_INFOTRON)
1177 else if (element == EL_SIEB_LEER || element == EL_SIEB2_LEER ||
1178 element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL)
1180 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1182 else if (IS_AMOEBOID(element))
1184 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1185 graphic += (x + 2 * y + 4) % 4;
1187 else if (element == EL_MAUER_LEBT)
1189 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1191 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1192 links_massiv = TRUE;
1193 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1194 rechts_massiv = TRUE;
1196 if (links_massiv && rechts_massiv)
1197 graphic = GFX_MAUERWERK;
1198 else if (links_massiv)
1199 graphic = GFX_MAUER_R;
1200 else if (rechts_massiv)
1201 graphic = GFX_MAUER_L;
1203 else if ((element == EL_INVISIBLE_STEEL ||
1204 element == EL_UNSICHTBAR ||
1205 element == EL_SAND_INVISIBLE) && game.light_time_left)
1207 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1208 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1209 GFX_SAND_INVISIBLE_ON);
1213 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1214 else if (mask_mode == USE_MASKING)
1215 DrawGraphicThruMask(x, y, graphic);
1217 DrawGraphic(x, y, graphic);
1220 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1221 int cut_mode, int mask_mode)
1223 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1224 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1225 cut_mode, mask_mode);
1228 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1231 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1234 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1237 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1240 void DrawScreenElementThruMask(int x, int y, int element)
1242 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1245 void DrawLevelElementThruMask(int x, int y, int element)
1247 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1250 void DrawLevelFieldThruMask(int x, int y)
1252 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1255 void ErdreichAnbroeckeln(int x, int y)
1257 int i, width, height, cx,cy;
1258 int ux = LEVELX(x), uy = LEVELY(y);
1259 int element, graphic;
1261 static int xy[4][2] =
1269 if (!IN_LEV_FIELD(ux, uy))
1272 element = Feld[ux][uy];
1274 if (element == EL_ERDREICH || element == EL_LANDMINE)
1276 if (!IN_SCR_FIELD(x, y))
1279 graphic = GFX_ERDENRAND;
1285 uxx = ux + xy[i][0];
1286 uyy = uy + xy[i][1];
1287 if (!IN_LEV_FIELD(uxx, uyy))
1290 element = Feld[uxx][uyy];
1292 if (element == EL_ERDREICH || element == EL_LANDMINE)
1295 if (i == 1 || i == 2)
1299 cx = (i == 2 ? TILEX - snip : 0);
1307 cy = (i == 3 ? TILEY - snip : 0);
1310 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1311 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1312 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1313 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1316 MarkTileDirty(x, y);
1320 graphic = GFX_ERDENRAND;
1324 int xx, yy, uxx, uyy;
1328 uxx = ux + xy[i][0];
1329 uyy = uy + xy[i][1];
1331 if (!IN_LEV_FIELD(uxx, uyy) ||
1332 (Feld[uxx][uyy] != EL_ERDREICH && Feld[uxx][uyy] != EL_LANDMINE) ||
1333 !IN_SCR_FIELD(xx, yy))
1336 if (i == 1 || i == 2)
1340 cx = (i == 1 ? TILEX - snip : 0);
1348 cy = (i==0 ? TILEY-snip : 0);
1351 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1352 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1353 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1354 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1356 MarkTileDirty(xx, yy);
1361 void DrawScreenElement(int x, int y, int element)
1363 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1364 ErdreichAnbroeckeln(x, y);
1367 void DrawLevelElement(int x, int y, int element)
1369 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1370 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1373 void DrawScreenField(int x, int y)
1375 int ux = LEVELX(x), uy = LEVELY(y);
1378 if (!IN_LEV_FIELD(ux, uy))
1380 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1381 element = EL_LEERRAUM;
1383 element = BorderElement;
1385 DrawScreenElement(x, y, element);
1389 element = Feld[ux][uy];
1391 if (IS_MOVING(ux, uy))
1393 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1394 boolean cut_mode = NO_CUTTING;
1396 if (Store[ux][uy] == EL_MORAST_LEER ||
1397 Store[ux][uy] == EL_SIEB_LEER ||
1398 Store[ux][uy] == EL_SIEB2_LEER ||
1399 Store[ux][uy] == EL_AMOEBE_NASS)
1400 cut_mode = CUT_ABOVE;
1401 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1402 Store[ux][uy] == EL_SIEB_VOLL ||
1403 Store[ux][uy] == EL_SIEB2_VOLL)
1404 cut_mode = CUT_BELOW;
1406 if (cut_mode == CUT_ABOVE)
1407 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1409 DrawScreenElement(x, y, EL_LEERRAUM);
1412 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1414 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1416 if (Store[ux][uy] == EL_SALZSAEURE)
1417 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1419 else if (IS_BLOCKED(ux, uy))
1424 boolean cut_mode = NO_CUTTING;
1426 Blocked2Moving(ux, uy, &oldx, &oldy);
1429 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1430 MovDir[oldx][oldy] == MV_RIGHT);
1432 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1433 Store[oldx][oldy] == EL_SIEB_LEER ||
1434 Store[oldx][oldy] == EL_SIEB2_LEER ||
1435 Store[oldx][oldy] == EL_AMOEBE_NASS)
1436 cut_mode = CUT_ABOVE;
1438 DrawScreenElement(x, y, EL_LEERRAUM);
1439 element = Feld[oldx][oldy];
1442 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1444 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1446 else if (IS_DRAWABLE(element))
1447 DrawScreenElement(x, y, element);
1449 DrawScreenElement(x, y, EL_LEERRAUM);
1452 void DrawLevelField(int x, int y)
1454 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1455 DrawScreenField(SCREENX(x), SCREENY(y));
1456 else if (IS_MOVING(x, y))
1460 Moving2Blocked(x, y, &newx, &newy);
1461 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1462 DrawScreenField(SCREENX(newx), SCREENY(newy));
1464 else if (IS_BLOCKED(x, y))
1468 Blocked2Moving(x, y, &oldx, &oldy);
1469 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1470 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1474 void DrawMiniElement(int x, int y, int element)
1480 DrawMiniGraphic(x, y, -1);
1484 graphic = el2gfx(element);
1485 DrawMiniGraphic(x, y, graphic);
1488 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1490 int x = sx + scroll_x, y = sy + scroll_y;
1492 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1493 DrawMiniElement(sx, sy, EL_LEERRAUM);
1494 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1495 DrawMiniElement(sx, sy, Feld[x][y]);
1498 int steel_type, steel_position;
1501 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1502 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1503 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1504 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1505 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1506 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1509 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1510 steel_position = (x == -1 && y == -1 ? 0 :
1511 x == lev_fieldx && y == -1 ? 1 :
1512 x == -1 && y == lev_fieldy ? 2 :
1513 x == lev_fieldx && y == lev_fieldy ? 3 :
1514 x == -1 || x == lev_fieldx ? 4 :
1515 y == -1 || y == lev_fieldy ? 5 : -1);
1517 if (steel_position != -1)
1518 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1522 void DrawMicroElement(int xpos, int ypos, int element)
1526 if (element == EL_LEERRAUM)
1529 graphic = el2gfx(element);
1531 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1533 graphic -= GFX_START_ROCKSSP;
1534 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1535 XCopyArea(display, pix[PIX_SP], drawto, gc,
1536 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1537 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1538 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1540 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1542 graphic -= GFX_START_ROCKSDC;
1543 XCopyArea(display, pix[PIX_DC], drawto, gc,
1544 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1545 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1546 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1549 XCopyArea(display, pix[PIX_BACK], drawto, gc,
1550 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1551 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1552 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1561 for(x=BX1; x<=BX2; x++)
1562 for(y=BY1; y<=BY2; y++)
1563 DrawScreenField(x, y);
1565 redraw_mask |= REDRAW_FIELD;
1568 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1572 for(x=0; x<size_x; x++)
1573 for(y=0; y<size_y; y++)
1574 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1576 redraw_mask |= REDRAW_FIELD;
1579 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1583 XFillRectangle(display, drawto, gc,
1584 xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1586 if (lev_fieldx < STD_LEV_FIELDX)
1587 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1588 if (lev_fieldy < STD_LEV_FIELDY)
1589 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1591 xpos += MICRO_TILEX;
1592 ypos += MICRO_TILEY;
1594 for(x=-1; x<=STD_LEV_FIELDX; x++)
1596 for(y=-1; y<=STD_LEV_FIELDY; y++)
1598 int lx = from_x + x, ly = from_y + y;
1600 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1601 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1603 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1604 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1609 redraw_mask |= REDRAW_MICROLEVEL;
1612 #define MICROLABEL_EMPTY 0
1613 #define MICROLABEL_LEVEL_NAME 1
1614 #define MICROLABEL_CREATED_BY 2
1615 #define MICROLABEL_LEVEL_AUTHOR 3
1616 #define MICROLABEL_IMPORTED_FROM 4
1617 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1619 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1621 static void DrawMicroLevelLabelExt(int mode)
1623 char label_text[MAX_MICROLABEL_SIZE + 1];
1625 XFillRectangle(display, drawto,gc,
1626 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1628 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1629 mode == MICROLABEL_CREATED_BY ? "created by" :
1630 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1631 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1632 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1633 leveldir[leveldir_nr].imported_from : ""),
1634 MAX_MICROLABEL_SIZE);
1635 label_text[MAX_MICROLABEL_SIZE] = '\0';
1637 if (strlen(label_text) > 0)
1639 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1640 int lypos = MICROLABEL_YPOS;
1642 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1645 redraw_mask |= REDRAW_MICROLEVEL;
1648 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1650 static unsigned long scroll_delay = 0;
1651 static unsigned long label_delay = 0;
1652 static int from_x, from_y, scroll_direction;
1653 static int label_state, label_counter;
1657 from_x = from_y = 0;
1658 scroll_direction = MV_RIGHT;
1662 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1663 DrawMicroLevelLabelExt(label_state);
1665 /* initialize delay counters */
1666 DelayReached(&scroll_delay, 0);
1667 DelayReached(&label_delay, 0);
1672 /* scroll micro level, if needed */
1673 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1674 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1676 switch (scroll_direction)
1682 scroll_direction = MV_UP;
1686 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1689 scroll_direction = MV_DOWN;
1696 scroll_direction = MV_RIGHT;
1700 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1703 scroll_direction = MV_LEFT;
1710 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1713 /* redraw micro level label, if needed */
1714 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1715 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1716 strcmp(level.author, leveldir[leveldir_nr].name) != 0 &&
1717 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1719 int max_label_counter = 23;
1721 if (leveldir[leveldir_nr].imported_from != NULL)
1722 max_label_counter += 14;
1724 label_counter = (label_counter + 1) % max_label_counter;
1725 label_state = (label_counter >= 0 && label_counter <= 7 ?
1726 MICROLABEL_LEVEL_NAME :
1727 label_counter >= 9 && label_counter <= 12 ?
1728 MICROLABEL_CREATED_BY :
1729 label_counter >= 14 && label_counter <= 21 ?
1730 MICROLABEL_LEVEL_AUTHOR :
1731 label_counter >= 23 && label_counter <= 26 ?
1732 MICROLABEL_IMPORTED_FROM :
1733 label_counter >= 28 && label_counter <= 35 ?
1734 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1735 DrawMicroLevelLabelExt(label_state);
1739 int REQ_in_range(int x, int y)
1741 if (y > DY+249 && y < DY+278)
1743 if (x > DX+1 && x < DX+48)
1745 else if (x > DX+51 && x < DX+98)
1751 boolean Request(char *text, unsigned int req_state)
1753 int mx, my, ty, result = -1;
1754 unsigned int old_door_state;
1757 /* pause network game while waiting for request to answer */
1758 if (options.network &&
1759 game_status == PLAYING &&
1760 req_state & REQUEST_WAIT_FOR)
1761 SendToServer_PausePlaying();
1764 old_door_state = GetDoorState();
1768 CloseDoor(DOOR_CLOSE_1);
1770 /* save old door content */
1771 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
1772 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1773 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1775 /* clear door drawing field */
1776 XFillRectangle(display, drawto, gc, DX, DY, DXSIZE, DYSIZE);
1778 /* write text for request */
1779 for(ty=0; ty<13; ty++)
1787 for(tl=0,tx=0; tx<7; tl++,tx++)
1790 if (!tc || tc == 32)
1801 DrawTextExt(drawto, gc,
1802 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1803 txt, FS_SMALL, FC_YELLOW);
1804 text += tl + (tc == 32 ? 1 : 0);
1807 if (req_state & REQ_ASK)
1809 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1810 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1812 else if (req_state & REQ_CONFIRM)
1814 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1816 else if (req_state & REQ_PLAYER)
1818 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1819 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1820 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1821 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1824 /* copy request gadgets to door backbuffer */
1825 XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
1826 DX, DY, DXSIZE, DYSIZE,
1827 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1829 OpenDoor(DOOR_OPEN_1);
1835 if (!(req_state & REQUEST_WAIT_FOR))
1838 if (game_status != MAINMENU)
1841 button_status = MB_RELEASED;
1843 request_gadget_id = -1;
1847 if (XPending(display))
1851 XNextEvent(display, &event);
1859 if (event.type == MotionNotify)
1866 if (!XQueryPointer(display, window, &root, &child,
1867 &root_x, &root_y, &win_x, &win_y, &mask))
1873 motion_status = TRUE;
1874 mx = ((XMotionEvent *) &event)->x;
1875 my = ((XMotionEvent *) &event)->y;
1879 motion_status = FALSE;
1880 mx = ((XButtonEvent *) &event)->x;
1881 my = ((XButtonEvent *) &event)->y;
1882 if (event.type==ButtonPress)
1883 button_status = ((XButtonEvent *) &event)->button;
1885 button_status = MB_RELEASED;
1888 /* this sets 'request_gadget_id' */
1889 HandleGadgets(mx, my, button_status);
1891 switch(request_gadget_id)
1893 case TOOL_CTRL_ID_YES:
1896 case TOOL_CTRL_ID_NO:
1899 case TOOL_CTRL_ID_CONFIRM:
1900 result = TRUE | FALSE;
1903 case TOOL_CTRL_ID_PLAYER_1:
1906 case TOOL_CTRL_ID_PLAYER_2:
1909 case TOOL_CTRL_ID_PLAYER_3:
1912 case TOOL_CTRL_ID_PLAYER_4:
1924 switch(XLookupKeysym((XKeyEvent *)&event,
1925 ((XKeyEvent *)&event)->state))
1938 if (req_state & REQ_PLAYER)
1943 key_joystick_mapping = 0;
1947 HandleOtherEvents(&event);
1951 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1953 int joy = AnyJoystick();
1955 if (joy & JOY_BUTTON_1)
1957 else if (joy & JOY_BUTTON_2)
1963 /* don't eat all CPU time */
1967 if (game_status != MAINMENU)
1972 if (!(req_state & REQ_STAY_OPEN))
1974 CloseDoor(DOOR_CLOSE_1);
1976 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1978 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1979 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1980 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1981 OpenDoor(DOOR_OPEN_1);
1988 /* continue network game after request */
1989 if (options.network &&
1990 game_status == PLAYING &&
1991 req_state & REQUEST_WAIT_FOR)
1992 SendToServer_ContinuePlaying();
1998 unsigned int OpenDoor(unsigned int door_state)
2000 unsigned int new_door_state;
2002 if (door_state & DOOR_COPY_BACK)
2004 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
2005 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2006 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2007 door_state &= ~DOOR_COPY_BACK;
2010 new_door_state = MoveDoor(door_state);
2012 return(new_door_state);
2015 unsigned int CloseDoor(unsigned int door_state)
2017 unsigned int new_door_state;
2019 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
2020 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2021 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
2022 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2024 new_door_state = MoveDoor(door_state);
2026 return(new_door_state);
2029 unsigned int GetDoorState()
2031 return(MoveDoor(DOOR_GET_STATE));
2034 unsigned int MoveDoor(unsigned int door_state)
2036 static int door1 = DOOR_OPEN_1;
2037 static int door2 = DOOR_CLOSE_2;
2038 static unsigned long door_delay = 0;
2039 int x, start, stepsize = 2;
2040 unsigned long door_delay_value = stepsize * 5;
2042 if (door_state == DOOR_GET_STATE)
2043 return(door1 | door2);
2045 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2046 door_state &= ~DOOR_OPEN_1;
2047 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2048 door_state &= ~DOOR_CLOSE_1;
2049 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2050 door_state &= ~DOOR_OPEN_2;
2051 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2052 door_state &= ~DOOR_CLOSE_2;
2054 if (setup.quick_doors)
2057 door_delay_value = 0;
2058 StopSound(SND_OEFFNEN);
2061 if (door_state & DOOR_ACTION)
2063 if (!(door_state & DOOR_NO_DELAY))
2064 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2066 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2068 for(x=start; x<=DXSIZE; x+=stepsize)
2070 WaitUntilDelayReached(&door_delay, door_delay_value);
2072 if (door_state & DOOR_ACTION_1)
2074 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2075 int j = (DXSIZE - i) / 3;
2077 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
2078 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2079 DXSIZE,DYSIZE - i/2, DX, DY);
2081 XFillRectangle(display, drawto, gc, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2083 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2084 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2085 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
2086 DXSIZE, DOOR_GFX_PAGEY1, i, 77, DX + DXSIZE - i, DY + j);
2087 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2088 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63, DX + DXSIZE - i,
2090 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2091 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2092 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2093 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j, DX, DY);
2094 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2095 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63, DX, DY + 140 - j);
2097 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2098 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2100 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2101 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2103 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2104 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2105 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2106 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2107 DX + DXSIZE - i, DY + 77 + j);
2108 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2109 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2110 DX + DXSIZE - i, DY + 203 + j);
2112 redraw_mask |= REDRAW_DOOR_1;
2115 if (door_state & DOOR_ACTION_2)
2117 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2118 int j = (VXSIZE - i) / 3;
2120 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
2121 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2122 VXSIZE, VYSIZE - i/2, VX, VY);
2124 XFillRectangle(display, drawto, gc, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2126 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2127 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2128 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2129 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2, VX + VXSIZE-i, VY+j);
2130 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2131 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2132 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
2133 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j, VX, VY);
2135 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2136 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2,
2137 VX, VY + VYSIZE / 2 - j);
2138 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2139 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2140 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2141 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2 - j,
2142 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2144 redraw_mask |= REDRAW_DOOR_2;
2149 if (game_status == MAINMENU)
2154 if (setup.quick_doors)
2155 StopSound(SND_OEFFNEN);
2157 if (door_state & DOOR_ACTION_1)
2158 door1 = door_state & DOOR_ACTION_1;
2159 if (door_state & DOOR_ACTION_2)
2160 door2 = door_state & DOOR_ACTION_2;
2162 return (door1 | door2);
2165 void DrawSpecialEditorDoor()
2167 /* draw bigger toolbox window */
2168 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
2169 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2171 redraw_mask |= REDRAW_ALL;
2174 void UndrawSpecialEditorDoor()
2176 /* draw normal tape recorder window */
2177 XCopyArea(display, pix[PIX_BACK], drawto, gc,
2178 562, 344, 108, 56, EX - 4, EY - 12);
2180 redraw_mask |= REDRAW_ALL;
2183 int ReadPixel(Drawable d, int x, int y)
2185 XImage *pixel_image;
2186 unsigned long pixel_value;
2188 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
2189 pixel_value = XGetPixel(pixel_image, 0, 0);
2191 XDestroyImage(pixel_image);
2196 /* ---------- new tool button stuff ---------------------------------------- */
2198 /* graphic position values for tool buttons */
2199 #define TOOL_BUTTON_YES_XPOS 2
2200 #define TOOL_BUTTON_YES_YPOS 250
2201 #define TOOL_BUTTON_YES_GFX_YPOS 0
2202 #define TOOL_BUTTON_YES_XSIZE 46
2203 #define TOOL_BUTTON_YES_YSIZE 28
2204 #define TOOL_BUTTON_NO_XPOS 52
2205 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2206 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2207 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2208 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2209 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2210 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2211 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2212 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2213 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2214 #define TOOL_BUTTON_PLAYER_XSIZE 30
2215 #define TOOL_BUTTON_PLAYER_YSIZE 30
2216 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2217 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2218 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2219 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2220 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2221 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2222 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2223 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2224 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2225 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2226 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2227 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2228 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2229 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2230 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2231 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2232 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2233 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2234 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2235 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2244 } toolbutton_info[NUM_TOOL_BUTTONS] =
2247 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2248 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2249 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2254 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2255 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2256 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2261 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2262 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2263 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2264 TOOL_CTRL_ID_CONFIRM,
2268 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2269 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2270 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2271 TOOL_CTRL_ID_PLAYER_1,
2275 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2276 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2277 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2278 TOOL_CTRL_ID_PLAYER_2,
2282 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2283 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2284 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2285 TOOL_CTRL_ID_PLAYER_3,
2289 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2290 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2291 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2292 TOOL_CTRL_ID_PLAYER_4,
2297 static void DoNotDisplayInfoText(void *ptr)
2302 void CreateToolButtons()
2306 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2308 Pixmap gd_pixmap = pix[PIX_DOOR];
2309 Pixmap deco_pixmap = None;
2310 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2311 struct GadgetInfo *gi;
2312 unsigned long event_mask;
2313 int gd_xoffset, gd_yoffset;
2314 int gd_x1, gd_x2, gd_y;
2317 event_mask = GD_EVENT_RELEASED;
2319 gd_xoffset = toolbutton_info[i].xpos;
2320 gd_yoffset = toolbutton_info[i].ypos;
2321 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2322 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2323 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2325 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2327 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2328 &deco_pixmap, &deco_x, &deco_y);
2329 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2330 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2333 gi = CreateGadget(GDI_CUSTOM_ID, id,
2334 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2335 GDI_X, DX + toolbutton_info[i].x,
2336 GDI_Y, DY + toolbutton_info[i].y,
2337 GDI_WIDTH, toolbutton_info[i].width,
2338 GDI_HEIGHT, toolbutton_info[i].height,
2339 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2340 GDI_STATE, GD_BUTTON_UNPRESSED,
2341 GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
2342 GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
2343 GDI_DECORATION_DESIGN, deco_pixmap, deco_x, deco_y,
2344 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2345 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2346 GDI_DECORATION_SHIFTING, 1, 1,
2347 GDI_EVENT_MASK, event_mask,
2348 GDI_CALLBACK_ACTION, HandleToolButtons,
2349 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2353 Error(ERR_EXIT, "cannot create gadget");
2355 tool_gadget[id] = gi;
2359 static void UnmapToolButtons()
2363 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2364 UnmapGadget(tool_gadget[i]);
2367 static void HandleToolButtons(struct GadgetInfo *gi)
2369 request_gadget_id = gi->custom_id;
2372 int el2gfx(int element)
2376 case EL_LEERRAUM: return -1;
2377 case EL_ERDREICH: return GFX_ERDREICH;
2378 case EL_MAUERWERK: return GFX_MAUERWERK;
2379 case EL_FELSBODEN: return GFX_FELSBODEN;
2380 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2381 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2382 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2383 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2384 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2385 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2386 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2387 case EL_SPIELER1: return GFX_SPIELER1;
2388 case EL_SPIELER2: return GFX_SPIELER2;
2389 case EL_SPIELER3: return GFX_SPIELER3;
2390 case EL_SPIELER4: return GFX_SPIELER4;
2391 case EL_KAEFER: return GFX_KAEFER;
2392 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2393 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2394 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2395 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2396 case EL_FLIEGER: return GFX_FLIEGER;
2397 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2398 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2399 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2400 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2401 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2402 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2403 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2404 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2405 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2406 case EL_FIREFLY: return GFX_FIREFLY;
2407 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2408 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2409 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2410 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2411 case EL_MAMPFER: return GFX_MAMPFER;
2412 case EL_ROBOT: return GFX_ROBOT;
2413 case EL_BETON: return GFX_BETON;
2414 case EL_DIAMANT: return GFX_DIAMANT;
2415 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2416 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2417 case EL_TROPFEN: return GFX_TROPFEN;
2418 case EL_BOMBE: return GFX_BOMBE;
2419 case EL_SIEB_INAKTIV: return GFX_SIEB_INAKTIV;
2420 case EL_SIEB_LEER: return GFX_SIEB_LEER;
2421 case EL_SIEB_VOLL: return GFX_SIEB_VOLL;
2422 case EL_SIEB_TOT: return GFX_SIEB_TOT;
2423 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2424 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2425 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2426 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2427 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2428 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2429 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2430 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2431 case EL_LIFE: return GFX_LIFE;
2432 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2433 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2434 case EL_BADEWANNE: return GFX_BADEWANNE;
2435 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2436 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2437 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2438 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2439 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2440 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2441 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2442 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2443 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2444 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2445 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2446 case EL_PFORTE1: return GFX_PFORTE1;
2447 case EL_PFORTE2: return GFX_PFORTE2;
2448 case EL_PFORTE3: return GFX_PFORTE3;
2449 case EL_PFORTE4: return GFX_PFORTE4;
2450 case EL_PFORTE1X: return GFX_PFORTE1X;
2451 case EL_PFORTE2X: return GFX_PFORTE2X;
2452 case EL_PFORTE3X: return GFX_PFORTE3X;
2453 case EL_PFORTE4X: return GFX_PFORTE4X;
2454 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2455 case EL_PACMAN: return GFX_PACMAN;
2456 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2457 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2458 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2459 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2460 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2461 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2462 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2463 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2464 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2465 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2466 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2467 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2468 case EL_MAUER_X: return GFX_MAUER_X;
2469 case EL_MAUER_Y: return GFX_MAUER_Y;
2470 case EL_MAUER_XY: return GFX_MAUER_XY;
2471 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2472 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2473 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2474 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2475 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2476 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2477 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2478 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2479 case EL_MAMPFER2: return GFX_MAMPFER2;
2480 case EL_SIEB2_INAKTIV: return GFX_SIEB2_INAKTIV;
2481 case EL_SIEB2_LEER: return GFX_SIEB2_LEER;
2482 case EL_SIEB2_VOLL: return GFX_SIEB2_VOLL;
2483 case EL_SIEB2_TOT: return GFX_SIEB2_TOT;
2484 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2485 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2486 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2487 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2488 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2489 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2490 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2491 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2492 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2493 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2494 case EL_MOLE: return GFX_MOLE;
2495 case EL_PINGUIN: return GFX_PINGUIN;
2496 case EL_SCHWEIN: return GFX_SCHWEIN;
2497 case EL_DRACHE: return GFX_DRACHE;
2498 case EL_SONDE: return GFX_SONDE;
2499 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2500 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2501 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2502 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2503 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2504 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2505 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2506 case EL_SP_ZONK: return GFX_SP_ZONK;
2507 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2508 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2509 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2510 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2511 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2512 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2513 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2514 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2515 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2516 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2517 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2518 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2519 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2520 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2521 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2522 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2523 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2524 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2525 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2526 case EL_PEARL: return GFX_PEARL;
2527 case EL_CRYSTAL: return GFX_CRYSTAL;
2528 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2529 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2530 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2531 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2532 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2533 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2534 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2535 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2536 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2537 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2538 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2539 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2540 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2541 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2542 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2543 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2544 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2545 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2546 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2547 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2548 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2549 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2550 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2551 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2552 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2553 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2554 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2555 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2556 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2557 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2558 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2559 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2560 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2561 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2562 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2563 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2564 case EL_LANDMINE: return GFX_LANDMINE;
2565 case EL_ENVELOPE: return GFX_ENVELOPE;
2566 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2567 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2568 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2569 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2570 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2571 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2572 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2573 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2574 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2575 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2576 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2577 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2578 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2579 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2580 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2581 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2582 case EL_MOLE_UP: return GFX_MOLE_UP;
2583 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2584 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2585 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2586 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2587 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2588 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2589 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2590 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2591 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2592 case EL_BALLOON: return GFX_BALLOON;
2593 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2594 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2595 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2596 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2597 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2598 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2599 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2600 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2601 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2602 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2603 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2604 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2605 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2606 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2607 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2608 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2609 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2613 if (IS_CHAR(element))
2614 return GFX_CHAR_START + (element - EL_CHAR_START);
2615 else if (element >= EL_SP_START && element <= EL_SP_END)
2617 int nr_element = element - EL_SP_START;
2618 int gfx_per_line = 8;
2620 (nr_element / gfx_per_line) * SP_PER_LINE +
2621 (nr_element % gfx_per_line);
2623 return GFX_START_ROCKSSP + nr_graphic;