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 ***********************************************************/
15 #include <machine/joystick.h>
30 extern BOOL wait_for_vsync;
33 void SetDrawtoField(int mode)
35 if (mode == DRAW_BUFFERED && soft_scrolling_on)
46 drawto_field = fieldbuffer;
48 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
59 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
66 Drawable buffer = (drawto_field != window ? drawto_field : backbuffer);
68 if (direct_draw_on && game_status == PLAYING)
69 redraw_mask &= ~REDRAW_MAIN;
71 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
72 redraw_mask |= REDRAW_FIELD;
74 if (redraw_mask & REDRAW_FIELD || ScreenGfxPos)
75 redraw_mask &= ~REDRAW_TILES;
80 /* synchronize X11 graphics at this point; if we would synchronize the
81 display immediately after the buffer switching (after the XFlush),
82 this could mean that we have to wait for the graphics to complete,
83 although we could go on doing calculations for the next frame */
88 wait_for_vsync = TRUE;
91 if (redraw_mask & REDRAW_ALL)
93 XCopyArea(display,backbuffer,window,gc,
94 0,0, WIN_XSIZE,WIN_YSIZE,
99 if (redraw_mask & REDRAW_FIELD)
101 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
102 XCopyArea(display,backbuffer,window,gc,
103 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
107 int fx = FX, fy = FY;
109 if (soft_scrolling_on)
111 fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
112 fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0);
115 XCopyArea(display,buffer,window,gc,
116 fx,fy, SXSIZE,SYSIZE,
119 redraw_mask &= ~REDRAW_MAIN;
122 if (redraw_mask & REDRAW_DOORS)
124 if (redraw_mask & REDRAW_DOOR_1)
125 XCopyArea(display,backbuffer,window,gc,
126 DX,DY, DXSIZE,DYSIZE,
128 if (redraw_mask & REDRAW_DOOR_2)
130 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
131 XCopyArea(display,backbuffer,window,gc,
132 VX,VY, VXSIZE,VYSIZE,
136 if (redraw_mask & REDRAW_VIDEO_1)
137 XCopyArea(display,backbuffer,window,gc,
138 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
139 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
140 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
141 if (redraw_mask & REDRAW_VIDEO_2)
142 XCopyArea(display,backbuffer,window,gc,
143 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
144 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
145 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
146 if (redraw_mask & REDRAW_VIDEO_3)
147 XCopyArea(display,backbuffer,window,gc,
148 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
149 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
150 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
153 redraw_mask &= ~REDRAW_DOORS;
156 if (redraw_mask & REDRAW_MICROLEV)
158 XCopyArea(display,backbuffer,window,gc,
159 MICROLEV_XPOS,MICROLEV_YPOS, MICROLEV_XSIZE,MICROLEV_YSIZE,
160 MICROLEV_XPOS,MICROLEV_YPOS);
161 XCopyArea(display,backbuffer,window,gc,
162 SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE,
164 redraw_mask &= ~REDRAW_MICROLEV;
167 if (redraw_mask & REDRAW_TILES)
169 for(x=0; x<SCR_FIELDX; x++)
170 for(y=0; y<SCR_FIELDY; y++)
171 if (redraw[redraw_x1 + x][redraw_y1 + y])
172 XCopyArea(display,buffer,window,gc,
173 FX+x*TILEX,FX+y*TILEY, TILEX,TILEY,
174 SX+x*TILEX,SY+y*TILEY);
179 for(x=0; x<MAX_BUF_XSIZE; x++)
180 for(y=0; y<MAX_BUF_YSIZE; y++)
189 long fading_delay = 300;
191 if (fading_on && (redraw_mask & REDRAW_FIELD))
198 XFillRectangle(display,window,gc,
199 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
202 for(i=0;i<2*FULL_SYSIZE;i++)
204 for(y=0;y<FULL_SYSIZE;y++)
206 XCopyArea(display,backbuffer,window,gc,
207 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
215 for(i=1;i<FULL_SYSIZE;i+=2)
216 XCopyArea(display,backbuffer,window,gc,
217 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
223 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
224 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
225 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
229 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
230 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
231 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
235 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
236 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
237 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
241 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
242 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
243 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
247 redraw_mask &= ~REDRAW_MAIN;
256 XFillRectangle(display,backbuffer,gc,
257 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
259 if (soft_scrolling_on && game_status==PLAYING)
261 XFillRectangle(display,fieldbuffer,gc,
263 SetDrawtoField(DRAW_BUFFERED);
266 SetDrawtoField(DRAW_BACKBUFFER);
268 if (direct_draw_on && game_status==PLAYING)
270 XFillRectangle(display,window,gc,
271 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
272 SetDrawtoField(DRAW_DIRECT);
275 redraw_mask |= REDRAW_FIELD;
278 void DrawText(int x, int y, char *text, int font, int col)
280 DrawTextExt(drawto, gc, x, y, text, font, col);
282 redraw_mask |= REDRAW_FIELD;
284 redraw_mask |= REDRAW_DOOR_1;
287 void DrawTextExt(Drawable d, GC gc, int x, int y,
288 char *text, int font, int font_color)
290 int font_width, font_height, font_start;
293 if (font!=FS_SMALL && font!=FS_BIG)
295 if (font_color<FC_RED || font_color>FC_SPECIAL2)
299 (font==FS_BIG ? FONT1_XSIZE :
300 font_color<FC_SPECIAL1 ? FONT2_XSIZE :
301 font_color<FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
303 (font==FS_BIG ? FONT1_XSIZE :
304 font_color<FC_SPECIAL2 ? FONT2_XSIZE: FONT4_XSIZE);
305 font_pixmap = (font==FS_BIG ? PIX_BIGFONT : PIX_SMALLFONT);
307 font_color*(font==FS_BIG ? FONT1_YSIZE : FONT2_YSIZE)*FONT_LINES_PER_FONT;
313 if (c>='a' && c<='z')
315 else if (c=='ä' || c=='Ä')
317 else if (c=='ö' || c=='Ö')
319 else if (c=='ü' || c=='Ü')
323 XCopyArea(display,pix[font_pixmap],d,gc,
324 ((c-32) % FONT_CHARS_PER_LINE)*font_width,
325 ((c-32) / FONT_CHARS_PER_LINE)*font_height + font_start,
326 font_width,font_height, x,y);
332 void DrawAllPlayers()
336 for(i=0; i<MAX_PLAYERS; i++)
337 if (stored_player[i].active)
338 DrawPlayer(&stored_player[i]);
341 void DrawPlayerField(int x, int y)
346 DrawPlayer(PLAYERINFO(x,y));
349 void DrawPlayer(struct PlayerInfo *player)
351 int jx = player->jx, jy = player->jy;
352 int last_jx = player->last_jx, last_jy = player->last_jy;
353 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
354 int sx = SCREENX(jx), sy = SCREENY(jy);
355 int sxx = 0, syy = 0;
356 int element = Feld[jx][jy];
359 if (!player->active || player->gone || !IN_SCR_FIELD(sx,sy))
363 if (!IN_LEV_FIELD(jx,jy) || !IN_SCR_FIELD(sx,sy))
365 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
366 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
367 printf("DrawPlayerField(): This should never happen!\n");
372 if (element == EL_EXPLODING)
376 SetDrawtoField(DRAW_BUFFERED);
378 /* draw things in the field the player is leaving, if needed */
380 if (last_jx != jx || last_jy != jy)
382 if (Store[last_jx][last_jy])
384 DrawLevelElement(last_jx,last_jy, Store[last_jx][last_jy]);
385 DrawLevelElementThruMask(last_jx,last_jy, Feld[last_jx][last_jy]);
387 else if (Feld[last_jx][last_jy] == EL_DYNAMIT)
388 DrawDynamite(last_jx,last_jy);
390 DrawLevelField(last_jx,last_jy);
396 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
397 DrawLevelElement(next_jx,next_jy, EL_SOKOBAN_FELD_LEER);
399 DrawLevelElement(next_jx,next_jy, EL_LEERRAUM);
402 DrawLevelField(next_jx,next_jy);
406 /* draw things behind the player, if needed */
409 DrawLevelElement(jx,jy, Store[jx][jy]);
410 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
411 DrawLevelField(jx,jy);
413 /* draw player himself */
415 if (player->MovDir==MV_LEFT)
416 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
417 else if (player->MovDir==MV_RIGHT)
418 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
419 else if (player->MovDir==MV_UP)
420 graphic = GFX_SPIELER1_UP;
421 else /* MV_DOWN || MV_NO_MOVING */
422 graphic = GFX_SPIELER1_DOWN;
424 graphic += player->nr * 3*HEROES_PER_LINE;
425 graphic += player->Frame;
429 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
430 sxx = player->GfxPos;
432 syy = player->GfxPos;
435 if (!soft_scrolling_on && ScreenMovPos)
438 DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING);
440 if (player->Pushing && player->GfxPos)
442 int px = SCREENX(next_jx), py = SCREENY(next_jy);
444 if (Feld[jx][jy] == EL_SOKOBAN_FELD_LEER ||
445 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
446 DrawGraphicShiftedThruMask(px,py,sxx,syy, GFX_SOKOBAN_OBJEKT,NO_CUTTING);
449 int element = Feld[next_jx][next_jy];
450 int graphic = el2gfx(element);
452 if (element == EL_FELSBROCKEN && sxx)
454 int phase = (player->GfxPos / (TILEX/4));
456 if (player->MovDir == MV_LEFT)
459 graphic += (phase+4)%4;
462 DrawGraphicShifted(px,py, sxx,syy, graphic, NO_CUTTING, NO_MASKING);
466 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
468 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
470 graphic = el2gfx(element);
472 if (element == EL_DYNAMIT)
474 if ((phase = (96-MovDelay[jx][jy])/12) > 6)
479 if ((phase = ((96-MovDelay[jx][jy])/6) % 8) > 3)
483 DrawGraphicThruMask(sx,sy, graphic + phase);
488 int dest_x = SX + SCREENX(MIN(jx,last_jx))*TILEX;
489 int dest_y = SY + SCREENY(MIN(jy,last_jy))*TILEY;
490 int x_size = TILEX * (1 + ABS(jx - last_jx));
491 int y_size = TILEY * (1 + ABS(jy - last_jy));
493 XCopyArea(display,drawto_field,window,gc,
494 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
495 SetDrawtoField(DRAW_DIRECT);
498 MarkTileDirty(sx,sy);
501 static int getGraphicAnimationPhase(int frames, int delay, int mode)
505 if (mode == ANIM_OSCILLATE)
507 int max_anim_frames = frames*2 - 2;
508 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
509 phase = (phase < frames ? phase : max_anim_frames - phase);
512 phase = (FrameCounter % (delay * frames)) / delay;
514 if (mode == ANIM_REVERSE)
520 void DrawGraphicAnimationExt(int x, int y, int graphic,
521 int frames, int delay, int mode, int mask_mode)
523 int phase = getGraphicAnimationPhase(frames, delay, mode);
525 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
527 if (mask_mode == USE_MASKING)
528 DrawGraphicThruMask(SCREENX(x),SCREENY(y), graphic + phase);
530 DrawGraphic(SCREENX(x),SCREENY(y), graphic + phase);
534 void DrawGraphicAnimation(int x, int y, int graphic,
535 int frames, int delay, int mode)
537 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, NO_MASKING);
540 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
541 int frames, int delay, int mode)
543 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, USE_MASKING);
546 void DrawGraphic(int x, int y, int graphic)
550 if (!IN_SCR_FIELD(x,y))
552 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
553 printf("DrawGraphic(): This should never happen!\n");
558 DrawGraphicExt(drawto_field, gc, FX+x*TILEX, FY+y*TILEY, graphic);
562 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
564 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
566 graphic -= GFX_START_ROCKSSCREEN;
567 XCopyArea(display,pix[PIX_BACK],d,gc,
568 SX + (graphic % GFX_PER_LINE) * TILEX,
569 SY + (graphic / GFX_PER_LINE) * TILEY,
572 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
574 graphic -= GFX_START_ROCKSHEROES;
575 XCopyArea(display,pix[PIX_HEROES],d,gc,
576 (graphic % HEROES_PER_LINE) * TILEX,
577 (graphic / HEROES_PER_LINE) * TILEY,
580 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
582 graphic -= GFX_START_ROCKSFONT;
583 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
584 (graphic % FONT_CHARS_PER_LINE) * TILEX,
585 (graphic / FONT_CHARS_PER_LINE) * TILEY +
586 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
590 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
593 void DrawGraphicThruMask(int x, int y, int graphic)
595 int src_x,src_y, dest_x,dest_y;
601 if (!IN_SCR_FIELD(x,y))
603 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
604 printf("DrawGraphicThruMask(): This should never happen!\n");
609 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
611 src_pixmap = pix[PIX_BACK];
612 drawing_gc = clip_gc[PIX_BACK];
613 graphic -= GFX_START_ROCKSSCREEN;
614 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
615 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
617 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
619 src_pixmap = pix[PIX_HEROES];
620 drawing_gc = clip_gc[PIX_HEROES];
621 graphic -= GFX_START_ROCKSHEROES;
622 src_x = (graphic % HEROES_PER_LINE)*TILEX;
623 src_y = (graphic / HEROES_PER_LINE)*TILEY;
627 DrawGraphic(x,y,graphic);
631 dest_x = FX + x*TILEX;
632 dest_y = FY + y*TILEY;
634 if (tile_clipmask[tile] != None)
636 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
637 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
638 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
639 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
644 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
647 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
648 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
649 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
655 void DrawMiniGraphic(int x, int y, int graphic)
657 DrawMiniGraphicExt(drawto,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
658 MarkTileDirty(x/2, y/2);
661 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
663 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
665 graphic -= GFX_START_ROCKSSCREEN;
666 XCopyArea(display,pix[PIX_BACK],d,gc,
667 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
668 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
669 MINI_TILEX,MINI_TILEY, x,y);
671 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
673 graphic -= GFX_START_ROCKSFONT;
674 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
675 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
676 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
677 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
678 MINI_TILEX,MINI_TILEY, x,y);
681 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
684 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
685 int cut_mode, int mask_mode)
687 int width = TILEX, height = TILEY;
689 int src_x,src_y, dest_x,dest_y;
696 DrawGraphic(x,y,graphic);
700 if (dx || dy) /* Verschiebung der Grafik? */
702 if (x < BX1) /* Element kommt von links ins Bild */
709 else if (x > BX2) /* Element kommt von rechts ins Bild */
715 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
721 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
723 else if (dx) /* allg. Bewegung in x-Richtung */
724 MarkTileDirty(x + SIGN(dx), y);
726 if (y < BY1) /* Element kommt von oben ins Bild */
728 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
736 else if (y > BY2) /* Element kommt von unten ins Bild */
742 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
748 else if (dy > 0 && cut_mode==CUT_ABOVE)
750 if (y == BY2) /* Element unterhalb des Bildes */
756 MarkTileDirty(x, y + 1);
757 } /* Element verläßt unten das Bild */
758 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
760 else if (dy) /* allg. Bewegung in y-Richtung */
761 MarkTileDirty(x, y + SIGN(dy));
764 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
766 src_pixmap = pix[PIX_BACK];
767 drawing_gc = clip_gc[PIX_BACK];
768 graphic -= GFX_START_ROCKSSCREEN;
769 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
770 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
772 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
774 src_pixmap = pix[PIX_HEROES];
775 drawing_gc = clip_gc[PIX_HEROES];
776 graphic -= GFX_START_ROCKSHEROES;
777 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
778 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
781 dest_x = FX + x*TILEX + dx;
782 dest_y = FY + y*TILEY + dy;
785 if (!IN_SCR_FIELD(x,y))
787 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
788 printf("DrawGraphicShifted(): This should never happen!\n");
793 if (mask_mode == USE_MASKING)
795 if (tile_clipmask[tile] != None)
797 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
798 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
799 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
800 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
805 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
808 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
809 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
810 src_x,src_y, width,height, dest_x,dest_y);
814 XCopyArea(display, src_pixmap, drawto_field, gc,
815 src_x,src_y, width,height, dest_x,dest_y);
820 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
823 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
826 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
827 int cut_mode, int mask_mode)
829 int ux = LEVELX(x), uy = LEVELY(y);
830 int graphic = el2gfx(element);
831 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
832 int phase = phase4 / 2;
833 int dir = MovDir[ux][uy];
835 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
841 else if (dir == MV_LEFT)
843 else if (dir == MV_DOWN)
846 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
847 element==EL_SCHWEIN || element==EL_DRACHE)
850 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
851 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
852 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
853 else if (dir==MV_RIGHT)
854 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
855 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
856 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
858 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
859 element==EL_PINGUIN ? GFX_PINGUIN_UP :
860 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
862 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
863 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
864 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
868 else if (element==EL_SONDE)
870 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
872 else if (element==EL_SALZSAEURE)
874 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
876 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
880 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
882 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
884 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
885 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
887 graphic += 3-(SiebAktiv%8)/2;
889 else if (IS_AMOEBOID(element))
891 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
892 graphic += (x+2*y) % 4;
894 else if (element==EL_MAUER_LEBT)
896 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
898 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
900 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
901 rechts_massiv = TRUE;
903 if (links_massiv && rechts_massiv)
904 graphic = GFX_MAUERWERK;
905 else if (links_massiv)
906 graphic = GFX_MAUER_R;
907 else if (rechts_massiv)
908 graphic = GFX_MAUER_L;
912 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, mask_mode);
913 else if (mask_mode == USE_MASKING)
914 DrawGraphicThruMask(x,y, graphic);
916 DrawGraphic(x,y, graphic);
919 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
920 int cut_mode, int mask_mode)
922 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
923 DrawScreenElementExt(SCREENX(x),SCREENY(y), dx,dy, element,
924 cut_mode, mask_mode);
927 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
930 DrawScreenElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
933 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
936 DrawLevelElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
939 void DrawScreenElementThruMask(int x, int y, int element)
941 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
944 void DrawLevelElementThruMask(int x, int y, int element)
946 DrawLevelElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
949 void ErdreichAnbroeckeln(int x, int y)
951 int i, width, height, cx,cy;
952 int ux = LEVELX(x), uy = LEVELY(y);
953 int element, graphic;
955 static int xy[4][2] =
963 if (!IN_LEV_FIELD(ux,uy))
966 element = Feld[ux][uy];
968 if (element==EL_ERDREICH)
970 if (!IN_SCR_FIELD(x,y))
973 graphic = GFX_ERDENRAND;
981 if (!IN_LEV_FIELD(uxx,uyy))
984 element = Feld[uxx][uyy];
986 if (element==EL_ERDREICH)
993 cx = (i==2 ? TILEX-snip : 0);
1001 cy = (i==3 ? TILEY-snip : 0);
1004 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1005 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1006 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1007 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1014 graphic = GFX_ERDENRAND;
1025 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1026 !IN_SCR_FIELD(xx,yy))
1033 cx = (i==1 ? TILEX-snip : 0);
1041 cy = (i==0 ? TILEY-snip : 0);
1044 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1045 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1046 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1047 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1049 MarkTileDirty(xx,yy);
1054 void DrawScreenElement(int x, int y, int element)
1056 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, NO_MASKING);
1057 ErdreichAnbroeckeln(x,y);
1060 void DrawLevelElement(int x, int y, int element)
1062 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1063 DrawScreenElement(SCREENX(x),SCREENY(y),element);
1066 void DrawScreenField(int x, int y)
1068 int ux = LEVELX(x), uy = LEVELY(y);
1071 if (!IN_LEV_FIELD(ux,uy))
1073 DrawScreenElement(x,y,EL_BETON);
1077 element = Feld[ux][uy];
1079 if (IS_MOVING(ux,uy))
1081 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1082 BOOL cut_mode = NO_CUTTING;
1084 if (Store[ux][uy]==EL_MORAST_LEER ||
1085 Store[ux][uy]==EL_SIEB_LEER ||
1086 Store[ux][uy]==EL_SIEB2_LEER ||
1087 Store[ux][uy]==EL_AMOEBE_NASS)
1088 cut_mode = CUT_ABOVE;
1089 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1092 Store[ux][uy]==EL_SALZSAEURE ||
1095 Store[ux][uy]==EL_SIEB_VOLL ||
1096 Store[ux][uy]==EL_SIEB2_VOLL)
1097 cut_mode = CUT_BELOW;
1099 if (cut_mode==CUT_ABOVE)
1100 DrawScreenElementShifted(x,y, 0,0, Store[ux][uy], NO_CUTTING);
1102 DrawScreenElement(x,y,EL_LEERRAUM);
1105 DrawScreenElementShifted(x,y, MovPos[ux][uy],0, element, NO_CUTTING);
1107 DrawScreenElementShifted(x,y, 0,MovPos[ux][uy], element, cut_mode);
1110 if (Store[ux][uy] == EL_SALZSAEURE)
1111 DrawLevelElementThruMask(ux,uy+1, EL_SALZSAEURE);
1115 else if (IS_BLOCKED(ux,uy))
1120 BOOL cut_mode = NO_CUTTING;
1122 Blocked2Moving(ux,uy,&oldx,&oldy);
1125 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1127 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1128 Store[oldx][oldy]==EL_SIEB_LEER ||
1129 Store[oldx][oldy]==EL_SIEB2_LEER ||
1130 Store[oldx][oldy]==EL_AMOEBE_NASS)
1131 cut_mode = CUT_ABOVE;
1133 DrawScreenElement(x,y,EL_LEERRAUM);
1134 element = Feld[oldx][oldy];
1137 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1139 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1141 else if (IS_DRAWABLE(element))
1142 DrawScreenElement(x,y,element);
1144 DrawScreenElement(x,y,EL_LEERRAUM);
1147 void DrawLevelField(int x, int y)
1149 if (IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1150 DrawScreenField(SCREENX(x),SCREENY(y));
1151 else if (IS_MOVING(x,y))
1155 Moving2Blocked(x,y,&newx,&newy);
1156 if (IN_SCR_FIELD(SCREENX(newx),SCREENY(newy)))
1157 DrawScreenField(SCREENX(newx),SCREENY(newy));
1159 else if (IS_BLOCKED(x,y))
1163 Blocked2Moving(x,y,&oldx,&oldy);
1164 if (IN_SCR_FIELD(SCREENX(oldx),SCREENY(oldy)))
1165 DrawScreenField(SCREENX(oldx),SCREENY(oldy));
1169 void DrawMiniElement(int x, int y, int element)
1175 DrawMiniGraphic(x,y,-1);
1179 graphic = el2gfx(element);
1180 DrawMiniGraphic(x,y,graphic);
1183 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1185 int x = sx + scroll_x, y = sy + scroll_y;
1187 if (x<-1 || x>lev_fieldx || y<-1 || y>lev_fieldy)
1188 DrawMiniElement(sx,sy,EL_LEERRAUM);
1189 else if (x==-1 || x==lev_fieldx || y==-1 || y==lev_fieldy)
1190 DrawMiniElement(sx,sy,EL_BETON);
1192 DrawMiniElement(sx,sy,Feld[x][y]);
1195 void DrawMicroElement(int xpos, int ypos, int element)
1199 if (element==EL_LEERRAUM)
1202 graphic = el2gfx(element);
1204 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1205 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1206 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1207 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1216 for(x=BX1; x<=BX2; x++)
1217 for(y=BY1; y<=BY2; y++)
1218 DrawScreenField(x,y);
1220 if (soft_scrolling_on)
1221 XCopyArea(display,fieldbuffer,backbuffer,gc,
1222 FX,FY, SXSIZE,SYSIZE,
1225 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1228 void DrawMiniLevel(int scroll_x, int scroll_y)
1234 for(x=0;x<2*SCR_FIELDX;x++)
1235 for(y=0;y<2*SCR_FIELDY;y++)
1236 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1238 redraw_mask |= REDRAW_FIELD;
1241 void DrawMicroLevel(int xpos, int ypos)
1245 XFillRectangle(display,drawto,gc,
1246 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1247 MICRO_TILEX*(STD_LEV_FIELDX+2),
1248 MICRO_TILEY*(STD_LEV_FIELDY+2));
1249 if (lev_fieldx < STD_LEV_FIELDX)
1250 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1251 if (lev_fieldy < STD_LEV_FIELDY)
1252 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1254 for(x=-1;x<=STD_LEV_FIELDX;x++)
1255 for(y=-1;y<=STD_LEV_FIELDY;y++)
1256 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1257 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1258 Feld[x][y]=Ur[x][y]);
1259 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1260 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1263 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1267 int len = strlen(level.name);
1268 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1269 int lypos = MICROLABEL_YPOS;
1271 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1274 redraw_mask |= REDRAW_MICROLEV;
1277 int AYS_in_range(int x, int y)
1279 if (y>DY+249 && y<DY+278)
1281 if (x>DX+1 && x<DX+48)
1283 else if (x>DX+51 && x<DX+98)
1289 BOOL AreYouSure(char *text, unsigned int ays_state)
1291 int mx,my, ty, result = -1;
1292 unsigned int old_door_state;
1294 old_door_state = GetDoorState();
1296 CloseDoor(DOOR_CLOSE_1);
1298 /* Alten Türinhalt sichern */
1299 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1300 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1301 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1303 /* Fragetext schreiben */
1304 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1305 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1307 for(ty=0;ty<13;ty++)
1314 for(tl=0,tx=0;tx<7;tl++,tx++)
1328 DrawTextExt(pix[PIX_DB_DOOR],gc,
1329 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1330 text+=(tl+(tc==32));
1333 if (ays_state & AYS_ASK)
1334 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1335 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1336 DXSIZE,OK_BUTTON_YSIZE,
1337 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1338 else if (ays_state & AYS_CONFIRM)
1339 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1340 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1341 DXSIZE,CONFIRM_BUTTON_YSIZE,
1342 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1344 OpenDoor(DOOR_OPEN_1);
1347 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1350 if (game_status != MAINMENU)
1353 button_status = MB_RELEASED;
1360 if (XPending(display))
1364 XNextEvent(display, &event);
1368 HandleExposeEvent((XExposeEvent *) &event);
1371 SleepWhileUnmapped();
1379 if (event.type == MotionNotify)
1381 motion_status = TRUE;
1382 mx = ((XMotionEvent *) &event)->x;
1383 my = ((XMotionEvent *) &event)->y;
1387 motion_status = FALSE;
1388 mx = ((XButtonEvent *) &event)->x;
1389 my = ((XButtonEvent *) &event)->y;
1390 if (event.type==ButtonPress)
1391 button_status = ((XButtonEvent *) &event)->button;
1393 button_status = MB_RELEASED;
1396 if (ays_state & AYS_ASK)
1397 choice = CheckChooseButtons(mx,my,button_status);
1399 choice = CheckConfirmButton(mx,my,button_status);
1409 case BUTTON_CONFIRM:
1410 result = TRUE|FALSE;
1418 switch(XLookupKeysym((XKeyEvent *)&event,
1419 ((XKeyEvent *)&event)->state))
1430 key_joystick_mapping = 0;
1434 HandleFocusEvent((XFocusChangeEvent *) &event);
1437 HandleClientMessageEvent((XClientMessageEvent *) &event);
1443 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1447 if (joy & JOY_BUTTON_1)
1449 else if (joy & JOY_BUTTON_2)
1454 if (game_status != MAINMENU)
1457 if (!(ays_state & AYS_STAY_OPEN))
1459 CloseDoor(DOOR_CLOSE_1);
1461 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1463 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1464 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1465 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1466 OpenDoor(DOOR_OPEN_1);
1473 unsigned int OpenDoor(unsigned int door_state)
1475 unsigned int new_door_state;
1477 if (door_state & DOOR_COPY_BACK)
1479 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1480 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1481 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1482 door_state &= ~DOOR_COPY_BACK;
1485 new_door_state = MoveDoor(door_state);
1487 return(new_door_state);
1490 unsigned int CloseDoor(unsigned int door_state)
1492 unsigned int new_door_state;
1494 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1495 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1496 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1497 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1499 new_door_state = MoveDoor(door_state);
1501 return(new_door_state);
1504 unsigned int GetDoorState()
1506 return(MoveDoor(DOOR_GET_STATE));
1509 unsigned int MoveDoor(unsigned int door_state)
1511 static unsigned int door1 = DOOR_OPEN_1;
1512 static unsigned int door2 = DOOR_CLOSE_2;
1513 static long door_delay = 0;
1514 int x, start, stepsize = 2;
1515 long door_delay_value = stepsize * 5;
1517 if (door_state == DOOR_GET_STATE)
1518 return(door1 | door2);
1520 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1521 door_state &= ~DOOR_OPEN_1;
1522 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1523 door_state &= ~DOOR_CLOSE_1;
1524 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1525 door_state &= ~DOOR_OPEN_2;
1526 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1527 door_state &= ~DOOR_CLOSE_2;
1532 door_delay_value = 0;
1533 StopSound(SND_OEFFNEN);
1536 if (door_state & DOOR_ACTION)
1538 if (!(door_state & DOOR_NO_DELAY))
1539 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1541 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1543 for(x=start; x<=DXSIZE; x+=stepsize)
1545 WaitUntilDelayReached(&door_delay, door_delay_value);
1547 if (door_state & DOOR_ACTION_1)
1549 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1550 int j = (DXSIZE - i)/3;
1552 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1553 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1554 DXSIZE,DYSIZE-i/2, DX,DY);
1556 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1558 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1559 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1560 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1561 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1562 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1563 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1564 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1565 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1566 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1567 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1568 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1569 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1571 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1572 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1574 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1575 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1577 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1578 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1579 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1580 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1581 DX+DXSIZE-i,DY+77+j);
1582 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1583 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1584 DX+DXSIZE-i,DY+203+j);
1586 redraw_mask |= REDRAW_DOOR_1;
1589 if (door_state & DOOR_ACTION_2)
1591 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1592 int j = (VXSIZE - i)/3;
1594 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1595 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1596 VXSIZE,VYSIZE-i/2, VX,VY);
1598 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1600 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1601 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1602 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1603 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1604 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1605 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1606 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1607 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1609 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1610 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1612 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1613 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1614 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1615 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1616 VX+VXSIZE-i,VY+VYSIZE/2+j);
1618 redraw_mask |= REDRAW_DOOR_2;
1623 if (game_status == MAINMENU)
1628 if (door_state & DOOR_ACTION_1)
1629 door1 = door_state & DOOR_ACTION_1;
1630 if (door_state & DOOR_ACTION_2)
1631 door2 = door_state & DOOR_ACTION_2;
1633 return(door1 | door2);
1636 int ReadPixel(Drawable d, int x, int y)
1638 static XImage *pixelimage;
1640 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1641 return(XGetPixel(pixelimage,0,0));
1644 int el2gfx(int element)
1648 case EL_LEERRAUM: return(-1);
1649 case EL_ERDREICH: return(GFX_ERDREICH);
1650 case EL_MAUERWERK: return(GFX_MAUERWERK);
1651 case EL_FELSBODEN: return(GFX_FELSBODEN);
1652 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1653 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1654 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1655 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1656 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1657 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1658 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1659 case EL_SPIELER1: return(GFX_SPIELER1);
1660 case EL_SPIELER2: return(GFX_SPIELER2);
1661 case EL_SPIELER3: return(GFX_SPIELER3);
1662 case EL_SPIELER4: return(GFX_SPIELER4);
1663 case EL_KAEFER: return(GFX_KAEFER);
1664 case EL_KAEFER_R: return(GFX_KAEFER_R);
1665 case EL_KAEFER_O: return(GFX_KAEFER_O);
1666 case EL_KAEFER_L: return(GFX_KAEFER_L);
1667 case EL_KAEFER_U: return(GFX_KAEFER_U);
1668 case EL_FLIEGER: return(GFX_FLIEGER);
1669 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1670 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1671 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1672 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1673 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1674 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1675 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1676 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1677 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1678 case EL_FIREFLY: return(GFX_FIREFLY);
1679 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1680 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1681 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1682 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1683 case EL_MAMPFER: return(GFX_MAMPFER);
1684 case EL_ROBOT: return(GFX_ROBOT);
1685 case EL_BETON: return(GFX_BETON);
1686 case EL_DIAMANT: return(GFX_DIAMANT);
1687 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1688 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1689 case EL_TROPFEN: return(GFX_TROPFEN);
1690 case EL_BOMBE: return(GFX_BOMBE);
1691 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1692 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1693 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1694 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1695 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1696 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1697 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1698 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1699 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1700 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1701 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1702 case EL_LIFE: return(GFX_LIFE);
1703 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1704 case EL_DYNAMIT: return(GFX_DYNAMIT);
1705 case EL_BADEWANNE: return(GFX_BADEWANNE);
1706 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1707 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1708 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1709 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1710 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1711 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1712 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1713 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1714 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1715 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1716 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1717 case EL_PFORTE1: return(GFX_PFORTE1);
1718 case EL_PFORTE2: return(GFX_PFORTE2);
1719 case EL_PFORTE3: return(GFX_PFORTE3);
1720 case EL_PFORTE4: return(GFX_PFORTE4);
1721 case EL_PFORTE1X: return(GFX_PFORTE1X);
1722 case EL_PFORTE2X: return(GFX_PFORTE2X);
1723 case EL_PFORTE3X: return(GFX_PFORTE3X);
1724 case EL_PFORTE4X: return(GFX_PFORTE4X);
1725 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1726 case EL_PACMAN: return(GFX_PACMAN);
1727 case EL_PACMAN_R: return(GFX_PACMAN_R);
1728 case EL_PACMAN_O: return(GFX_PACMAN_O);
1729 case EL_PACMAN_L: return(GFX_PACMAN_L);
1730 case EL_PACMAN_U: return(GFX_PACMAN_U);
1731 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1732 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1733 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1734 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1735 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1736 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1737 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1738 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1739 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1740 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1741 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1742 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1743 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1744 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1745 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1746 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1747 case EL_MAMPFER2: return(GFX_MAMPFER2);
1748 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1749 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1750 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1751 case EL_DYNABOMB: return(GFX_DYNABOMB);
1752 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1753 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1754 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1755 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1756 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1757 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1758 case EL_MAULWURF: return(GFX_MAULWURF);
1759 case EL_PINGUIN: return(GFX_PINGUIN);
1760 case EL_SCHWEIN: return(GFX_SCHWEIN);
1761 case EL_DRACHE: return(GFX_DRACHE);
1762 case EL_SONDE: return(GFX_SONDE);
1763 case EL_PFEIL_L: return(GFX_PFEIL_L);
1764 case EL_PFEIL_R: return(GFX_PFEIL_R);
1765 case EL_PFEIL_O: return(GFX_PFEIL_O);
1766 case EL_PFEIL_U: return(GFX_PFEIL_U);
1769 if (IS_CHAR(element))
1770 return(GFX_CHAR_START + (element-EL_CHAR_START));