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_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
806 graphic -= GFX_START_ROCKSMORE;
807 *pixmap_nr = PIX_MORE;
808 *x = (graphic % MORE_PER_LINE) * TILEX;
809 *y = (graphic / MORE_PER_LINE) * TILEY;
811 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
813 graphic -= GFX_START_ROCKSFONT;
814 *pixmap_nr = PIX_BIGFONT;
815 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
816 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
817 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
827 void DrawGraphic(int x, int y, int graphic)
830 if (!IN_SCR_FIELD(x,y))
832 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
833 printf("DrawGraphic(): This should never happen!\n");
838 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
842 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
847 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
848 XCopyArea(display, pix[pixmap_nr], d, gc,
849 src_x, src_y, TILEX, TILEY, x, y);
852 void DrawGraphicThruMask(int x, int y, int graphic)
855 if (!IN_SCR_FIELD(x,y))
857 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
858 printf("DrawGraphicThruMask(): This should never happen!\n");
863 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
867 void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
875 if (graphic == GFX_LEERRAUM)
878 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
879 src_pixmap = pix[pixmap_nr];
880 drawing_gc = clip_gc[pixmap_nr];
882 if (tile_clipmask[tile] != None)
884 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
885 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
886 XCopyArea(display, src_pixmap, d, tile_clip_gc,
887 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
892 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
895 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
896 XCopyArea(display, src_pixmap, d, drawing_gc,
897 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
901 void DrawMiniGraphic(int x, int y, int graphic)
903 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
904 MarkTileDirty(x/2, y/2);
907 void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y)
909 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
911 graphic -= GFX_START_ROCKSSCREEN;
912 *pixmap = pix[PIX_BACK];
913 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
914 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
916 else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
918 graphic -= GFX_START_ROCKSSP;
919 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
920 *pixmap = pix[PIX_SP];
921 *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
922 *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
924 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
926 graphic -= GFX_START_ROCKSDC;
927 *pixmap = pix[PIX_DC];
928 *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
929 *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
931 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
933 graphic -= GFX_START_ROCKSMORE;
934 *pixmap = pix[PIX_MORE];
935 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
936 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
938 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
940 graphic -= GFX_START_ROCKSFONT;
941 *pixmap = pix[PIX_SMALLFONT];
942 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
943 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
944 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
948 *pixmap = pix[PIX_SP];
954 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
959 getMiniGraphicSource(graphic, &pixmap, &src_x, &src_y);
960 XCopyArea(display, pixmap, d, gc,
961 src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
964 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
965 int cut_mode, int mask_mode)
967 int width = TILEX, height = TILEY;
969 int src_x, src_y, dest_x, dest_y;
977 DrawGraphic(x, y, graphic);
981 if (dx || dy) /* Verschiebung der Grafik? */
983 if (x < BX1) /* Element kommt von links ins Bild */
990 else if (x > BX2) /* Element kommt von rechts ins Bild */
996 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1002 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1004 else if (dx) /* allg. Bewegung in x-Richtung */
1005 MarkTileDirty(x + SIGN(dx), y);
1007 if (y < BY1) /* Element kommt von oben ins Bild */
1009 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1017 else if (y > BY2) /* Element kommt von unten ins Bild */
1023 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1029 else if (dy > 0 && cut_mode == CUT_ABOVE)
1031 if (y == BY2) /* Element unterhalb des Bildes */
1037 MarkTileDirty(x, y + 1);
1038 } /* Element verläßt unten das Bild */
1039 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1041 else if (dy) /* allg. Bewegung in y-Richtung */
1042 MarkTileDirty(x, y + SIGN(dy));
1045 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
1046 src_pixmap = pix[pixmap_nr];
1047 drawing_gc = clip_gc[pixmap_nr];
1052 dest_x = FX + x * TILEX + dx;
1053 dest_y = FY + y * TILEY + dy;
1056 if (!IN_SCR_FIELD(x,y))
1058 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1059 printf("DrawGraphicShifted(): This should never happen!\n");
1064 if (mask_mode == USE_MASKING)
1066 if (tile_clipmask[tile] != None)
1068 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
1069 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
1070 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
1071 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1076 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1079 XSetClipOrigin(display, drawing_gc, dest_x - src_x, dest_y - src_y);
1080 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
1081 src_x, src_y, width, height, dest_x, dest_y);
1085 XCopyArea(display, src_pixmap, drawto_field, gc,
1086 src_x, src_y, width, height, dest_x, dest_y);
1091 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1094 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1097 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1098 int cut_mode, int mask_mode)
1100 int ux = LEVELX(x), uy = LEVELY(y);
1101 int graphic = el2gfx(element);
1102 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1103 int phase4 = phase8 / 2;
1104 int phase2 = phase8 / 4;
1105 int dir = MovDir[ux][uy];
1107 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1109 graphic += 4 * !phase2;
1113 else if (dir == MV_LEFT)
1115 else if (dir == MV_DOWN)
1118 else if (element == EL_SP_SNIKSNAK)
1121 graphic = GFX_SP_SNIKSNAK_LEFT;
1122 else if (dir == MV_RIGHT)
1123 graphic = GFX_SP_SNIKSNAK_RIGHT;
1124 else if (dir == MV_UP)
1125 graphic = GFX_SP_SNIKSNAK_UP;
1127 graphic = GFX_SP_SNIKSNAK_DOWN;
1129 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1131 else if (element == EL_SP_ELECTRON)
1133 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1135 else if (element == EL_MOLE || element == EL_PINGUIN ||
1136 element == EL_SCHWEIN || element == EL_DRACHE)
1139 graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
1140 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1141 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1142 else if (dir == MV_RIGHT)
1143 graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
1144 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1145 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1146 else if (dir == MV_UP)
1147 graphic = (element == EL_MOLE ? GFX_MOLE_UP :
1148 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1149 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1151 graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
1152 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1153 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1157 else if (element == EL_SONDE)
1159 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1161 else if (element == EL_SALZSAEURE)
1163 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1165 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1169 else if (element == EL_BALLOON)
1173 else if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK ||
1174 IS_GEM(element)) && !cut_mode)
1176 if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
1178 if (element == EL_FELSBROCKEN || element == EL_SP_ZONK)
1181 graphic += (4 - phase4) % 4;
1182 else if (dir == MV_RIGHT)
1185 graphic += phase2 * 2;
1187 else if (element != EL_SP_INFOTRON)
1191 else if (element == EL_SIEB_LEER || element == EL_SIEB2_LEER ||
1192 element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL)
1194 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1196 else if (IS_AMOEBOID(element))
1198 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1199 graphic += (x + 2 * y + 4) % 4;
1201 else if (element == EL_MAUER_LEBT)
1203 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1205 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1206 links_massiv = TRUE;
1207 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1208 rechts_massiv = TRUE;
1210 if (links_massiv && rechts_massiv)
1211 graphic = GFX_MAUERWERK;
1212 else if (links_massiv)
1213 graphic = GFX_MAUER_R;
1214 else if (rechts_massiv)
1215 graphic = GFX_MAUER_L;
1217 else if ((element == EL_INVISIBLE_STEEL ||
1218 element == EL_UNSICHTBAR ||
1219 element == EL_SAND_INVISIBLE) && game.light_time_left)
1221 graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
1222 element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
1223 GFX_SAND_INVISIBLE_ON);
1227 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1228 else if (mask_mode == USE_MASKING)
1229 DrawGraphicThruMask(x, y, graphic);
1231 DrawGraphic(x, y, graphic);
1234 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1235 int cut_mode, int mask_mode)
1237 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1238 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1239 cut_mode, mask_mode);
1242 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1245 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1248 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1251 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1254 void DrawScreenElementThruMask(int x, int y, int element)
1256 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1259 void DrawLevelElementThruMask(int x, int y, int element)
1261 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1264 void DrawLevelFieldThruMask(int x, int y)
1266 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1269 void ErdreichAnbroeckeln(int x, int y)
1271 int i, width, height, cx,cy;
1272 int ux = LEVELX(x), uy = LEVELY(y);
1273 int element, graphic;
1275 static int xy[4][2] =
1283 if (!IN_LEV_FIELD(ux, uy))
1286 element = Feld[ux][uy];
1288 if (element == EL_ERDREICH ||
1289 element == EL_LANDMINE ||
1290 element == EL_TRAP_INACTIVE ||
1291 element == EL_TRAP_ACTIVE)
1293 if (!IN_SCR_FIELD(x, y))
1296 graphic = GFX_ERDENRAND;
1302 uxx = ux + xy[i][0];
1303 uyy = uy + xy[i][1];
1304 if (!IN_LEV_FIELD(uxx, uyy))
1307 element = Feld[uxx][uyy];
1309 if (element == EL_ERDREICH ||
1310 element == EL_LANDMINE ||
1311 element == EL_TRAP_INACTIVE ||
1312 element == EL_TRAP_ACTIVE)
1315 if (i == 1 || i == 2)
1319 cx = (i == 2 ? TILEX - snip : 0);
1327 cy = (i == 3 ? TILEY - snip : 0);
1330 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1331 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1332 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1333 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1336 MarkTileDirty(x, y);
1340 graphic = GFX_ERDENRAND;
1344 int xx, yy, uxx, uyy;
1348 uxx = ux + xy[i][0];
1349 uyy = uy + xy[i][1];
1351 if (!IN_LEV_FIELD(uxx, uyy) ||
1352 (Feld[uxx][uyy] != EL_ERDREICH &&
1353 Feld[uxx][uyy] != EL_LANDMINE &&
1354 Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
1355 Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
1356 !IN_SCR_FIELD(xx, yy))
1359 if (i == 1 || i == 2)
1363 cx = (i == 1 ? TILEX - snip : 0);
1371 cy = (i==0 ? TILEY-snip : 0);
1374 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1375 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1376 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1377 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1379 MarkTileDirty(xx, yy);
1384 void DrawScreenElement(int x, int y, int element)
1386 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1387 ErdreichAnbroeckeln(x, y);
1390 void DrawLevelElement(int x, int y, int element)
1392 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1393 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1396 void DrawScreenField(int x, int y)
1398 int ux = LEVELX(x), uy = LEVELY(y);
1401 if (!IN_LEV_FIELD(ux, uy))
1403 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1404 element = EL_LEERRAUM;
1406 element = BorderElement;
1408 DrawScreenElement(x, y, element);
1412 element = Feld[ux][uy];
1414 if (IS_MOVING(ux, uy))
1416 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1417 boolean cut_mode = NO_CUTTING;
1419 if (Store[ux][uy] == EL_MORAST_LEER ||
1420 Store[ux][uy] == EL_SIEB_LEER ||
1421 Store[ux][uy] == EL_SIEB2_LEER ||
1422 Store[ux][uy] == EL_AMOEBE_NASS)
1423 cut_mode = CUT_ABOVE;
1424 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1425 Store[ux][uy] == EL_SIEB_VOLL ||
1426 Store[ux][uy] == EL_SIEB2_VOLL)
1427 cut_mode = CUT_BELOW;
1429 if (cut_mode == CUT_ABOVE)
1430 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1432 DrawScreenElement(x, y, EL_LEERRAUM);
1435 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1437 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1439 if (Store[ux][uy] == EL_SALZSAEURE)
1440 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1442 else if (IS_BLOCKED(ux, uy))
1447 boolean cut_mode = NO_CUTTING;
1449 Blocked2Moving(ux, uy, &oldx, &oldy);
1452 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1453 MovDir[oldx][oldy] == MV_RIGHT);
1455 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1456 Store[oldx][oldy] == EL_SIEB_LEER ||
1457 Store[oldx][oldy] == EL_SIEB2_LEER ||
1458 Store[oldx][oldy] == EL_AMOEBE_NASS)
1459 cut_mode = CUT_ABOVE;
1461 DrawScreenElement(x, y, EL_LEERRAUM);
1462 element = Feld[oldx][oldy];
1465 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1467 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1469 else if (IS_DRAWABLE(element))
1470 DrawScreenElement(x, y, element);
1472 DrawScreenElement(x, y, EL_LEERRAUM);
1475 void DrawLevelField(int x, int y)
1477 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1478 DrawScreenField(SCREENX(x), SCREENY(y));
1479 else if (IS_MOVING(x, y))
1483 Moving2Blocked(x, y, &newx, &newy);
1484 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1485 DrawScreenField(SCREENX(newx), SCREENY(newy));
1487 else if (IS_BLOCKED(x, y))
1491 Blocked2Moving(x, y, &oldx, &oldy);
1492 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1493 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1497 void DrawMiniElement(int x, int y, int element)
1503 DrawMiniGraphic(x, y, -1);
1507 graphic = el2gfx(element);
1508 DrawMiniGraphic(x, y, graphic);
1511 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1513 int x = sx + scroll_x, y = sy + scroll_y;
1515 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1516 DrawMiniElement(sx, sy, EL_LEERRAUM);
1517 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1518 DrawMiniElement(sx, sy, Feld[x][y]);
1521 int steel_type, steel_position;
1524 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1525 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1526 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1527 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1528 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1529 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1532 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1533 steel_position = (x == -1 && y == -1 ? 0 :
1534 x == lev_fieldx && y == -1 ? 1 :
1535 x == -1 && y == lev_fieldy ? 2 :
1536 x == lev_fieldx && y == lev_fieldy ? 3 :
1537 x == -1 || x == lev_fieldx ? 4 :
1538 y == -1 || y == lev_fieldy ? 5 : -1);
1540 if (steel_position != -1)
1541 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1545 void DrawMicroElement(int xpos, int ypos, int element)
1549 if (element == EL_LEERRAUM)
1552 graphic = el2gfx(element);
1554 if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
1556 graphic -= GFX_START_ROCKSSP;
1557 graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
1558 XCopyArea(display, pix[PIX_SP], drawto, gc,
1559 MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
1560 MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
1561 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1563 else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
1565 graphic -= GFX_START_ROCKSDC;
1566 XCopyArea(display, pix[PIX_DC], drawto, gc,
1567 MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
1568 MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
1569 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1571 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1573 graphic -= GFX_START_ROCKSMORE;
1574 XCopyArea(display, pix[PIX_MORE], drawto, gc,
1575 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX,
1576 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY,
1577 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1580 XCopyArea(display, pix[PIX_BACK], drawto, gc,
1581 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1582 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1583 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1592 for(x=BX1; x<=BX2; x++)
1593 for(y=BY1; y<=BY2; y++)
1594 DrawScreenField(x, y);
1596 redraw_mask |= REDRAW_FIELD;
1599 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1603 for(x=0; x<size_x; x++)
1604 for(y=0; y<size_y; y++)
1605 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1607 redraw_mask |= REDRAW_FIELD;
1610 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1614 XFillRectangle(display, drawto, gc,
1615 xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1617 if (lev_fieldx < STD_LEV_FIELDX)
1618 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1619 if (lev_fieldy < STD_LEV_FIELDY)
1620 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1622 xpos += MICRO_TILEX;
1623 ypos += MICRO_TILEY;
1625 for(x=-1; x<=STD_LEV_FIELDX; x++)
1627 for(y=-1; y<=STD_LEV_FIELDY; y++)
1629 int lx = from_x + x, ly = from_y + y;
1631 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1632 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1634 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1635 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1640 redraw_mask |= REDRAW_MICROLEVEL;
1643 #define MICROLABEL_EMPTY 0
1644 #define MICROLABEL_LEVEL_NAME 1
1645 #define MICROLABEL_CREATED_BY 2
1646 #define MICROLABEL_LEVEL_AUTHOR 3
1647 #define MICROLABEL_IMPORTED_FROM 4
1648 #define MICROLABEL_LEVEL_IMPORT_INFO 5
1650 #define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
1652 static void DrawMicroLevelLabelExt(int mode)
1654 char label_text[MAX_MICROLABEL_SIZE + 1];
1656 XFillRectangle(display, drawto,gc,
1657 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1659 strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
1660 mode == MICROLABEL_CREATED_BY ? "created by" :
1661 mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
1662 mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
1663 mode == MICROLABEL_LEVEL_IMPORT_INFO ?
1664 leveldir_current->imported_from : ""),
1665 MAX_MICROLABEL_SIZE);
1666 label_text[MAX_MICROLABEL_SIZE] = '\0';
1668 if (strlen(label_text) > 0)
1670 int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
1671 int lypos = MICROLABEL_YPOS;
1673 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1676 redraw_mask |= REDRAW_MICROLEVEL;
1679 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1681 static unsigned long scroll_delay = 0;
1682 static unsigned long label_delay = 0;
1683 static int from_x, from_y, scroll_direction;
1684 static int label_state, label_counter;
1688 from_x = from_y = 0;
1689 scroll_direction = MV_RIGHT;
1693 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1694 DrawMicroLevelLabelExt(label_state);
1696 /* initialize delay counters */
1697 DelayReached(&scroll_delay, 0);
1698 DelayReached(&label_delay, 0);
1703 /* scroll micro level, if needed */
1704 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1705 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1707 switch (scroll_direction)
1713 scroll_direction = MV_UP;
1717 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1720 scroll_direction = MV_DOWN;
1727 scroll_direction = MV_RIGHT;
1731 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1734 scroll_direction = MV_LEFT;
1741 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1744 /* redraw micro level label, if needed */
1745 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1746 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1747 strcmp(level.author, leveldir_current->name) != 0 &&
1748 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1750 int max_label_counter = 23;
1752 if (leveldir_current->imported_from != NULL)
1753 max_label_counter += 14;
1755 label_counter = (label_counter + 1) % max_label_counter;
1756 label_state = (label_counter >= 0 && label_counter <= 7 ?
1757 MICROLABEL_LEVEL_NAME :
1758 label_counter >= 9 && label_counter <= 12 ?
1759 MICROLABEL_CREATED_BY :
1760 label_counter >= 14 && label_counter <= 21 ?
1761 MICROLABEL_LEVEL_AUTHOR :
1762 label_counter >= 23 && label_counter <= 26 ?
1763 MICROLABEL_IMPORTED_FROM :
1764 label_counter >= 28 && label_counter <= 35 ?
1765 MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
1766 DrawMicroLevelLabelExt(label_state);
1770 int REQ_in_range(int x, int y)
1772 if (y > DY+249 && y < DY+278)
1774 if (x > DX+1 && x < DX+48)
1776 else if (x > DX+51 && x < DX+98)
1782 boolean Request(char *text, unsigned int req_state)
1784 int mx, my, ty, result = -1;
1785 unsigned int old_door_state;
1788 /* pause network game while waiting for request to answer */
1789 if (options.network &&
1790 game_status == PLAYING &&
1791 req_state & REQUEST_WAIT_FOR)
1792 SendToServer_PausePlaying();
1795 old_door_state = GetDoorState();
1799 CloseDoor(DOOR_CLOSE_1);
1801 /* save old door content */
1802 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
1803 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1804 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1806 /* clear door drawing field */
1807 XFillRectangle(display, drawto, gc, DX, DY, DXSIZE, DYSIZE);
1809 /* write text for request */
1810 for(ty=0; ty<13; ty++)
1818 for(tl=0,tx=0; tx<7; tl++,tx++)
1821 if (!tc || tc == 32)
1832 DrawTextExt(drawto, gc,
1833 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1834 txt, FS_SMALL, FC_YELLOW);
1835 text += tl + (tc == 32 ? 1 : 0);
1838 if (req_state & REQ_ASK)
1840 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1841 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1843 else if (req_state & REQ_CONFIRM)
1845 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1847 else if (req_state & REQ_PLAYER)
1849 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1850 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1851 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1852 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1855 /* copy request gadgets to door backbuffer */
1856 XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
1857 DX, DY, DXSIZE, DYSIZE,
1858 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1860 OpenDoor(DOOR_OPEN_1);
1866 if (!(req_state & REQUEST_WAIT_FOR))
1869 if (game_status != MAINMENU)
1872 button_status = MB_RELEASED;
1874 request_gadget_id = -1;
1878 if (XPending(display))
1882 XNextEvent(display, &event);
1890 if (event.type == MotionNotify)
1897 if (!XQueryPointer(display, window, &root, &child,
1898 &root_x, &root_y, &win_x, &win_y, &mask))
1904 motion_status = TRUE;
1905 mx = ((XMotionEvent *) &event)->x;
1906 my = ((XMotionEvent *) &event)->y;
1910 motion_status = FALSE;
1911 mx = ((XButtonEvent *) &event)->x;
1912 my = ((XButtonEvent *) &event)->y;
1913 if (event.type==ButtonPress)
1914 button_status = ((XButtonEvent *) &event)->button;
1916 button_status = MB_RELEASED;
1919 /* this sets 'request_gadget_id' */
1920 HandleGadgets(mx, my, button_status);
1922 switch(request_gadget_id)
1924 case TOOL_CTRL_ID_YES:
1927 case TOOL_CTRL_ID_NO:
1930 case TOOL_CTRL_ID_CONFIRM:
1931 result = TRUE | FALSE;
1934 case TOOL_CTRL_ID_PLAYER_1:
1937 case TOOL_CTRL_ID_PLAYER_2:
1940 case TOOL_CTRL_ID_PLAYER_3:
1943 case TOOL_CTRL_ID_PLAYER_4:
1955 switch(XLookupKeysym((XKeyEvent *)&event,
1956 ((XKeyEvent *)&event)->state))
1969 if (req_state & REQ_PLAYER)
1974 key_joystick_mapping = 0;
1978 HandleOtherEvents(&event);
1982 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1984 int joy = AnyJoystick();
1986 if (joy & JOY_BUTTON_1)
1988 else if (joy & JOY_BUTTON_2)
1994 /* don't eat all CPU time */
1998 if (game_status != MAINMENU)
2003 if (!(req_state & REQ_STAY_OPEN))
2005 CloseDoor(DOOR_CLOSE_1);
2007 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2009 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
2010 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2011 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2012 OpenDoor(DOOR_OPEN_1);
2019 /* continue network game after request */
2020 if (options.network &&
2021 game_status == PLAYING &&
2022 req_state & REQUEST_WAIT_FOR)
2023 SendToServer_ContinuePlaying();
2029 unsigned int OpenDoor(unsigned int door_state)
2031 unsigned int new_door_state;
2033 if (door_state & DOOR_COPY_BACK)
2035 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
2036 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2037 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2038 door_state &= ~DOOR_COPY_BACK;
2041 new_door_state = MoveDoor(door_state);
2043 return(new_door_state);
2046 unsigned int CloseDoor(unsigned int door_state)
2048 unsigned int new_door_state;
2050 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
2051 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2052 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
2053 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2055 new_door_state = MoveDoor(door_state);
2057 return(new_door_state);
2060 unsigned int GetDoorState()
2062 return(MoveDoor(DOOR_GET_STATE));
2065 unsigned int MoveDoor(unsigned int door_state)
2067 static int door1 = DOOR_OPEN_1;
2068 static int door2 = DOOR_CLOSE_2;
2069 static unsigned long door_delay = 0;
2070 int x, start, stepsize = 2;
2071 unsigned long door_delay_value = stepsize * 5;
2073 if (door_state == DOOR_GET_STATE)
2074 return(door1 | door2);
2076 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2077 door_state &= ~DOOR_OPEN_1;
2078 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2079 door_state &= ~DOOR_CLOSE_1;
2080 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2081 door_state &= ~DOOR_OPEN_2;
2082 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2083 door_state &= ~DOOR_CLOSE_2;
2085 if (setup.quick_doors)
2088 door_delay_value = 0;
2089 StopSound(SND_OEFFNEN);
2092 if (door_state & DOOR_ACTION)
2094 if (!(door_state & DOOR_NO_DELAY))
2095 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2097 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2099 for(x=start; x<=DXSIZE; x+=stepsize)
2101 WaitUntilDelayReached(&door_delay, door_delay_value);
2103 if (door_state & DOOR_ACTION_1)
2105 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2106 int j = (DXSIZE - i) / 3;
2108 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
2109 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2110 DXSIZE,DYSIZE - i/2, DX, DY);
2112 XFillRectangle(display, drawto, gc, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2114 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2115 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2116 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
2117 DXSIZE, DOOR_GFX_PAGEY1, i, 77, DX + DXSIZE - i, DY + j);
2118 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2119 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63, DX + DXSIZE - i,
2121 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2122 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2123 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2124 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j, DX, DY);
2125 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2126 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63, DX, DY + 140 - j);
2128 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2129 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2131 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2132 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2134 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2135 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2136 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2137 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2138 DX + DXSIZE - i, DY + 77 + j);
2139 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2140 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2141 DX + DXSIZE - i, DY + 203 + j);
2143 redraw_mask |= REDRAW_DOOR_1;
2146 if (door_state & DOOR_ACTION_2)
2148 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2149 int j = (VXSIZE - i) / 3;
2151 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
2152 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2153 VXSIZE, VYSIZE - i/2, VX, VY);
2155 XFillRectangle(display, drawto, gc, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2157 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2158 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2159 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2160 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2, VX + VXSIZE-i, VY+j);
2161 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2162 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2163 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
2164 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j, VX, VY);
2166 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2167 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2,
2168 VX, VY + VYSIZE / 2 - j);
2169 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2170 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2171 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2172 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2 - j,
2173 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2175 redraw_mask |= REDRAW_DOOR_2;
2180 if (game_status == MAINMENU)
2185 if (setup.quick_doors)
2186 StopSound(SND_OEFFNEN);
2188 if (door_state & DOOR_ACTION_1)
2189 door1 = door_state & DOOR_ACTION_1;
2190 if (door_state & DOOR_ACTION_2)
2191 door2 = door_state & DOOR_ACTION_2;
2193 return (door1 | door2);
2196 void DrawSpecialEditorDoor()
2198 /* draw bigger toolbox window */
2199 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
2200 DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
2202 redraw_mask |= REDRAW_ALL;
2205 void UndrawSpecialEditorDoor()
2207 /* draw normal tape recorder window */
2208 XCopyArea(display, pix[PIX_BACK], drawto, gc,
2209 562, 344, 108, 56, EX - 4, EY - 12);
2211 redraw_mask |= REDRAW_ALL;
2214 int ReadPixel(Drawable d, int x, int y)
2216 XImage *pixel_image;
2217 unsigned long pixel_value;
2219 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
2220 pixel_value = XGetPixel(pixel_image, 0, 0);
2222 XDestroyImage(pixel_image);
2227 /* ---------- new tool button stuff ---------------------------------------- */
2229 /* graphic position values for tool buttons */
2230 #define TOOL_BUTTON_YES_XPOS 2
2231 #define TOOL_BUTTON_YES_YPOS 250
2232 #define TOOL_BUTTON_YES_GFX_YPOS 0
2233 #define TOOL_BUTTON_YES_XSIZE 46
2234 #define TOOL_BUTTON_YES_YSIZE 28
2235 #define TOOL_BUTTON_NO_XPOS 52
2236 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2237 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2238 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2239 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2240 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2241 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2242 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2243 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2244 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2245 #define TOOL_BUTTON_PLAYER_XSIZE 30
2246 #define TOOL_BUTTON_PLAYER_YSIZE 30
2247 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2248 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2249 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2250 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2251 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2252 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2253 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2254 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2255 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2256 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2257 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2258 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2259 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2260 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2261 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2262 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2263 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2264 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2265 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2266 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2275 } toolbutton_info[NUM_TOOL_BUTTONS] =
2278 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2279 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2280 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2285 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2286 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2287 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2292 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2293 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2294 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2295 TOOL_CTRL_ID_CONFIRM,
2299 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2300 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2301 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2302 TOOL_CTRL_ID_PLAYER_1,
2306 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2307 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2308 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2309 TOOL_CTRL_ID_PLAYER_2,
2313 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2314 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2315 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2316 TOOL_CTRL_ID_PLAYER_3,
2320 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2321 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2322 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2323 TOOL_CTRL_ID_PLAYER_4,
2328 static void DoNotDisplayInfoText(void *ptr)
2333 void CreateToolButtons()
2337 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2339 Pixmap gd_pixmap = pix[PIX_DOOR];
2340 Pixmap deco_pixmap = None;
2341 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2342 struct GadgetInfo *gi;
2343 unsigned long event_mask;
2344 int gd_xoffset, gd_yoffset;
2345 int gd_x1, gd_x2, gd_y;
2348 event_mask = GD_EVENT_RELEASED;
2350 gd_xoffset = toolbutton_info[i].xpos;
2351 gd_yoffset = toolbutton_info[i].ypos;
2352 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2353 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2354 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2356 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2358 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2359 &deco_pixmap, &deco_x, &deco_y);
2360 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2361 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2364 gi = CreateGadget(GDI_CUSTOM_ID, id,
2365 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2366 GDI_X, DX + toolbutton_info[i].x,
2367 GDI_Y, DY + toolbutton_info[i].y,
2368 GDI_WIDTH, toolbutton_info[i].width,
2369 GDI_HEIGHT, toolbutton_info[i].height,
2370 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2371 GDI_STATE, GD_BUTTON_UNPRESSED,
2372 GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
2373 GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
2374 GDI_DECORATION_DESIGN, deco_pixmap, deco_x, deco_y,
2375 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2376 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2377 GDI_DECORATION_SHIFTING, 1, 1,
2378 GDI_EVENT_MASK, event_mask,
2379 GDI_CALLBACK_ACTION, HandleToolButtons,
2380 GDI_CALLBACK_INFO, DoNotDisplayInfoText,
2384 Error(ERR_EXIT, "cannot create gadget");
2386 tool_gadget[id] = gi;
2390 static void UnmapToolButtons()
2394 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2395 UnmapGadget(tool_gadget[i]);
2398 static void HandleToolButtons(struct GadgetInfo *gi)
2400 request_gadget_id = gi->custom_id;
2403 int el2gfx(int element)
2407 case EL_LEERRAUM: return -1;
2408 case EL_ERDREICH: return GFX_ERDREICH;
2409 case EL_MAUERWERK: return GFX_MAUERWERK;
2410 case EL_FELSBODEN: return GFX_FELSBODEN;
2411 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2412 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2413 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2414 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2415 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2416 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2417 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2418 case EL_SPIELER1: return GFX_SPIELER1;
2419 case EL_SPIELER2: return GFX_SPIELER2;
2420 case EL_SPIELER3: return GFX_SPIELER3;
2421 case EL_SPIELER4: return GFX_SPIELER4;
2422 case EL_KAEFER: return GFX_KAEFER;
2423 case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
2424 case EL_KAEFER_UP: return GFX_KAEFER_UP;
2425 case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
2426 case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
2427 case EL_FLIEGER: return GFX_FLIEGER;
2428 case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
2429 case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
2430 case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
2431 case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
2432 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2433 case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
2434 case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
2435 case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
2436 case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
2437 case EL_FIREFLY: return GFX_FIREFLY;
2438 case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
2439 case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
2440 case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
2441 case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
2442 case EL_MAMPFER: return GFX_MAMPFER;
2443 case EL_ROBOT: return GFX_ROBOT;
2444 case EL_BETON: return GFX_BETON;
2445 case EL_DIAMANT: return GFX_DIAMANT;
2446 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2447 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2448 case EL_TROPFEN: return GFX_TROPFEN;
2449 case EL_BOMBE: return GFX_BOMBE;
2450 case EL_SIEB_INAKTIV: return GFX_SIEB_INAKTIV;
2451 case EL_SIEB_LEER: return GFX_SIEB_LEER;
2452 case EL_SIEB_VOLL: return GFX_SIEB_VOLL;
2453 case EL_SIEB_TOT: return GFX_SIEB_TOT;
2454 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2455 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2456 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2457 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2458 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2459 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2460 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2461 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2462 case EL_LIFE: return GFX_LIFE;
2463 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2464 case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
2465 case EL_BADEWANNE: return GFX_BADEWANNE;
2466 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2467 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2468 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2469 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2470 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2471 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2472 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2473 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2474 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2475 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2476 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2477 case EL_PFORTE1: return GFX_PFORTE1;
2478 case EL_PFORTE2: return GFX_PFORTE2;
2479 case EL_PFORTE3: return GFX_PFORTE3;
2480 case EL_PFORTE4: return GFX_PFORTE4;
2481 case EL_PFORTE1X: return GFX_PFORTE1X;
2482 case EL_PFORTE2X: return GFX_PFORTE2X;
2483 case EL_PFORTE3X: return GFX_PFORTE3X;
2484 case EL_PFORTE4X: return GFX_PFORTE4X;
2485 case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
2486 case EL_PACMAN: return GFX_PACMAN;
2487 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
2488 case EL_PACMAN_UP: return GFX_PACMAN_UP;
2489 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
2490 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
2491 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2492 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2493 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2494 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2495 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2496 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2497 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2498 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2499 case EL_MAUER_X: return GFX_MAUER_X;
2500 case EL_MAUER_Y: return GFX_MAUER_Y;
2501 case EL_MAUER_XY: return GFX_MAUER_XY;
2502 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2503 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2504 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2505 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2506 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2507 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2508 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2509 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2510 case EL_MAMPFER2: return GFX_MAMPFER2;
2511 case EL_SIEB2_INAKTIV: return GFX_SIEB2_INAKTIV;
2512 case EL_SIEB2_LEER: return GFX_SIEB2_LEER;
2513 case EL_SIEB2_VOLL: return GFX_SIEB2_VOLL;
2514 case EL_SIEB2_TOT: return GFX_SIEB2_TOT;
2515 case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
2516 case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
2517 case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
2518 case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
2519 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2520 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2521 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2522 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2523 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2524 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2525 case EL_MOLE: return GFX_MOLE;
2526 case EL_PINGUIN: return GFX_PINGUIN;
2527 case EL_SCHWEIN: return GFX_SCHWEIN;
2528 case EL_DRACHE: return GFX_DRACHE;
2529 case EL_SONDE: return GFX_SONDE;
2530 case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
2531 case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
2532 case EL_PFEIL_UP: return GFX_PFEIL_UP;
2533 case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
2534 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2535 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2536 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2537 case EL_SP_ZONK: return GFX_SP_ZONK;
2538 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2539 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2540 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2541 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2542 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2543 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2544 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2545 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2546 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2547 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2548 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2549 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2550 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2551 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2552 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2553 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2554 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2555 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2556 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2557 case EL_PEARL: return GFX_PEARL;
2558 case EL_CRYSTAL: return GFX_CRYSTAL;
2559 case EL_WALL_PEARL: return GFX_WALL_PEARL;
2560 case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
2561 case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
2562 case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
2563 case EL_KEY_WHITE: return GFX_KEY_WHITE;
2564 case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
2565 case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
2566 case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
2567 case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
2568 case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
2569 case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
2570 case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
2571 case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
2572 case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
2573 case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
2574 case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
2575 case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
2576 case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
2577 case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
2578 case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
2579 case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
2580 case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
2581 case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
2582 case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
2583 case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
2584 case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
2585 case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
2586 case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
2587 case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
2588 case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
2589 case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
2590 case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
2591 case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
2592 case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
2593 case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
2594 case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
2595 case EL_LANDMINE: return GFX_LANDMINE;
2596 case EL_ENVELOPE: return GFX_ENVELOPE;
2597 case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
2598 case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
2599 case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
2600 case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
2601 case EL_SIGN_STOP: return GFX_SIGN_STOP;
2602 case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
2603 case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
2604 case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
2605 case EL_SIGN_HEART: return GFX_SIGN_HEART;
2606 case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
2607 case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
2608 case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
2609 case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
2610 case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
2611 case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
2612 case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
2613 case EL_MOLE_UP: return GFX_MOLE_UP;
2614 case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
2615 case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
2616 case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
2617 case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
2618 case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
2619 case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
2620 case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
2621 case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
2622 case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
2623 case EL_BALLOON: return GFX_BALLOON;
2624 case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
2625 case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
2626 case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
2627 case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
2628 case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
2629 case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
2630 case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
2631 case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
2632 case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
2633 case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
2634 case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
2635 case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
2636 case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
2637 case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
2638 case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
2639 case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
2640 case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
2641 case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
2642 case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
2643 case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
2644 case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
2645 case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
2646 case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
2647 case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
2648 case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
2649 case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
2650 case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
2651 case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
2652 case EL_SPRING: return GFX_SPRING;
2653 case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
2654 case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
2658 if (IS_CHAR(element))
2659 return GFX_CHAR_START + (element - EL_CHAR_START);
2660 else if (element >= EL_SP_START && element <= EL_SP_END)
2662 int nr_element = element - EL_SP_START;
2663 int gfx_per_line = 8;
2665 (nr_element / gfx_per_line) * SP_PER_LINE +
2666 (nr_element % gfx_per_line);
2668 return GFX_START_ROCKSSP + nr_graphic;