1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * ©1995 Artsoft Development *
6 * 33659 Bielefeld-Senne *
7 * Telefon: (0521) 493245 *
8 * eMail: aeglos@valinor.owl.de *
9 * aeglos@uni-paderborn.de *
10 * q99492@pbhrzx.uni-paderborn.de *
11 *----------------------------------------------------------*
13 ***********************************************************/
16 #include <machine/joystick.h>
31 extern BOOL wait_for_vsync;
34 void SetDrawtoField(int mode)
36 if (mode == DRAW_BUFFERED && soft_scrolling_on)
47 drawto_field = fieldbuffer;
49 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
60 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
67 Drawable buffer = (drawto_field != window ? drawto_field : backbuffer);
69 if (direct_draw_on && game_status == PLAYING)
70 redraw_mask &= ~REDRAW_MAIN;
72 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
73 redraw_mask |= REDRAW_FIELD;
75 if (redraw_mask & REDRAW_FIELD || ScreenMovPos)
76 redraw_mask &= ~REDRAW_TILES;
81 /* synchronize X11 graphics at this point; if we would synchronize the
82 display immediately after the buffer switching (after the XFlush),
83 this could mean that we have to wait for the graphics to complete,
84 although we could go on doing calculations for the next frame */
89 wait_for_vsync = TRUE;
92 if (redraw_mask & REDRAW_ALL)
94 XCopyArea(display,backbuffer,window,gc,
95 0,0, WIN_XSIZE,WIN_YSIZE,
100 if (redraw_mask & REDRAW_FIELD)
102 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
103 XCopyArea(display,backbuffer,window,gc,
104 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
108 int fx = FX, fy = FY;
110 if (soft_scrolling_on)
112 fx += (PlayerMovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0);
113 fy += (PlayerMovDir & (MV_UP|MV_DOWN) ? ScreenMovPos : 0);
116 XCopyArea(display,buffer,window,gc,
117 fx,fy, SXSIZE,SYSIZE,
120 redraw_mask &= ~REDRAW_MAIN;
123 if (redraw_mask & REDRAW_DOORS)
125 if (redraw_mask & REDRAW_DOOR_1)
126 XCopyArea(display,backbuffer,window,gc,
127 DX,DY, DXSIZE,DYSIZE,
129 if (redraw_mask & REDRAW_DOOR_2)
131 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
132 XCopyArea(display,backbuffer,window,gc,
133 VX,VY, VXSIZE,VYSIZE,
137 if (redraw_mask & REDRAW_VIDEO_1)
138 XCopyArea(display,backbuffer,window,gc,
139 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
140 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
141 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
142 if (redraw_mask & REDRAW_VIDEO_2)
143 XCopyArea(display,backbuffer,window,gc,
144 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
145 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
146 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
147 if (redraw_mask & REDRAW_VIDEO_3)
148 XCopyArea(display,backbuffer,window,gc,
149 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
150 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
151 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
154 redraw_mask &= ~REDRAW_DOORS;
157 if (redraw_mask & REDRAW_MICROLEV)
159 XCopyArea(display,backbuffer,window,gc,
160 MICROLEV_XPOS,MICROLEV_YPOS, MICROLEV_XSIZE,MICROLEV_YSIZE,
161 MICROLEV_XPOS,MICROLEV_YPOS);
162 XCopyArea(display,backbuffer,window,gc,
163 SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE,
165 redraw_mask &= ~REDRAW_MICROLEV;
168 if (redraw_mask & REDRAW_TILES)
170 for(x=0; x<SCR_FIELDX; x++)
171 for(y=0; y<SCR_FIELDY; y++)
172 if (redraw[redraw_x1 + x][redraw_y1 + y])
173 XCopyArea(display,buffer,window,gc,
174 FX+x*TILEX,FX+y*TILEY, TILEX,TILEY,
175 SX+x*TILEX,SY+y*TILEY);
180 for(x=0; x<MAX_BUF_XSIZE; x++)
181 for(y=0; y<MAX_BUF_YSIZE; y++)
190 long fading_delay = 300000;
192 if (fading_on && (redraw_mask & REDRAW_FIELD))
199 XFillRectangle(display,window,gc,
200 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
203 for(i=0;i<2*FULL_SYSIZE;i++)
205 for(y=0;y<FULL_SYSIZE;y++)
207 XCopyArea(display,backbuffer,window,gc,
208 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
216 for(i=1;i<FULL_SYSIZE;i+=2)
217 XCopyArea(display,backbuffer,window,gc,
218 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
224 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
225 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
226 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
230 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
231 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
232 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
236 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
237 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
238 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
242 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
243 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
244 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
248 redraw_mask &= ~REDRAW_MAIN;
257 XFillRectangle(display,backbuffer,gc,
258 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
260 if (soft_scrolling_on && game_status==PLAYING)
262 XFillRectangle(display,fieldbuffer,gc,
264 SetDrawtoField(DRAW_BUFFERED);
267 SetDrawtoField(DRAW_BACKBUFFER);
269 if (direct_draw_on && game_status==PLAYING)
271 XFillRectangle(display,window,gc,
272 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
273 SetDrawtoField(DRAW_DIRECT);
276 redraw_mask |= REDRAW_FIELD;
279 void DrawText(int x, int y, char *text, int font, int col)
281 DrawTextExt(drawto, gc, x, y, text, font, col);
283 redraw_mask |= REDRAW_FIELD;
285 redraw_mask |= REDRAW_DOOR_1;
288 void DrawTextExt(Drawable d, GC gc, int x, int y,
289 char *text, int font, int font_color)
291 int font_width, font_height, font_start;
294 if (font!=FS_SMALL && font!=FS_BIG)
296 if (font_color<FC_RED || font_color>FC_SPECIAL2)
300 (font==FS_BIG ? FONT1_XSIZE :
301 font_color<FC_SPECIAL1 ? FONT2_XSIZE :
302 font_color<FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
304 (font==FS_BIG ? FONT1_XSIZE :
305 font_color<FC_SPECIAL2 ? FONT2_XSIZE: FONT4_XSIZE);
306 font_pixmap = (font==FS_BIG ? PIX_BIGFONT : PIX_SMALLFONT);
308 font_color*(font==FS_BIG ? FONT1_YSIZE : FONT2_YSIZE)*FONT_LINES_PER_FONT;
314 if (c>='a' && c<='z')
316 else if (c=='ä' || c=='Ä')
318 else if (c=='ö' || c=='Ö')
320 else if (c=='ü' || c=='Ü')
324 XCopyArea(display,pix[font_pixmap],d,gc,
325 ((c-32) % FONT_CHARS_PER_LINE)*font_width,
326 ((c-32) / FONT_CHARS_PER_LINE)*font_height + font_start,
327 font_width,font_height, x,y);
333 void DrawPlayerField()
336 int sx = SCROLLX(x), sy = SCROLLY(y);
338 int sxx = 0, syy = 0;
340 int element = Feld[x][y];
347 if (!IN_LEV_FIELD(x,y) || !IN_SCR_FIELD(sx,sy))
349 printf("DrawPlayerField(): x = %d, y = %d\n",x,y);
350 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
351 printf("DrawPlayerField(): This should never happen!\n");
356 if (element == EL_EXPLODING)
360 SetDrawtoField(DRAW_BUFFERED);
362 /* draw things in the field the player is leaving, if needed */
364 if (lastJX != JX || lastJY != JY)
366 if (Store[lastJX][lastJY])
368 DrawLevelElement(lastJX,lastJY, Store[lastJX][lastJY]);
369 DrawLevelElementThruMask(lastJX,lastJY, Feld[lastJX][lastJY]);
371 else if (Feld[lastJX][lastJY] == EL_DYNAMIT)
372 DrawDynamite(lastJX,lastJY);
374 DrawLevelField(lastJX,lastJY);
378 int nextJX = JX + (JX - lastJX);
379 int nextJY = JY + (JY - lastJY);
383 if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
384 DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER);
386 DrawLevelElement(nextJX,nextJY, EL_LEERRAUM);
389 DrawLevelField(nextJX,nextJY);
393 /* draw things behind the player, if needed */
396 DrawLevelElement(x,y, Store[x][y]);
397 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
400 /* draw player himself */
402 if (PlayerMovDir==MV_LEFT)
403 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT);
404 else if (PlayerMovDir==MV_RIGHT)
405 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT);
406 else if (PlayerMovDir==MV_UP)
407 graphic = GFX_SPIELER_UP;
408 else /* MV_DOWN || MV_NO_MOVING */
409 graphic = GFX_SPIELER_DOWN;
411 graphic += PlayerFrame;
415 if (PlayerMovDir == MV_LEFT || PlayerMovDir == MV_RIGHT)
421 if (!soft_scrolling_on && ScreenMovPos)
424 DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING);
426 if (PlayerPushing && PlayerGfxPos)
428 int nextJX = JX + (JX - lastJX);
429 int nextJY = JY + (JY - lastJY);
430 int px = SCROLLX(nextJX), py = SCROLLY(nextJY);
432 if (Feld[JX][JY] == EL_SOKOBAN_FELD_LEER ||
433 Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
434 DrawGraphicShiftedThruMask(px,py,sxx,syy, GFX_SOKOBAN_OBJEKT,NO_CUTTING);
437 int element = Feld[nextJX][nextJY];
438 int graphic = el2gfx(element);
440 if (element == EL_FELSBROCKEN && sxx)
442 int phase = (PlayerGfxPos / (TILEX/4));
444 if (PlayerMovDir == MV_LEFT)
447 graphic += (phase+4)%4;
450 DrawGraphicShifted(px,py, sxx,syy, graphic, NO_CUTTING, NO_MASKING);
454 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
456 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
458 graphic = el2gfx(element);
460 if (element == EL_DYNAMIT)
462 if ((phase = (96-MovDelay[x][y])/12) > 6)
467 if ((phase = ((96-MovDelay[x][y])/6) % 8) > 3)
471 DrawGraphicThruMask(sx,sy, graphic + phase);
476 int dest_x = SX+SCROLLX(x)*TILEX;
477 int dest_y = SY+SCROLLY(y)*TILEY;
483 dest_x = SX + SCROLLX(MIN(JX,lastJX))*TILEX;
484 dest_y = SY + SCROLLY(MIN(JY,lastJY))*TILEY;
485 x_size = TILEX * (1 + ABS(JX - lastJX));
486 y_size = TILEY * (1 + ABS(JY - lastJY));
489 XCopyArea(display,drawto_field,window,gc,
490 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
491 SetDrawtoField(DRAW_DIRECT);
494 MarkTileDirty(sx,sy);
497 static int getGraphicAnimationPhase(int frames, int delay, int mode)
501 if (mode == ANIM_OSCILLATE)
503 int max_anim_frames = frames*2 - 2;
504 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
505 phase = (phase < frames ? phase : max_anim_frames - phase);
508 phase = (FrameCounter % (delay * frames)) / delay;
510 if (mode == ANIM_REVERSE)
516 void DrawGraphicAnimation(int x, int y, int graphic,
517 int frames, int delay, int mode)
519 int phase = getGraphicAnimationPhase(frames, delay, mode);
521 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
522 DrawGraphic(SCROLLX(x),SCROLLY(y), graphic + phase);
525 void DrawGraphic(int x, int y, int graphic)
529 if (!IN_SCR_FIELD(x,y))
531 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
532 printf("DrawGraphic(): This should never happen!\n");
537 DrawGraphicExt(drawto_field, gc, x, y, graphic);
541 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
543 DrawGraphicExtHiRes(d, gc, FX+x*TILEX, FY+y*TILEY, graphic);
546 void DrawGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
548 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
550 graphic -= GFX_START_ROCKSSCREEN;
551 XCopyArea(display,pix[PIX_BACK],d,gc,
552 SX+(graphic % GFX_PER_LINE)*TILEX,
553 SY+(graphic / GFX_PER_LINE)*TILEY,
556 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
558 graphic -= GFX_START_ROCKSHEROES;
559 XCopyArea(display,pix[PIX_HEROES],d,gc,
560 (graphic % HEROES_PER_LINE)*TILEX,
561 (graphic / HEROES_PER_LINE)*TILEY,
564 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
566 graphic -= GFX_START_ROCKSFONT;
567 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
568 (graphic % FONT_CHARS_PER_LINE)*TILEX,
569 (graphic / FONT_CHARS_PER_LINE)*TILEY +
570 FC_SPECIAL1*TILEY*FONT_LINES_PER_FONT,
574 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
577 void DrawGraphicThruMask(int x, int y, int graphic)
579 int src_x,src_y, dest_x,dest_y;
582 if (!IN_SCR_FIELD(x,y))
584 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
585 printf("DrawGraphicThruMask(): This should never happen!\n");
590 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
592 graphic -= GFX_START_ROCKSSCREEN;
593 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
594 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
598 XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y);
599 XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK],
600 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
602 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
604 graphic -= GFX_START_ROCKSHEROES;
605 src_x = (graphic % HEROES_PER_LINE)*TILEX;
606 src_y = (graphic / HEROES_PER_LINE)*TILEY;
610 XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
611 XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
612 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
616 DrawGraphic(x,y,graphic);
623 void DrawScreenElementThruMask(int x, int y, int element)
625 DrawGraphicThruMask(x,y,el2gfx(element));
628 void DrawLevelElementThruMask(int x, int y, int element)
630 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
631 DrawScreenElementThruMask(SCROLLX(x),SCROLLY(y),element);
634 void DrawMiniGraphic(int x, int y, int graphic)
636 DrawMiniGraphicExt(drawto, gc, x, y, graphic);
637 MarkTileDirty(x/2, y/2);
640 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
642 DrawMiniGraphicExtHiRes(d,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
645 void DrawMiniGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
647 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
649 graphic -= GFX_START_ROCKSSCREEN;
650 XCopyArea(display,pix[PIX_BACK],d,gc,
651 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
652 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
653 MINI_TILEX,MINI_TILEY, x,y);
655 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
657 graphic -= GFX_START_ROCKSFONT;
658 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
659 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
660 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
661 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
662 MINI_TILEX,MINI_TILEY, x,y);
665 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
668 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
669 int cut_mode, int mask_mode)
671 int width = TILEX, height = TILEY;
673 int src_x,src_y, dest_x,dest_y;
677 DrawGraphic(x,y,graphic);
681 if (dx || dy) /* Verschiebung der Grafik? */
683 if (x < BX1) /* Element kommt von links ins Bild */
690 else if (x > BX2) /* Element kommt von rechts ins Bild */
696 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
702 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
704 else if (dx) /* allg. Bewegung in x-Richtung */
705 MarkTileDirty(x + SIGN(dx), y);
707 if (y < BY1) /* Element kommt von oben ins Bild */
709 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
717 else if (y > BY2) /* Element kommt von unten ins Bild */
723 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
729 else if (dy > 0 && cut_mode==CUT_ABOVE)
731 if (y == BY2) /* Element unterhalb des Bildes */
737 MarkTileDirty(x, y + 1);
738 } /* Element verläßt unten das Bild */
739 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
741 else if (dy) /* allg. Bewegung in y-Richtung */
742 MarkTileDirty(x, y + SIGN(dy));
745 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
747 graphic -= GFX_START_ROCKSSCREEN;
748 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
749 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
750 dest_x = FX+x*TILEX+dx;
751 dest_y = FY+y*TILEY+dy;
753 if (mask_mode == USE_MASKING)
755 XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y);
756 XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK],
757 src_x,src_y, width,height, dest_x,dest_y);
760 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
761 src_x,src_y, width,height, dest_x,dest_y);
763 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
765 graphic -= GFX_START_ROCKSHEROES;
766 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
767 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
768 dest_x = FX+x*TILEX+dx;
769 dest_y = FY+y*TILEY+dy;
771 if (mask_mode == USE_MASKING)
773 XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
774 XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
775 src_x,src_y, width,height, dest_x,dest_y);
778 XCopyArea(display,pix[PIX_HEROES],drawto_field,gc,
779 src_x,src_y, width,height, dest_x,dest_y);
783 if (!IN_SCR_FIELD(x,y))
785 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
786 printf("DrawGraphicShifted(): This should never happen!\n");
794 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
797 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
800 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
803 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
804 int graphic = el2gfx(element);
805 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
806 int phase = phase4 / 2;
807 int dir = MovDir[ux][uy];
809 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
815 else if (dir == MV_LEFT)
817 else if (dir == MV_DOWN)
820 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
821 element==EL_SCHWEIN || element==EL_DRACHE)
824 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
825 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
826 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
827 else if (dir==MV_RIGHT)
828 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
829 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
830 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
832 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
833 element==EL_PINGUIN ? GFX_PINGUIN_UP :
834 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
836 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
837 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
838 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
842 else if (element==EL_SONDE)
844 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
846 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
850 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
852 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
854 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
855 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
857 graphic += 3-(SiebAktiv%8)/2;
859 else if (IS_AMOEBOID(element))
861 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
862 graphic += (x+2*y) % 4;
864 else if (element==EL_MAUER_LEBT)
866 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
868 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
870 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
871 rechts_massiv = TRUE;
873 if (links_massiv && rechts_massiv)
874 graphic = GFX_MAUERWERK;
875 else if (links_massiv)
876 graphic = GFX_MAUER_R;
877 else if (rechts_massiv)
878 graphic = GFX_MAUER_L;
882 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, NO_MASKING);
884 DrawGraphic(x,y, graphic);
887 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
890 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
891 DrawScreenElementShifted(SCROLLX(x),SCROLLY(y), dx,dy, element, cut_mode);
894 void ErdreichAnbroeckeln(int x, int y)
896 int i, width, height, cx,cy;
897 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
898 int element, graphic;
900 static int xy[4][2] =
908 if (!IN_LEV_FIELD(ux,uy))
911 element = Feld[ux][uy];
913 if (element==EL_ERDREICH)
915 if (!IN_SCR_FIELD(x,y))
918 graphic = GFX_ERDENRAND;
926 if (!IN_LEV_FIELD(uxx,uyy))
929 element = Feld[uxx][uyy];
931 if (element==EL_ERDREICH)
938 cx = (i==2 ? TILEX-snip : 0);
946 cy = (i==3 ? TILEY-snip : 0);
949 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
950 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
951 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
952 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
959 graphic = GFX_ERDENRAND;
970 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
971 !IN_SCR_FIELD(xx,yy))
978 cx = (i==1 ? TILEX-snip : 0);
986 cy = (i==0 ? TILEY-snip : 0);
989 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
990 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
991 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
992 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
994 MarkTileDirty(xx,yy);
999 void DrawScreenElement(int x, int y, int element)
1001 DrawScreenElementShifted(x,y, 0,0, element, NO_CUTTING);
1002 ErdreichAnbroeckeln(x,y);
1005 void DrawLevelElement(int x, int y, int element)
1007 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1008 DrawScreenElement(SCROLLX(x),SCROLLY(y),element);
1011 void DrawScreenField(int x, int y)
1013 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
1016 if (!IN_LEV_FIELD(ux,uy))
1018 DrawScreenElement(x,y,EL_BETON);
1022 element = Feld[ux][uy];
1024 if (IS_MOVING(ux,uy))
1026 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1027 BOOL cut_mode = NO_CUTTING;
1029 if (Store[ux][uy]==EL_MORAST_LEER ||
1030 Store[ux][uy]==EL_SIEB_LEER ||
1031 Store[ux][uy]==EL_SIEB2_LEER ||
1032 Store[ux][uy]==EL_AMOEBE_NASS)
1033 cut_mode = CUT_ABOVE;
1034 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1035 Store[ux][uy]==EL_SIEB_VOLL ||
1036 Store[ux][uy]==EL_SIEB2_VOLL ||
1037 Store[ux][uy]==EL_SALZSAEURE)
1038 cut_mode = CUT_BELOW;
1040 if (cut_mode==CUT_ABOVE)
1041 DrawScreenElementShifted(x,y, 0,0, Store[ux][uy], NO_CUTTING);
1043 DrawScreenElement(x,y,EL_LEERRAUM);
1046 DrawScreenElementShifted(x,y, MovPos[ux][uy],0, element, NO_CUTTING);
1048 DrawScreenElementShifted(x,y, 0,MovPos[ux][uy], element, cut_mode);
1050 else if (IS_BLOCKED(ux,uy))
1055 BOOL cut_mode = NO_CUTTING;
1057 Blocked2Moving(ux,uy,&oldx,&oldy);
1060 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1062 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1063 Store[oldx][oldy]==EL_SIEB_LEER ||
1064 Store[oldx][oldy]==EL_SIEB2_LEER ||
1065 Store[oldx][oldy]==EL_AMOEBE_NASS)
1066 cut_mode = CUT_ABOVE;
1068 DrawScreenElement(x,y,EL_LEERRAUM);
1069 element = Feld[oldx][oldy];
1072 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1074 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1076 else if (IS_DRAWABLE(element))
1077 DrawScreenElement(x,y,element);
1079 DrawScreenElement(x,y,EL_LEERRAUM);
1082 void DrawLevelField(int x, int y)
1084 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1085 DrawScreenField(SCROLLX(x),SCROLLY(y));
1086 else if (IS_MOVING(x,y))
1090 Moving2Blocked(x,y,&newx,&newy);
1091 if (IN_SCR_FIELD(SCROLLX(newx),SCROLLY(newy)))
1092 DrawScreenField(SCROLLX(newx),SCROLLY(newy));
1094 else if (IS_BLOCKED(x,y))
1098 Blocked2Moving(x,y,&oldx,&oldy);
1099 if (IN_SCR_FIELD(SCROLLX(oldx),SCROLLY(oldy)))
1100 DrawScreenField(SCROLLX(oldx),SCROLLY(oldy));
1104 void DrawMiniElement(int x, int y, int element)
1110 DrawMiniGraphic(x,y,-1);
1114 graphic = el2gfx(element);
1115 DrawMiniGraphic(x,y,graphic);
1118 void DrawMiniElementOrWall(int x, int y, int scroll_x, int scroll_y)
1120 if (x+scroll_x<-1 || x+scroll_x>lev_fieldx ||
1121 y+scroll_y<-1 || y+scroll_y>lev_fieldy)
1122 DrawMiniElement(x,y,EL_LEERRAUM);
1123 else if (x+scroll_x==-1 || x+scroll_x==lev_fieldx ||
1124 y+scroll_y==-1 || y+scroll_y==lev_fieldy)
1125 DrawMiniElement(x,y,EL_BETON);
1127 DrawMiniElement(x,y,Feld[x+scroll_x][y+scroll_y]);
1130 void DrawMicroElement(int xpos, int ypos, int element)
1134 if (element==EL_LEERRAUM)
1137 graphic = el2gfx(element);
1139 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1140 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1141 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1142 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1151 for(x=BX1; x<=BX2; x++)
1152 for(y=BY1; y<=BY2; y++)
1153 DrawScreenField(x,y);
1155 if (soft_scrolling_on)
1156 XCopyArea(display,fieldbuffer,backbuffer,gc,
1157 FX,FY, SXSIZE,SYSIZE,
1160 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1163 void DrawMiniLevel(int scroll_x, int scroll_y)
1169 for(x=0;x<2*SCR_FIELDX;x++)
1170 for(y=0;y<2*SCR_FIELDY;y++)
1171 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1173 redraw_mask |= REDRAW_FIELD;
1176 void DrawMicroLevel(int xpos, int ypos)
1180 XFillRectangle(display,drawto,gc,
1181 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1182 MICRO_TILEX*(STD_LEV_FIELDX+2),
1183 MICRO_TILEY*(STD_LEV_FIELDY+2));
1184 if (lev_fieldx < STD_LEV_FIELDX)
1185 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1186 if (lev_fieldy < STD_LEV_FIELDY)
1187 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1189 for(x=-1;x<=STD_LEV_FIELDX;x++)
1190 for(y=-1;y<=STD_LEV_FIELDY;y++)
1191 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1192 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1193 Feld[x][y]=Ur[x][y]);
1194 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1195 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1198 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1202 int len = strlen(level.name);
1203 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1204 int lypos = MICROLABEL_YPOS;
1206 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1209 redraw_mask |= REDRAW_MICROLEV;
1212 int AYS_in_range(int x, int y)
1214 if (y>DY+249 && y<DY+278)
1216 if (x>DX+1 && x<DX+48)
1218 else if (x>DX+51 && x<DX+98)
1224 BOOL AreYouSure(char *text, unsigned int ays_state)
1226 int mx,my, ty, result = -1;
1227 unsigned int old_door_state;
1229 old_door_state = GetDoorState();
1231 CloseDoor(DOOR_CLOSE_1);
1233 /* Alten Türinhalt sichern */
1234 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1235 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1236 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1238 /* Fragetext schreiben */
1239 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1240 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1242 for(ty=0;ty<13;ty++)
1249 for(tl=0,tx=0;tx<7;tl++,tx++)
1263 DrawTextExt(pix[PIX_DB_DOOR],gc,
1264 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1265 text+=(tl+(tc==32));
1268 if (ays_state & AYS_ASK)
1269 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1270 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1271 DXSIZE,OK_BUTTON_YSIZE,
1272 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1273 else if (ays_state & AYS_CONFIRM)
1274 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1275 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1276 DXSIZE,CONFIRM_BUTTON_YSIZE,
1277 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1279 OpenDoor(DOOR_OPEN_1);
1282 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1285 if (game_status != MAINMENU)
1288 button_status = MB_RELEASED;
1295 if (XPending(display))
1299 XNextEvent(display, &event);
1303 HandleExposeEvent((XExposeEvent *) &event);
1306 SleepWhileUnmapped();
1314 if (event.type == MotionNotify)
1316 motion_status = TRUE;
1317 mx = ((XMotionEvent *) &event)->x;
1318 my = ((XMotionEvent *) &event)->y;
1322 motion_status = FALSE;
1323 mx = ((XButtonEvent *) &event)->x;
1324 my = ((XButtonEvent *) &event)->y;
1325 if (event.type==ButtonPress)
1326 button_status = ((XButtonEvent *) &event)->button;
1328 button_status = MB_RELEASED;
1331 if (ays_state & AYS_ASK)
1332 choice = CheckChooseButtons(mx,my,button_status);
1334 choice = CheckConfirmButton(mx,my,button_status);
1344 case BUTTON_CONFIRM:
1345 result = TRUE|FALSE;
1353 switch(XLookupKeysym((XKeyEvent *)&event,
1354 ((XKeyEvent *)&event)->state))
1365 key_joystick_mapping = 0;
1369 HandleFocusEvent((XFocusChangeEvent *) &event);
1372 HandleClientMessageEvent((XClientMessageEvent *) &event);
1378 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1382 if (joy & JOY_BUTTON_1)
1384 else if (joy & JOY_BUTTON_2)
1389 if (game_status != MAINMENU)
1392 if (!(ays_state & AYS_STAY_OPEN))
1394 CloseDoor(DOOR_CLOSE_1);
1396 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1398 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1399 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1400 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1401 OpenDoor(DOOR_OPEN_1);
1408 unsigned int OpenDoor(unsigned int door_state)
1410 unsigned int new_door_state;
1412 if (door_state & DOOR_COPY_BACK)
1414 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1415 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1416 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1417 door_state &= ~DOOR_COPY_BACK;
1420 new_door_state = MoveDoor(door_state);
1422 return(new_door_state);
1425 unsigned int CloseDoor(unsigned int door_state)
1427 unsigned int new_door_state;
1429 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1430 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1431 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1432 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1434 new_door_state = MoveDoor(door_state);
1436 return(new_door_state);
1439 unsigned int GetDoorState()
1441 return(MoveDoor(DOOR_GET_STATE));
1444 unsigned int MoveDoor(unsigned int door_state)
1446 static unsigned int door1 = DOOR_OPEN_1;
1447 static unsigned int door2 = DOOR_CLOSE_2;
1448 static long door_delay = 0;
1449 int x, start, stepsize = 2;
1450 long door_delay_value = stepsize * 5000;
1452 if (door_state == DOOR_GET_STATE)
1453 return(door1 | door2);
1455 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1456 door_state &= ~DOOR_OPEN_1;
1457 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1458 door_state &= ~DOOR_CLOSE_1;
1459 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1460 door_state &= ~DOOR_OPEN_2;
1461 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1462 door_state &= ~DOOR_CLOSE_2;
1467 door_delay_value = 0;
1468 StopSound(SND_OEFFNEN);
1471 if (door_state & DOOR_ACTION)
1473 if (!(door_state & DOOR_NO_DELAY))
1474 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1476 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1478 for(x=start; x<=DXSIZE; x+=stepsize)
1480 while(!DelayReached(&door_delay, door_delay_value/10000))
1483 if (door_state & DOOR_ACTION_1)
1485 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1486 int j = (DXSIZE - i)/3;
1488 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1489 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1490 DXSIZE,DYSIZE-i/2, DX,DY);
1492 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1494 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1495 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1496 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1497 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1498 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1499 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1500 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1501 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1502 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1503 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1504 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1505 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1507 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1508 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1510 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1511 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1513 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1514 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1515 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1516 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1517 DX+DXSIZE-i,DY+77+j);
1518 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1519 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1520 DX+DXSIZE-i,DY+203+j);
1522 redraw_mask |= REDRAW_DOOR_1;
1525 if (door_state & DOOR_ACTION_2)
1527 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1528 int j = (VXSIZE - i)/3;
1530 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1531 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1532 VXSIZE,VYSIZE-i/2, VX,VY);
1534 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1536 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1537 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1538 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1539 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1540 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1541 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1542 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1543 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1545 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1546 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1548 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1549 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1550 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1551 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1552 VX+VXSIZE-i,VY+VYSIZE/2+j);
1554 redraw_mask |= REDRAW_DOOR_2;
1559 if (game_status == MAINMENU)
1564 if (door_state & DOOR_ACTION_1)
1565 door1 = door_state & DOOR_ACTION_1;
1566 if (door_state & DOOR_ACTION_2)
1567 door2 = door_state & DOOR_ACTION_2;
1569 return(door1 | door2);
1572 int ReadPixel(Drawable d, int x, int y)
1574 static XImage *pixelimage;
1576 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1577 return(XGetPixel(pixelimage,0,0));
1580 int el2gfx(int element)
1584 case EL_LEERRAUM: return(-1);
1585 case EL_ERDREICH: return(GFX_ERDREICH);
1586 case EL_MAUERWERK: return(GFX_MAUERWERK);
1587 case EL_FELSBODEN: return(GFX_FELSBODEN);
1588 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1589 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1590 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1591 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1592 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1593 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1594 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1595 case EL_SPIELER1: return(GFX_SPIELER1);
1596 case EL_SPIELER2: return(GFX_SPIELER2);
1597 case EL_SPIELER3: return(GFX_SPIELER3);
1598 case EL_SPIELER4: return(GFX_SPIELER4);
1599 case EL_KAEFER: return(GFX_KAEFER);
1600 case EL_KAEFER_R: return(GFX_KAEFER_R);
1601 case EL_KAEFER_O: return(GFX_KAEFER_O);
1602 case EL_KAEFER_L: return(GFX_KAEFER_L);
1603 case EL_KAEFER_U: return(GFX_KAEFER_U);
1604 case EL_FLIEGER: return(GFX_FLIEGER);
1605 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1606 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1607 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1608 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1609 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1610 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1611 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1612 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1613 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1614 case EL_FIREFLY: return(GFX_FIREFLY);
1615 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1616 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1617 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1618 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1619 case EL_MAMPFER: return(GFX_MAMPFER);
1620 case EL_ROBOT: return(GFX_ROBOT);
1621 case EL_BETON: return(GFX_BETON);
1622 case EL_DIAMANT: return(GFX_DIAMANT);
1623 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1624 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1625 case EL_TROPFEN: return(GFX_TROPFEN);
1626 case EL_BOMBE: return(GFX_BOMBE);
1627 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1628 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1629 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1630 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1631 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1632 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1633 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1634 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1635 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1636 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1637 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1638 case EL_LIFE: return(GFX_LIFE);
1639 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1640 case EL_DYNAMIT: return(GFX_DYNAMIT);
1641 case EL_BADEWANNE: return(GFX_BADEWANNE);
1642 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1643 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1644 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1645 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1646 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1647 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1648 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1649 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1650 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1651 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1652 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1653 case EL_PFORTE1: return(GFX_PFORTE1);
1654 case EL_PFORTE2: return(GFX_PFORTE2);
1655 case EL_PFORTE3: return(GFX_PFORTE3);
1656 case EL_PFORTE4: return(GFX_PFORTE4);
1657 case EL_PFORTE1X: return(GFX_PFORTE1X);
1658 case EL_PFORTE2X: return(GFX_PFORTE2X);
1659 case EL_PFORTE3X: return(GFX_PFORTE3X);
1660 case EL_PFORTE4X: return(GFX_PFORTE4X);
1661 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1662 case EL_PACMAN: return(GFX_PACMAN);
1663 case EL_PACMAN_R: return(GFX_PACMAN_R);
1664 case EL_PACMAN_O: return(GFX_PACMAN_O);
1665 case EL_PACMAN_L: return(GFX_PACMAN_L);
1666 case EL_PACMAN_U: return(GFX_PACMAN_U);
1667 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1668 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1669 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1670 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1671 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1672 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1673 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1674 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1675 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1676 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1677 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1678 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1679 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1680 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1681 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1682 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1683 case EL_MAMPFER2: return(GFX_MAMPFER2);
1684 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1685 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1686 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1687 case EL_DYNABOMB: return(GFX_DYNABOMB);
1688 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1689 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1690 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1691 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1692 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1693 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1694 case EL_MAULWURF: return(GFX_MAULWURF);
1695 case EL_PINGUIN: return(GFX_PINGUIN);
1696 case EL_SCHWEIN: return(GFX_SCHWEIN);
1697 case EL_DRACHE: return(GFX_DRACHE);
1698 case EL_SONDE: return(GFX_SONDE);
1699 case EL_PFEIL_L: return(GFX_PFEIL_L);
1700 case EL_PFEIL_R: return(GFX_PFEIL_R);
1701 case EL_PFEIL_O: return(GFX_PFEIL_O);
1702 case EL_PFEIL_U: return(GFX_PFEIL_U);
1705 if (IS_CHAR(element))
1706 return(GFX_CHAR_START + (element-EL_CHAR_START));