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];
342 BOOL draw_thru_mask = FALSE;
348 if (!IN_LEV_FIELD(x,y) || !IN_SCR_FIELD(sx,sy))
350 printf("DrawPlayerField(): x = %d, y = %d\n",x,y);
351 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
352 printf("DrawPlayerField(): This should never happen!\n");
357 if (element == EL_EXPLODING)
361 SetDrawtoField(DRAW_BUFFERED);
363 /* draw things behind the player (EL_PFORTE* || mole/penguin/pig/dragon) */
374 DrawGraphic(sx,sy, el2gfx(Store[x][y]));
375 draw_thru_mask = TRUE;
377 else if (element!=EL_DYNAMIT && element!=EL_DYNABOMB)
380 draw_thru_mask = TRUE;
384 else if (element!=EL_LEERRAUM && element!=EL_DYNAMIT && element!=EL_DYNABOMB)
387 draw_thru_mask = TRUE;
392 draw_thru_mask = TRUE;
397 /* draw player himself */
399 if (PlayerMovDir==MV_LEFT)
400 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT);
401 else if (PlayerMovDir==MV_RIGHT)
402 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT);
403 else if (PlayerMovDir==MV_UP)
404 graphic = GFX_SPIELER_UP;
405 else /* MV_DOWN || MV_NO_MOVING */
406 graphic = GFX_SPIELER_DOWN;
408 graphic += PlayerFrame;
413 if (PlayerMovDir == MV_LEFT || PlayerMovDir == MV_RIGHT)
420 if (!soft_scrolling_on && ScreenMovPos)
429 DrawGraphicShiftedThruMask(sx,sy,sxx,syy,graphic,CUT_NO_CUTTING);
431 DrawGraphicThruMask(sx, sy, graphic);
434 DrawGraphicShifted(sx,sy,sxx,syy,graphic,CUT_NO_CUTTING);
436 DrawGraphic(sx, sy, graphic);
441 MarkTileDirty(sx,sy);
445 if (PlayerPushing && PlayerGfxPos)
447 int nextJX = JX + (JX - lastJX);
448 int nextJY = JY + (JY - lastJY);
449 int px = SCROLLX(nextJX), py = SCROLLY(nextJY);
451 if (Feld[JX][JY] == EL_SOKOBAN_FELD_LEER ||
452 Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
453 DrawGraphicShiftedThruMask(px,py,sxx,syy,
458 int element = Feld[nextJX][nextJY];
459 int graphic = el2gfx(element);
461 if (element == EL_FELSBROCKEN && sxx)
463 int phase = (PlayerGfxPos / (TILEX/4));
465 if (PlayerMovDir == MV_LEFT)
468 graphic += (phase+4)%4;
472 printf("----> (%d, %d, %d)\n",
473 PlayerGfxPos, phase, graphic);
478 DrawGraphicShifted(px,py, sxx,syy, graphic, CUT_NO_CUTTING);
484 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
486 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
488 graphic = el2gfx(element);
490 if (element == EL_DYNAMIT)
492 if ((phase = (96-MovDelay[x][y])/12) > 6)
497 if ((phase = ((96-MovDelay[x][y])/6) % 8) > 3)
501 DrawGraphicThruMask(sx,sy, graphic + phase);
506 int dest_x = SX+SCROLLX(x)*TILEX;
507 int dest_y = SY+SCROLLY(y)*TILEY;
513 dest_x = SX + SCROLLX(MIN(JX,lastJX))*TILEX;
514 dest_y = SY + SCROLLY(MIN(JY,lastJY))*TILEY;
515 x_size = TILEX * (1 + ABS(JX - lastJX));
516 y_size = TILEY * (1 + ABS(JY - lastJY));
519 XCopyArea(display,drawto_field,window,gc,
520 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
521 SetDrawtoField(DRAW_DIRECT);
525 static int getGraphicAnimationPhase(int frames, int delay, int mode)
529 if (mode == ANIM_OSCILLATE)
531 int max_anim_frames = frames*2 - 2;
532 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
533 phase = (phase < frames ? phase : max_anim_frames - phase);
536 phase = (FrameCounter % (delay * frames)) / delay;
538 if (mode == ANIM_REVERSE)
544 void DrawGraphicAnimation(int x, int y, int graphic,
545 int frames, int delay, int mode)
547 int phase = getGraphicAnimationPhase(frames, delay, mode);
549 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
550 DrawGraphic(SCROLLX(x),SCROLLY(y), graphic + phase);
553 void DrawGraphic(int x, int y, int graphic)
557 if (!IN_SCR_FIELD(x,y))
559 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
560 printf("DrawGraphic(): This should never happen!\n");
565 DrawGraphicExt(drawto_field, gc, x, y, graphic);
569 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
571 DrawGraphicExtHiRes(d, gc, FX+x*TILEX, FY+y*TILEY, graphic);
574 void DrawGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
576 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
578 graphic -= GFX_START_ROCKSSCREEN;
579 XCopyArea(display,pix[PIX_BACK],d,gc,
580 SX+(graphic % GFX_PER_LINE)*TILEX,
581 SY+(graphic / GFX_PER_LINE)*TILEY,
584 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
586 graphic -= GFX_START_ROCKSHEROES;
587 XCopyArea(display,pix[PIX_HEROES],d,gc,
588 (graphic % HEROES_PER_LINE)*TILEX,
589 (graphic / HEROES_PER_LINE)*TILEY,
592 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
594 graphic -= GFX_START_ROCKSFONT;
595 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
596 (graphic % FONT_CHARS_PER_LINE)*TILEX,
597 (graphic / FONT_CHARS_PER_LINE)*TILEY +
598 FC_SPECIAL1*TILEY*FONT_LINES_PER_FONT,
602 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
605 void DrawGraphicThruMask(int x, int y, int graphic)
607 int src_x,src_y, dest_x,dest_y;
610 if (!IN_SCR_FIELD(x,y))
612 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
613 printf("DrawGraphicThruMask(): This should never happen!\n");
618 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
620 graphic -= GFX_START_ROCKSSCREEN;
621 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
622 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
626 XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y);
627 XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK],
628 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
630 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
632 graphic -= GFX_START_ROCKSHEROES;
633 src_x = (graphic % HEROES_PER_LINE)*TILEX;
634 src_y = (graphic / HEROES_PER_LINE)*TILEY;
638 XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
639 XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
640 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
644 DrawGraphic(x,y,graphic);
651 void DrawElementThruMask(int x, int y, int element)
653 DrawGraphicThruMask(x,y,el2gfx(element));
656 void DrawMiniGraphic(int x, int y, int graphic)
658 DrawMiniGraphicExt(drawto, gc, x, y, graphic);
659 MarkTileDirty(x/2, y/2);
662 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
664 DrawMiniGraphicExtHiRes(d,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
667 void DrawMiniGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
669 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
671 graphic -= GFX_START_ROCKSSCREEN;
672 XCopyArea(display,pix[PIX_BACK],d,gc,
673 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
674 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
675 MINI_TILEX,MINI_TILEY, x,y);
677 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
679 graphic -= GFX_START_ROCKSFONT;
680 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
681 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
682 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
683 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
684 MINI_TILEX,MINI_TILEY, x,y);
687 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
690 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, int cut_mode)
692 int width = TILEX, height = TILEY;
697 DrawGraphic(x,y,graphic);
701 if (dx || dy) /* Verschiebung der Grafik? */
703 if (x < BX1) /* Element kommt von links ins Bild */
710 else if (x > BX2) /* Element kommt von rechts ins Bild */
716 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
722 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
724 else if (dx) /* allg. Bewegung in x-Richtung */
725 MarkTileDirty(x + SIGN(dx), y);
727 if (y < BY1) /* Element kommt von oben ins Bild */
729 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
737 else if (y > BY2) /* Element kommt von unten ins Bild */
743 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
749 else if (dy > 0 && cut_mode==CUT_ABOVE)
751 if (y == BY2) /* Element unterhalb des Bildes */
757 MarkTileDirty(x, y + 1);
758 } /* Element verläßt unten das Bild */
759 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
761 else if (dy) /* allg. Bewegung in y-Richtung */
762 MarkTileDirty(x, y + SIGN(dy));
765 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
767 graphic -= GFX_START_ROCKSSCREEN;
768 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
769 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
770 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
771 width,height, FX+x*TILEX+dx,FY+y*TILEY+dy);
773 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
775 graphic -= GFX_START_ROCKSHEROES;
776 XCopyArea(display,pix[PIX_HEROES],drawto_field,gc,
777 (graphic % HEROES_PER_LINE)*TILEX+cx,
778 (graphic / HEROES_PER_LINE)*TILEY+cy,
779 width,height, FX+x*TILEX+dx,FY+y*TILEY+dy);
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 DrawElementShifted(int x, int y, int dx, int dy, int element,int cut_mode)
796 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
797 int graphic = el2gfx(element);
798 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
799 int phase = phase4 / 2;
800 int dir = MovDir[ux][uy];
802 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
808 else if (dir == MV_LEFT)
810 else if (dir == MV_DOWN)
813 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
814 element==EL_SCHWEIN || element==EL_DRACHE)
817 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
818 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
819 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
820 else if (dir==MV_RIGHT)
821 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
822 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
823 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
825 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
826 element==EL_PINGUIN ? GFX_PINGUIN_UP :
827 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
829 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
830 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
831 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
835 else if (element==EL_SONDE)
837 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
839 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
843 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
845 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
847 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
848 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
850 graphic += 3-(SiebAktiv%8)/2;
852 else if (IS_AMOEBOID(element))
854 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
855 graphic += (x+2*y) % 4;
857 else if (element==EL_MAUER_LEBT)
859 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
861 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
863 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
864 rechts_massiv = TRUE;
866 if (links_massiv && rechts_massiv)
867 graphic = GFX_MAUERWERK;
868 else if (links_massiv)
869 graphic = GFX_MAUER_R;
870 else if (rechts_massiv)
871 graphic = GFX_MAUER_L;
875 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode);
877 DrawGraphic(x,y, graphic);
880 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
883 int width = TILEX, height = TILEY;
885 int src_x,src_y, dest_x,dest_y;
889 DrawGraphic(x,y,graphic);
893 if (dx || dy) /* Verschiebung der Grafik? */
895 if (x < BX1) /* Element kommt von links ins Bild */
902 else if (x > BX2) /* Element kommt von rechts ins Bild */
908 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
914 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
916 else if (dx) /* allg. Bewegung in x-Richtung */
917 MarkTileDirty(x + SIGN(dx), y);
919 if (y < BY1) /* Element kommt von oben ins Bild */
921 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
929 else if (y > BY2) /* Element kommt von unten ins Bild */
935 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
941 else if (dy > 0 && cut_mode==CUT_ABOVE)
943 if (y == BY2) /* Element unterhalb des Bildes */
949 MarkTileDirty(x, y + 1);
950 } /* Element verläßt unten das Bild */
951 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
953 else if (dy) /* allg. Bewegung in y-Richtung */
954 MarkTileDirty(x, y + SIGN(dy));
957 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
959 graphic -= GFX_START_ROCKSSCREEN;
960 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
961 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
962 dest_x = FX+x*TILEX+dx;
963 dest_y = FY+y*TILEY+dy;
965 XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y);
966 XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK],
967 src_x,src_y, width,height, dest_x,dest_y);
969 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
971 graphic -= GFX_START_ROCKSHEROES;
972 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
973 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
974 dest_x = FX+x*TILEX+dx;
975 dest_y = FY+y*TILEY+dy;
977 XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
978 XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
979 src_x,src_y, width,height, dest_x,dest_y);
983 if (!IN_SCR_FIELD(x,y))
985 printf("DrawGraphicShiftedThruMask(): x = %d, y = %d, graphic = %d\n",
987 printf("DrawGraphicShifted(): This should never happen!\n");
995 void ErdreichAnbroeckeln(int x, int y)
997 int i, width, height, cx,cy;
998 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
999 int element, graphic;
1001 static int xy[4][2] =
1009 if (!IN_LEV_FIELD(ux,uy))
1012 element = Feld[ux][uy];
1014 if (element==EL_ERDREICH)
1016 if (!IN_SCR_FIELD(x,y))
1019 graphic = GFX_ERDENRAND;
1027 if (!IN_LEV_FIELD(uxx,uyy))
1030 element = Feld[uxx][uyy];
1033 if (element==EL_ERDREICH || IS_SOLID(element))
1036 if (element==EL_ERDREICH)
1043 cx = (i==2 ? TILEX-snip : 0);
1051 cy = (i==3 ? TILEY-snip : 0);
1054 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1055 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1056 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1057 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1064 graphic = GFX_ERDENRAND;
1075 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1076 !IN_SCR_FIELD(xx,yy) || IS_SOLID(element))
1080 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1081 !IN_SCR_FIELD(xx,yy))
1088 cx = (i==1 ? TILEX-snip : 0);
1096 cy = (i==0 ? TILEY-snip : 0);
1099 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1100 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1101 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1102 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1104 MarkTileDirty(xx,yy);
1109 void DrawScreenElement(int x, int y, int element)
1111 DrawElementShifted(x,y,0,0,element,CUT_NO_CUTTING);
1112 ErdreichAnbroeckeln(x,y);
1115 void DrawLevelElement(int x, int y, int element)
1117 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1118 DrawScreenElement(SCROLLX(x),SCROLLY(y),element);
1121 void DrawScreenField(int x, int y)
1123 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
1126 if (!IN_LEV_FIELD(ux,uy))
1128 DrawScreenElement(x,y,EL_BETON);
1132 element = Feld[ux][uy];
1134 if (IS_MOVING(ux,uy))
1136 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1137 BOOL cut_mode = CUT_NO_CUTTING;
1139 if (Store[ux][uy]==EL_MORAST_LEER ||
1140 Store[ux][uy]==EL_SIEB_LEER ||
1141 Store[ux][uy]==EL_SIEB2_LEER ||
1142 Store[ux][uy]==EL_AMOEBE_NASS)
1143 cut_mode = CUT_ABOVE;
1144 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1145 Store[ux][uy]==EL_SIEB_VOLL ||
1146 Store[ux][uy]==EL_SIEB2_VOLL ||
1147 Store[ux][uy]==EL_SALZSAEURE)
1148 cut_mode = CUT_BELOW;
1150 if (cut_mode==CUT_ABOVE)
1151 DrawElementShifted(x,y,0,0,Store[ux][uy],CUT_NO_CUTTING);
1153 DrawScreenElement(x,y,EL_LEERRAUM);
1156 DrawElementShifted(x,y,MovPos[ux][uy],0,element,CUT_NO_CUTTING);
1158 DrawElementShifted(x,y,0,MovPos[ux][uy],element,cut_mode);
1160 else if (IS_BLOCKED(ux,uy))
1165 BOOL cut_mode = CUT_NO_CUTTING;
1167 Blocked2Moving(ux,uy,&oldx,&oldy);
1170 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1172 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1173 Store[oldx][oldy]==EL_SIEB_LEER ||
1174 Store[oldx][oldy]==EL_SIEB2_LEER ||
1175 Store[oldx][oldy]==EL_AMOEBE_NASS)
1176 cut_mode = CUT_ABOVE;
1178 DrawScreenElement(x,y,EL_LEERRAUM);
1179 element = Feld[oldx][oldy];
1182 DrawElementShifted(sx,sy,MovPos[oldx][oldy],0,element,CUT_NO_CUTTING);
1184 DrawElementShifted(sx,sy,0,MovPos[oldx][oldy],element,cut_mode);
1186 else if (IS_DRAWABLE(element))
1187 DrawScreenElement(x,y,element);
1189 DrawScreenElement(x,y,EL_LEERRAUM);
1192 void DrawLevelField(int x, int y)
1194 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1195 DrawScreenField(SCROLLX(x),SCROLLY(y));
1196 else if (IS_MOVING(x,y))
1200 Moving2Blocked(x,y,&newx,&newy);
1201 if (IN_SCR_FIELD(SCROLLX(newx),SCROLLY(newy)))
1202 DrawScreenField(SCROLLX(newx),SCROLLY(newy));
1204 else if (IS_BLOCKED(x,y))
1208 Blocked2Moving(x,y,&oldx,&oldy);
1209 if (IN_SCR_FIELD(SCROLLX(oldx),SCROLLY(oldy)))
1210 DrawScreenField(SCROLLX(oldx),SCROLLY(oldy));
1214 void DrawMiniElement(int x, int y, int element)
1220 DrawMiniGraphic(x,y,-1);
1224 graphic = el2gfx(element);
1225 DrawMiniGraphic(x,y,graphic);
1228 void DrawMiniElementOrWall(int x, int y, int scroll_x, int scroll_y)
1230 if (x+scroll_x<-1 || x+scroll_x>lev_fieldx ||
1231 y+scroll_y<-1 || y+scroll_y>lev_fieldy)
1232 DrawMiniElement(x,y,EL_LEERRAUM);
1233 else if (x+scroll_x==-1 || x+scroll_x==lev_fieldx ||
1234 y+scroll_y==-1 || y+scroll_y==lev_fieldy)
1235 DrawMiniElement(x,y,EL_BETON);
1237 DrawMiniElement(x,y,Feld[x+scroll_x][y+scroll_y]);
1240 void DrawMicroElement(int xpos, int ypos, int element)
1244 if (element==EL_LEERRAUM)
1247 graphic = el2gfx(element);
1249 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1250 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1251 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1252 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1261 for(x=BX1; x<=BX2; x++)
1262 for(y=BY1; y<=BY2; y++)
1263 DrawScreenField(x,y);
1265 if (soft_scrolling_on)
1266 XCopyArea(display,fieldbuffer,backbuffer,gc,
1267 FX,FY, SXSIZE,SYSIZE,
1270 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1273 void DrawMiniLevel(int scroll_x, int scroll_y)
1279 for(x=0;x<2*SCR_FIELDX;x++)
1280 for(y=0;y<2*SCR_FIELDY;y++)
1281 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1283 redraw_mask |= REDRAW_FIELD;
1286 void DrawMicroLevel(int xpos, int ypos)
1290 XFillRectangle(display,drawto,gc,
1291 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1292 MICRO_TILEX*(STD_LEV_FIELDX+2),
1293 MICRO_TILEY*(STD_LEV_FIELDY+2));
1294 if (lev_fieldx < STD_LEV_FIELDX)
1295 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1296 if (lev_fieldy < STD_LEV_FIELDY)
1297 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1299 for(x=-1;x<=STD_LEV_FIELDX;x++)
1300 for(y=-1;y<=STD_LEV_FIELDY;y++)
1301 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1302 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1303 Feld[x][y]=Ur[x][y]);
1304 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1305 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1308 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1312 int len = strlen(level.name);
1313 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1314 int lypos = MICROLABEL_YPOS;
1316 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1319 redraw_mask |= REDRAW_MICROLEV;
1322 int AYS_in_range(int x, int y)
1324 if (y>DY+249 && y<DY+278)
1326 if (x>DX+1 && x<DX+48)
1328 else if (x>DX+51 && x<DX+98)
1334 BOOL AreYouSure(char *text, unsigned int ays_state)
1336 int mx,my, ty, result = -1;
1337 unsigned int old_door_state;
1339 old_door_state = GetDoorState();
1341 CloseDoor(DOOR_CLOSE_1);
1343 /* Alten Türinhalt sichern */
1344 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1345 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1346 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1348 /* Fragetext schreiben */
1349 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1350 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1352 for(ty=0;ty<13;ty++)
1359 for(tl=0,tx=0;tx<7;tl++,tx++)
1373 DrawTextExt(pix[PIX_DB_DOOR],gc,
1374 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1375 text+=(tl+(tc==32));
1378 if (ays_state & AYS_ASK)
1379 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1380 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1381 DXSIZE,OK_BUTTON_YSIZE,
1382 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1383 else if (ays_state & AYS_CONFIRM)
1384 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1385 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1386 DXSIZE,CONFIRM_BUTTON_YSIZE,
1387 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1389 OpenDoor(DOOR_OPEN_1);
1392 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1395 if (game_status != MAINMENU)
1398 button_status = MB_RELEASED;
1405 if (XPending(display))
1409 XNextEvent(display, &event);
1413 HandleExposeEvent((XExposeEvent *) &event);
1416 SleepWhileUnmapped();
1424 if (event.type == MotionNotify)
1426 motion_status = TRUE;
1427 mx = ((XMotionEvent *) &event)->x;
1428 my = ((XMotionEvent *) &event)->y;
1432 motion_status = FALSE;
1433 mx = ((XButtonEvent *) &event)->x;
1434 my = ((XButtonEvent *) &event)->y;
1435 if (event.type==ButtonPress)
1436 button_status = ((XButtonEvent *) &event)->button;
1438 button_status = MB_RELEASED;
1441 if (ays_state & AYS_ASK)
1442 choice = CheckChooseButtons(mx,my,button_status);
1444 choice = CheckConfirmButton(mx,my,button_status);
1454 case BUTTON_CONFIRM:
1455 result = TRUE|FALSE;
1463 switch(XLookupKeysym((XKeyEvent *)&event,
1464 ((XKeyEvent *)&event)->state))
1475 key_joystick_mapping = 0;
1479 HandleFocusEvent((XFocusChangeEvent *) &event);
1482 HandleClientMessageEvent((XClientMessageEvent *) &event);
1488 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1492 if (joy & JOY_BUTTON_1)
1494 else if (joy & JOY_BUTTON_2)
1499 if (game_status != MAINMENU)
1502 if (!(ays_state & AYS_STAY_OPEN))
1504 CloseDoor(DOOR_CLOSE_1);
1506 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1508 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1509 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1510 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1511 OpenDoor(DOOR_OPEN_1);
1518 unsigned int OpenDoor(unsigned int door_state)
1520 unsigned int new_door_state;
1522 if (door_state & DOOR_COPY_BACK)
1524 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1525 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1526 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1527 door_state &= ~DOOR_COPY_BACK;
1530 new_door_state = MoveDoor(door_state);
1532 return(new_door_state);
1535 unsigned int CloseDoor(unsigned int door_state)
1537 unsigned int new_door_state;
1539 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1540 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1541 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1542 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1544 new_door_state = MoveDoor(door_state);
1546 return(new_door_state);
1549 unsigned int GetDoorState()
1551 return(MoveDoor(DOOR_GET_STATE));
1554 unsigned int MoveDoor(unsigned int door_state)
1556 static unsigned int door1 = DOOR_OPEN_1;
1557 static unsigned int door2 = DOOR_CLOSE_2;
1558 static long door_delay = 0;
1559 int x, start, stepsize = 2;
1560 long door_delay_value = stepsize * 5000;
1562 if (door_state == DOOR_GET_STATE)
1563 return(door1 | door2);
1565 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1566 door_state &= ~DOOR_OPEN_1;
1567 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1568 door_state &= ~DOOR_CLOSE_1;
1569 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1570 door_state &= ~DOOR_OPEN_2;
1571 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1572 door_state &= ~DOOR_CLOSE_2;
1577 door_delay_value = 0;
1578 StopSound(SND_OEFFNEN);
1581 if (door_state & DOOR_ACTION)
1583 if (!(door_state & DOOR_NO_DELAY))
1584 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1586 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1588 for(x=start; x<=DXSIZE; x+=stepsize)
1590 while(!DelayReached(&door_delay, door_delay_value/10000))
1593 if (door_state & DOOR_ACTION_1)
1595 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1596 int j = (DXSIZE - i)/3;
1598 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1599 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1600 DXSIZE,DYSIZE-i/2, DX,DY);
1602 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1604 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1605 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1606 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1607 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1608 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1609 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1610 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1611 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1612 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1613 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1614 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1615 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1617 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1618 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1620 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1621 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1623 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1624 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1625 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1626 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1627 DX+DXSIZE-i,DY+77+j);
1628 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1629 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1630 DX+DXSIZE-i,DY+203+j);
1632 redraw_mask |= REDRAW_DOOR_1;
1635 if (door_state & DOOR_ACTION_2)
1637 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1638 int j = (VXSIZE - i)/3;
1640 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1641 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1642 VXSIZE,VYSIZE-i/2, VX,VY);
1644 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1646 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1647 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1648 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1649 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1650 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1651 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1652 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1653 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1655 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1656 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1658 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1659 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1660 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1661 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1662 VX+VXSIZE-i,VY+VYSIZE/2+j);
1664 redraw_mask |= REDRAW_DOOR_2;
1669 if (game_status==MAINMENU)
1674 if (door_state & DOOR_ACTION_1)
1675 door1 = door_state & DOOR_ACTION_1;
1676 if (door_state & DOOR_ACTION_2)
1677 door2 = door_state & DOOR_ACTION_2;
1679 return(door1 | door2);
1682 int ReadPixel(Drawable d, int x, int y)
1684 static XImage *pixelimage;
1686 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1687 return(XGetPixel(pixelimage,0,0));
1690 int el2gfx(int element)
1694 case EL_LEERRAUM: return(-1);
1695 case EL_ERDREICH: return(GFX_ERDREICH);
1696 case EL_MAUERWERK: return(GFX_MAUERWERK);
1697 case EL_FELSBODEN: return(GFX_FELSBODEN);
1698 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1699 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1700 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1701 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1702 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1703 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1704 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1705 case EL_SPIELER1: return(GFX_SPIELER1);
1706 case EL_SPIELER2: return(GFX_SPIELER2);
1707 case EL_SPIELER3: return(GFX_SPIELER3);
1708 case EL_SPIELER4: return(GFX_SPIELER4);
1709 case EL_KAEFER: return(GFX_KAEFER);
1710 case EL_KAEFER_R: return(GFX_KAEFER_R);
1711 case EL_KAEFER_O: return(GFX_KAEFER_O);
1712 case EL_KAEFER_L: return(GFX_KAEFER_L);
1713 case EL_KAEFER_U: return(GFX_KAEFER_U);
1714 case EL_FLIEGER: return(GFX_FLIEGER);
1715 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1716 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1717 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1718 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1719 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1720 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1721 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1722 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1723 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1724 case EL_FIREFLY: return(GFX_FIREFLY);
1725 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1726 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1727 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1728 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1729 case EL_MAMPFER: return(GFX_MAMPFER);
1730 case EL_ROBOT: return(GFX_ROBOT);
1731 case EL_BETON: return(GFX_BETON);
1732 case EL_DIAMANT: return(GFX_DIAMANT);
1733 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1734 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1735 case EL_TROPFEN: return(GFX_TROPFEN);
1736 case EL_BOMBE: return(GFX_BOMBE);
1737 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1738 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1739 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1740 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1741 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1742 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1743 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1744 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1745 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1746 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1747 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1748 case EL_LIFE: return(GFX_LIFE);
1749 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1750 case EL_DYNAMIT: return(GFX_DYNAMIT);
1751 case EL_BADEWANNE: return(GFX_BADEWANNE);
1752 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1753 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1754 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1755 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1756 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1757 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1758 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1759 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1760 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1761 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1762 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1763 case EL_PFORTE1: return(GFX_PFORTE1);
1764 case EL_PFORTE2: return(GFX_PFORTE2);
1765 case EL_PFORTE3: return(GFX_PFORTE3);
1766 case EL_PFORTE4: return(GFX_PFORTE4);
1767 case EL_PFORTE1X: return(GFX_PFORTE1X);
1768 case EL_PFORTE2X: return(GFX_PFORTE2X);
1769 case EL_PFORTE3X: return(GFX_PFORTE3X);
1770 case EL_PFORTE4X: return(GFX_PFORTE4X);
1771 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1772 case EL_PACMAN: return(GFX_PACMAN);
1773 case EL_PACMAN_R: return(GFX_PACMAN_R);
1774 case EL_PACMAN_O: return(GFX_PACMAN_O);
1775 case EL_PACMAN_L: return(GFX_PACMAN_L);
1776 case EL_PACMAN_U: return(GFX_PACMAN_U);
1777 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1778 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1779 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1780 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1781 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1782 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1783 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1784 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1785 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1786 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1787 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1788 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1789 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1790 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1791 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1792 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1793 case EL_MAMPFER2: return(GFX_MAMPFER2);
1794 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1795 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1796 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1797 case EL_DYNABOMB: return(GFX_DYNABOMB);
1798 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1799 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1800 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1801 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1802 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1803 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1804 case EL_MAULWURF: return(GFX_MAULWURF);
1805 case EL_PINGUIN: return(GFX_PINGUIN);
1806 case EL_SCHWEIN: return(GFX_SCHWEIN);
1807 case EL_DRACHE: return(GFX_DRACHE);
1808 case EL_SONDE: return(GFX_SONDE);
1809 case EL_PFEIL_L: return(GFX_PFEIL_L);
1810 case EL_PFEIL_R: return(GFX_PFEIL_R);
1811 case EL_PFEIL_O: return(GFX_PFEIL_O);
1812 case EL_PFEIL_U: return(GFX_PFEIL_U);
1815 if (IS_CHAR(element))
1816 return(GFX_CHAR_START + (element-EL_CHAR_START));