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 if (redraw_mask & REDRAW_ALL)
83 XCopyArea(display,backbuffer,window,gc,
84 0,0, WIN_XSIZE,WIN_YSIZE,
89 if (redraw_mask & REDRAW_FIELD)
92 wait_for_vsync = TRUE;
94 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
95 XCopyArea(display,backbuffer,window,gc,
96 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
100 int fx = FX, fy = FY;
102 if (soft_scrolling_on)
104 fx += (PlayerMovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0);
105 fy += (PlayerMovDir & (MV_UP|MV_DOWN) ? ScreenMovPos : 0);
108 XCopyArea(display,buffer,window,gc,
109 fx,fy, SXSIZE,SYSIZE,
115 printf("FULL SCREEN REDRAW [%d]\n", ScreenMovPos);
121 redraw_mask &= ~REDRAW_MAIN;
124 if (redraw_mask & REDRAW_DOORS)
127 wait_for_vsync = TRUE;
129 if (redraw_mask & REDRAW_DOOR_1)
130 XCopyArea(display,backbuffer,window,gc,
131 DX,DY, DXSIZE,DYSIZE,
133 if (redraw_mask & REDRAW_DOOR_2)
135 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
136 XCopyArea(display,backbuffer,window,gc,
137 VX,VY, VXSIZE,VYSIZE,
141 if (redraw_mask & REDRAW_VIDEO_1)
142 XCopyArea(display,backbuffer,window,gc,
143 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
144 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
145 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
146 if (redraw_mask & REDRAW_VIDEO_2)
147 XCopyArea(display,backbuffer,window,gc,
148 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
149 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
150 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
151 if (redraw_mask & REDRAW_VIDEO_3)
152 XCopyArea(display,backbuffer,window,gc,
153 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
154 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
155 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
158 redraw_mask &= ~REDRAW_DOORS;
161 if (redraw_mask & REDRAW_MICROLEV)
163 XCopyArea(display,backbuffer,window,gc,
164 MICROLEV_XPOS,MICROLEV_YPOS, MICROLEV_XSIZE,MICROLEV_YSIZE,
165 MICROLEV_XPOS,MICROLEV_YPOS);
166 XCopyArea(display,backbuffer,window,gc,
167 SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE,
169 redraw_mask &= ~REDRAW_MICROLEV;
172 if (redraw_mask & REDRAW_TILES)
174 for(x=0; x<SCR_FIELDX; x++)
175 for(y=0; y<SCR_FIELDY; y++)
176 if (redraw[redraw_x1 + x][redraw_y1 + y])
177 XCopyArea(display,buffer,window,gc,
178 FX+x*TILEX,FX+y*TILEY, TILEX,TILEY,
179 SX+x*TILEX,SY+y*TILEY);
184 for(x=0; x<MAX_BUF_XSIZE; x++)
185 for(y=0; y<MAX_BUF_YSIZE; y++)
194 long fading_delay = 300000;
196 if (fading_on && (redraw_mask & REDRAW_FIELD))
203 XFillRectangle(display,window,gc,
204 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
207 for(i=0;i<2*FULL_SYSIZE;i++)
209 for(y=0;y<FULL_SYSIZE;y++)
211 XCopyArea(display,backbuffer,window,gc,
212 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
220 for(i=1;i<FULL_SYSIZE;i+=2)
221 XCopyArea(display,backbuffer,window,gc,
222 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
228 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
229 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
230 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
234 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
235 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
236 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
240 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
241 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
242 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
246 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
247 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
248 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
252 redraw_mask &= ~REDRAW_MAIN;
261 XFillRectangle(display,backbuffer,gc,
262 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
264 if (soft_scrolling_on && game_status==PLAYING)
266 XFillRectangle(display,fieldbuffer,gc,
268 SetDrawtoField(DRAW_BUFFERED);
271 SetDrawtoField(DRAW_BACKBUFFER);
273 if (direct_draw_on && game_status==PLAYING)
275 XFillRectangle(display,window,gc,
276 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
277 SetDrawtoField(DRAW_DIRECT);
280 redraw_mask |= REDRAW_FIELD;
283 void DrawText(int x, int y, char *text, int font, int col)
285 DrawTextExt(drawto, gc, x, y, text, font, col);
287 redraw_mask |= REDRAW_FIELD;
289 redraw_mask |= REDRAW_DOOR_1;
292 void DrawTextExt(Drawable d, GC gc, int x, int y,
293 char *text, int font, int font_color)
295 int font_width, font_height, font_start;
298 if (font!=FS_SMALL && font!=FS_BIG)
300 if (font_color<FC_RED || font_color>FC_SPECIAL2)
304 (font==FS_BIG ? FONT1_XSIZE :
305 font_color<FC_SPECIAL1 ? FONT2_XSIZE :
306 font_color<FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
308 (font==FS_BIG ? FONT1_XSIZE :
309 font_color<FC_SPECIAL2 ? FONT2_XSIZE: FONT4_XSIZE);
310 font_pixmap = (font==FS_BIG ? PIX_BIGFONT : PIX_SMALLFONT);
312 font_color*(font==FS_BIG ? FONT1_YSIZE : FONT2_YSIZE)*FONT_LINES_PER_FONT;
318 if (c>='a' && c<='z')
320 else if (c=='ä' || c=='Ä')
322 else if (c=='ö' || c=='Ö')
324 else if (c=='ü' || c=='Ü')
328 XCopyArea(display,pix[font_pixmap],d,gc,
329 ((c-32) % FONT_CHARS_PER_LINE)*font_width,
330 ((c-32) / FONT_CHARS_PER_LINE)*font_height + font_start,
331 font_width,font_height, x,y);
337 void DrawPlayerField()
340 int sx = SCROLLX(x), sy = SCROLLY(y);
342 int sxx = 0, syy = 0;
344 int element = Feld[x][y];
346 BOOL draw_thru_mask = FALSE;
352 if (!IN_LEV_FIELD(x,y) || !IN_SCR_FIELD(sx,sy))
354 printf("DrawPlayerField(): x = %d, y = %d\n",x,y);
355 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
356 printf("DrawPlayerField(): This should never happen!\n");
361 if (element == EL_EXPLODING)
365 SetDrawtoField(DRAW_BUFFERED);
367 /* draw things behind the player (EL_PFORTE* || mole/penguin/pig/dragon) */
378 DrawGraphic(sx,sy, el2gfx(Store[x][y]));
379 draw_thru_mask = TRUE;
381 else if (element!=EL_DYNAMIT && element!=EL_DYNABOMB)
384 draw_thru_mask = TRUE;
388 else if (element!=EL_LEERRAUM && element!=EL_DYNAMIT && element!=EL_DYNABOMB)
391 draw_thru_mask = TRUE;
396 draw_thru_mask = TRUE;
401 /* draw player himself */
403 if (PlayerMovDir==MV_LEFT)
404 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT);
405 else if (PlayerMovDir==MV_RIGHT)
406 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT);
407 else if (PlayerMovDir==MV_UP)
408 graphic = GFX_SPIELER_UP;
409 else /* MV_DOWN || MV_NO_MOVING */
410 graphic = GFX_SPIELER_DOWN;
412 graphic += PlayerFrame;
417 if (PlayerMovDir == MV_LEFT || PlayerMovDir == MV_RIGHT)
424 if (!soft_scrolling_on && ScreenMovPos)
433 DrawGraphicShiftedThruMask(sx,sy,sxx,syy,graphic,CUT_NO_CUTTING);
435 DrawGraphicThruMask(sx, sy, graphic);
438 DrawGraphicShifted(sx,sy,sxx,syy,graphic,CUT_NO_CUTTING);
440 DrawGraphic(sx, sy, graphic);
445 MarkTileDirty(sx,sy);
449 if (PlayerPushing && PlayerGfxPos)
451 int nextJX = JX + (JX - lastJX);
452 int nextJY = JY + (JY - lastJY);
453 int px = SCROLLX(nextJX), py = SCROLLY(nextJY);
455 if (Feld[JX][JY] == EL_SOKOBAN_FELD_LEER ||
456 Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
457 DrawGraphicShiftedThruMask(px,py,sxx,syy,
462 int element = Feld[nextJX][nextJY];
463 int graphic = el2gfx(element);
465 if (element == EL_FELSBROCKEN && sxx)
467 int phase = (PlayerGfxPos / (TILEX/4));
469 if (PlayerMovDir == MV_LEFT)
472 graphic += (phase+4)%4;
476 printf("----> (%d, %d, %d)\n",
477 PlayerGfxPos, phase, graphic);
482 DrawGraphicShifted(px,py, sxx,syy, graphic, CUT_NO_CUTTING);
488 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
490 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
492 graphic = el2gfx(element);
494 if (element == EL_DYNAMIT)
496 if ((phase = (96-MovDelay[x][y])/12) > 6)
501 if ((phase = ((96-MovDelay[x][y])/6) % 8) > 3)
505 DrawGraphicThruMask(sx,sy, graphic + phase);
510 int dest_x = SX+SCROLLX(x)*TILEX;
511 int dest_y = SY+SCROLLY(y)*TILEY;
517 dest_x = SX + SCROLLX(MIN(JX,lastJX))*TILEX;
518 dest_y = SY + SCROLLY(MIN(JY,lastJY))*TILEY;
519 x_size = TILEX * (1 + ABS(JX - lastJX));
520 y_size = TILEY * (1 + ABS(JY - lastJY));
523 XCopyArea(display,drawto_field,window,gc,
524 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
525 SetDrawtoField(DRAW_DIRECT);
529 static int getGraphicAnimationPhase(int frames, int delay, int mode)
533 if (mode == ANIM_OSCILLATE)
535 int max_anim_frames = frames*2 - 2;
536 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
537 phase = (phase < frames ? phase : max_anim_frames - phase);
540 phase = (FrameCounter % (delay * frames)) / delay;
542 if (mode == ANIM_REVERSE)
548 void DrawGraphicAnimation(int x, int y, int graphic,
549 int frames, int delay, int mode)
551 int phase = getGraphicAnimationPhase(frames, delay, mode);
553 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
554 DrawGraphic(SCROLLX(x),SCROLLY(y), graphic + phase);
557 void DrawGraphic(int x, int y, int graphic)
561 if (!IN_SCR_FIELD(x,y))
563 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
564 printf("DrawGraphic(): This should never happen!\n");
569 DrawGraphicExt(drawto_field, gc, x, y, graphic);
573 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
575 DrawGraphicExtHiRes(d, gc, FX+x*TILEX, FY+y*TILEY, graphic);
578 void DrawGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
580 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
582 graphic -= GFX_START_ROCKSSCREEN;
583 XCopyArea(display,pix[PIX_BACK],d,gc,
584 SX+(graphic % GFX_PER_LINE)*TILEX,
585 SY+(graphic / GFX_PER_LINE)*TILEY,
588 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
590 graphic -= GFX_START_ROCKSHEROES;
591 XCopyArea(display,pix[PIX_HEROES],d,gc,
592 (graphic % HEROES_PER_LINE)*TILEX,
593 (graphic / HEROES_PER_LINE)*TILEY,
596 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
598 graphic -= GFX_START_ROCKSFONT;
599 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
600 (graphic % FONT_CHARS_PER_LINE)*TILEX,
601 (graphic / FONT_CHARS_PER_LINE)*TILEY +
602 FC_SPECIAL1*TILEY*FONT_LINES_PER_FONT,
606 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
609 void DrawGraphicThruMask(int x, int y, int graphic)
611 int src_x,src_y, dest_x,dest_y;
614 if (!IN_SCR_FIELD(x,y))
616 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
617 printf("DrawGraphicThruMask(): This should never happen!\n");
622 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
624 graphic -= GFX_START_ROCKSSCREEN;
625 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
626 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
630 XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y);
631 XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK],
632 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
634 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
636 graphic -= GFX_START_ROCKSHEROES;
637 src_x = (graphic % HEROES_PER_LINE)*TILEX;
638 src_y = (graphic / HEROES_PER_LINE)*TILEY;
642 XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
643 XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
644 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
648 DrawGraphic(x,y,graphic);
655 void DrawElementThruMask(int x, int y, int element)
657 DrawGraphicThruMask(x,y,el2gfx(element));
660 void DrawMiniGraphic(int x, int y, int graphic)
662 DrawMiniGraphicExt(drawto, gc, x, y, graphic);
663 MarkTileDirty(x/2, y/2);
666 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
668 DrawMiniGraphicExtHiRes(d,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
671 void DrawMiniGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
673 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
675 graphic -= GFX_START_ROCKSSCREEN;
676 XCopyArea(display,pix[PIX_BACK],d,gc,
677 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
678 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
679 MINI_TILEX,MINI_TILEY, x,y);
681 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
683 graphic -= GFX_START_ROCKSFONT;
684 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
685 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
686 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
687 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
688 MINI_TILEX,MINI_TILEY, x,y);
691 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
694 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, int cut_mode)
696 int width = TILEX, height = TILEY;
701 DrawGraphic(x,y,graphic);
705 if (dx || dy) /* Verschiebung der Grafik? */
707 if (x < BX1) /* Element kommt von links ins Bild */
714 else if (x > BX2) /* Element kommt von rechts ins Bild */
720 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
726 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
728 else if (dx) /* allg. Bewegung in x-Richtung */
729 MarkTileDirty(x + SIGN(dx), y);
731 if (y < BY1) /* Element kommt von oben ins Bild */
733 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
741 else if (y > BY2) /* Element kommt von unten ins Bild */
747 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
753 else if (dy > 0 && cut_mode==CUT_ABOVE)
755 if (y == BY2) /* Element unterhalb des Bildes */
761 MarkTileDirty(x, y + 1);
762 } /* Element verläßt unten das Bild */
763 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
765 else if (dy) /* allg. Bewegung in y-Richtung */
766 MarkTileDirty(x, y + SIGN(dy));
769 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
771 graphic -= GFX_START_ROCKSSCREEN;
772 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
773 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
774 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
775 width,height, FX+x*TILEX+dx,FY+y*TILEY+dy);
777 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
779 graphic -= GFX_START_ROCKSHEROES;
780 XCopyArea(display,pix[PIX_HEROES],drawto_field,gc,
781 (graphic % HEROES_PER_LINE)*TILEX+cx,
782 (graphic / HEROES_PER_LINE)*TILEY+cy,
783 width,height, FX+x*TILEX+dx,FY+y*TILEY+dy);
787 if (!IN_SCR_FIELD(x,y))
789 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
790 printf("DrawGraphicShifted(): This should never happen!\n");
798 void DrawElementShifted(int x, int y, int dx, int dy, int element,int cut_mode)
800 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
801 int graphic = el2gfx(element);
802 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
803 int phase = phase4 / 2;
804 int dir = MovDir[ux][uy];
806 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
812 else if (dir == MV_LEFT)
814 else if (dir == MV_DOWN)
817 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
818 element==EL_SCHWEIN || element==EL_DRACHE)
821 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
822 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
823 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
824 else if (dir==MV_RIGHT)
825 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
826 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
827 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
829 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
830 element==EL_PINGUIN ? GFX_PINGUIN_UP :
831 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
833 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
834 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
835 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
839 else if (element==EL_SONDE)
841 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
843 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
847 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
849 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
851 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
852 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
854 graphic += 3-(SiebAktiv%8)/2;
856 else if (IS_AMOEBOID(element))
858 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
859 graphic += (x+2*y) % 4;
861 else if (element==EL_MAUER_LEBT)
863 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
865 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
867 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
868 rechts_massiv = TRUE;
870 if (links_massiv && rechts_massiv)
871 graphic = GFX_MAUERWERK;
872 else if (links_massiv)
873 graphic = GFX_MAUER_R;
874 else if (rechts_massiv)
875 graphic = GFX_MAUER_L;
879 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode);
881 DrawGraphic(x,y, graphic);
884 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
887 int width = TILEX, height = TILEY;
889 int src_x,src_y, dest_x,dest_y;
893 DrawGraphic(x,y,graphic);
897 if (dx || dy) /* Verschiebung der Grafik? */
899 if (x < BX1) /* Element kommt von links ins Bild */
906 else if (x > BX2) /* Element kommt von rechts ins Bild */
912 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
918 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
920 else if (dx) /* allg. Bewegung in x-Richtung */
921 MarkTileDirty(x + SIGN(dx), y);
923 if (y < BY1) /* Element kommt von oben ins Bild */
925 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
933 else if (y > BY2) /* Element kommt von unten ins Bild */
939 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
945 else if (dy > 0 && cut_mode==CUT_ABOVE)
947 if (y == BY2) /* Element unterhalb des Bildes */
953 MarkTileDirty(x, y + 1);
954 } /* Element verläßt unten das Bild */
955 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
957 else if (dy) /* allg. Bewegung in y-Richtung */
958 MarkTileDirty(x, y + SIGN(dy));
961 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
963 graphic -= GFX_START_ROCKSSCREEN;
964 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
965 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
966 dest_x = FX+x*TILEX+dx;
967 dest_y = FY+y*TILEY+dy;
969 XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y);
970 XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK],
971 src_x,src_y, width,height, dest_x,dest_y);
973 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
975 graphic -= GFX_START_ROCKSHEROES;
976 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
977 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
978 dest_x = FX+x*TILEX+dx;
979 dest_y = FY+y*TILEY+dy;
981 XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
982 XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
983 src_x,src_y, width,height, dest_x,dest_y);
987 if (!IN_SCR_FIELD(x,y))
989 printf("DrawGraphicShiftedThruMask(): x = %d, y = %d, graphic = %d\n",
991 printf("DrawGraphicShifted(): This should never happen!\n");
999 void ErdreichAnbroeckeln(int x, int y)
1001 int i, width, height, cx,cy;
1002 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
1003 int element, graphic;
1005 static int xy[4][2] =
1013 if (!IN_LEV_FIELD(ux,uy))
1016 element = Feld[ux][uy];
1018 if (element==EL_ERDREICH)
1020 if (!IN_SCR_FIELD(x,y))
1023 graphic = GFX_ERDENRAND;
1031 if (!IN_LEV_FIELD(uxx,uyy))
1034 element = Feld[uxx][uyy];
1037 if (element==EL_ERDREICH || IS_SOLID(element))
1040 if (element==EL_ERDREICH)
1047 cx = (i==2 ? TILEX-snip : 0);
1055 cy = (i==3 ? TILEY-snip : 0);
1058 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1059 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1060 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1061 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1068 graphic = GFX_ERDENRAND;
1079 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1080 !IN_SCR_FIELD(xx,yy) || IS_SOLID(element))
1084 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1085 !IN_SCR_FIELD(xx,yy))
1092 cx = (i==1 ? TILEX-snip : 0);
1100 cy = (i==0 ? TILEY-snip : 0);
1103 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1104 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1105 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1106 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1108 MarkTileDirty(xx,yy);
1113 void DrawScreenElement(int x, int y, int element)
1115 DrawElementShifted(x,y,0,0,element,CUT_NO_CUTTING);
1116 ErdreichAnbroeckeln(x,y);
1119 void DrawLevelElement(int x, int y, int element)
1121 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1122 DrawScreenElement(SCROLLX(x),SCROLLY(y),element);
1125 void DrawScreenField(int x, int y)
1127 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
1130 if (!IN_LEV_FIELD(ux,uy))
1132 DrawScreenElement(x,y,EL_BETON);
1136 element = Feld[ux][uy];
1138 if (IS_MOVING(ux,uy))
1140 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1141 BOOL cut_mode = CUT_NO_CUTTING;
1143 if (Store[ux][uy]==EL_MORAST_LEER ||
1144 Store[ux][uy]==EL_SIEB_LEER ||
1145 Store[ux][uy]==EL_SIEB2_LEER ||
1146 Store[ux][uy]==EL_AMOEBE_NASS)
1147 cut_mode = CUT_ABOVE;
1148 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1149 Store[ux][uy]==EL_SIEB_VOLL ||
1150 Store[ux][uy]==EL_SIEB2_VOLL ||
1151 Store[ux][uy]==EL_SALZSAEURE)
1152 cut_mode = CUT_BELOW;
1154 if (cut_mode==CUT_ABOVE)
1155 DrawElementShifted(x,y,0,0,Store[ux][uy],CUT_NO_CUTTING);
1157 DrawScreenElement(x,y,EL_LEERRAUM);
1160 DrawElementShifted(x,y,MovPos[ux][uy],0,element,CUT_NO_CUTTING);
1162 DrawElementShifted(x,y,0,MovPos[ux][uy],element,cut_mode);
1164 else if (IS_BLOCKED(ux,uy))
1169 BOOL cut_mode = CUT_NO_CUTTING;
1171 Blocked2Moving(ux,uy,&oldx,&oldy);
1174 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1176 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1177 Store[oldx][oldy]==EL_SIEB_LEER ||
1178 Store[oldx][oldy]==EL_SIEB2_LEER ||
1179 Store[oldx][oldy]==EL_AMOEBE_NASS)
1180 cut_mode = CUT_ABOVE;
1182 DrawScreenElement(x,y,EL_LEERRAUM);
1183 element = Feld[oldx][oldy];
1186 DrawElementShifted(sx,sy,MovPos[oldx][oldy],0,element,CUT_NO_CUTTING);
1188 DrawElementShifted(sx,sy,0,MovPos[oldx][oldy],element,cut_mode);
1190 else if (IS_DRAWABLE(element))
1191 DrawScreenElement(x,y,element);
1193 DrawScreenElement(x,y,EL_LEERRAUM);
1196 void DrawLevelField(int x, int y)
1198 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1199 DrawScreenField(SCROLLX(x),SCROLLY(y));
1200 else if (IS_MOVING(x,y))
1204 Moving2Blocked(x,y,&newx,&newy);
1205 if (IN_SCR_FIELD(SCROLLX(newx),SCROLLY(newy)))
1206 DrawScreenField(SCROLLX(newx),SCROLLY(newy));
1208 else if (IS_BLOCKED(x,y))
1212 Blocked2Moving(x,y,&oldx,&oldy);
1213 if (IN_SCR_FIELD(SCROLLX(oldx),SCROLLY(oldy)))
1214 DrawScreenField(SCROLLX(oldx),SCROLLY(oldy));
1218 void DrawMiniElement(int x, int y, int element)
1224 DrawMiniGraphic(x,y,-1);
1228 graphic = el2gfx(element);
1229 DrawMiniGraphic(x,y,graphic);
1232 void DrawMiniElementOrWall(int x, int y, int scroll_x, int scroll_y)
1234 if (x+scroll_x<-1 || x+scroll_x>lev_fieldx ||
1235 y+scroll_y<-1 || y+scroll_y>lev_fieldy)
1236 DrawMiniElement(x,y,EL_LEERRAUM);
1237 else if (x+scroll_x==-1 || x+scroll_x==lev_fieldx ||
1238 y+scroll_y==-1 || y+scroll_y==lev_fieldy)
1239 DrawMiniElement(x,y,EL_BETON);
1241 DrawMiniElement(x,y,Feld[x+scroll_x][y+scroll_y]);
1244 void DrawMicroElement(int xpos, int ypos, int element)
1248 if (element==EL_LEERRAUM)
1251 graphic = el2gfx(element);
1253 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1254 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1255 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1256 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1265 for(x=BX1; x<=BX2; x++)
1266 for(y=BY1; y<=BY2; y++)
1267 DrawScreenField(x,y);
1269 if (soft_scrolling_on)
1270 XCopyArea(display,fieldbuffer,backbuffer,gc,
1271 FX,FY, SXSIZE,SYSIZE,
1274 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1277 void DrawMiniLevel(int scroll_x, int scroll_y)
1283 for(x=0;x<2*SCR_FIELDX;x++)
1284 for(y=0;y<2*SCR_FIELDY;y++)
1285 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1287 redraw_mask |= REDRAW_FIELD;
1290 void DrawMicroLevel(int xpos, int ypos)
1294 XFillRectangle(display,drawto,gc,
1295 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1296 MICRO_TILEX*(STD_LEV_FIELDX+2),
1297 MICRO_TILEY*(STD_LEV_FIELDY+2));
1298 if (lev_fieldx < STD_LEV_FIELDX)
1299 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1300 if (lev_fieldy < STD_LEV_FIELDY)
1301 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1303 for(x=-1;x<=STD_LEV_FIELDX;x++)
1304 for(y=-1;y<=STD_LEV_FIELDY;y++)
1305 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1306 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1307 Feld[x][y]=Ur[x][y]);
1308 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1309 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1312 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1316 int len = strlen(level.name);
1317 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1318 int lypos = MICROLABEL_YPOS;
1320 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1323 redraw_mask |= REDRAW_MICROLEV;
1326 int AYS_in_range(int x, int y)
1328 if (y>DY+249 && y<DY+278)
1330 if (x>DX+1 && x<DX+48)
1332 else if (x>DX+51 && x<DX+98)
1338 BOOL AreYouSure(char *text, unsigned int ays_state)
1340 int mx,my, ty, result = -1;
1341 unsigned int old_door_state;
1343 old_door_state = GetDoorState();
1345 CloseDoor(DOOR_CLOSE_1);
1347 /* Alten Türinhalt sichern */
1348 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1349 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1350 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1352 /* Fragetext schreiben */
1353 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1354 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1356 for(ty=0;ty<13;ty++)
1363 for(tl=0,tx=0;tx<7;tl++,tx++)
1377 DrawTextExt(pix[PIX_DB_DOOR],gc,
1378 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1379 text+=(tl+(tc==32));
1382 if (ays_state & AYS_ASK)
1383 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1384 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1385 DXSIZE,OK_BUTTON_YSIZE,
1386 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1387 else if (ays_state & AYS_CONFIRM)
1388 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1389 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1390 DXSIZE,CONFIRM_BUTTON_YSIZE,
1391 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1393 OpenDoor(DOOR_OPEN_1);
1396 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1399 if (game_status != MAINMENU)
1402 button_status = MB_RELEASED;
1409 if (XPending(display))
1413 XNextEvent(display, &event);
1417 HandleExposeEvent((XExposeEvent *) &event);
1420 SleepWhileUnmapped();
1428 if (event.type == MotionNotify)
1430 motion_status = TRUE;
1431 mx = ((XMotionEvent *) &event)->x;
1432 my = ((XMotionEvent *) &event)->y;
1436 motion_status = FALSE;
1437 mx = ((XButtonEvent *) &event)->x;
1438 my = ((XButtonEvent *) &event)->y;
1439 if (event.type==ButtonPress)
1440 button_status = ((XButtonEvent *) &event)->button;
1442 button_status = MB_RELEASED;
1445 if (ays_state & AYS_ASK)
1446 choice = CheckChooseButtons(mx,my,button_status);
1448 choice = CheckConfirmButton(mx,my,button_status);
1458 case BUTTON_CONFIRM:
1459 result = TRUE|FALSE;
1467 switch(XLookupKeysym((XKeyEvent *)&event,
1468 ((XKeyEvent *)&event)->state))
1480 HandleFocusEvent((XFocusChangeEvent *) &event);
1483 HandleClientMessageEvent((XClientMessageEvent *) &event);
1489 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1493 if (joy & JOY_BUTTON_1)
1495 else if (joy & JOY_BUTTON_2)
1500 if (game_status != MAINMENU)
1503 if (!(ays_state & AYS_STAY_OPEN))
1505 CloseDoor(DOOR_CLOSE_1);
1507 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1509 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1510 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1511 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1512 OpenDoor(DOOR_OPEN_1);
1519 unsigned int OpenDoor(unsigned int door_state)
1521 unsigned int new_door_state;
1523 if (door_state & DOOR_COPY_BACK)
1525 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1526 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1527 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1528 door_state &= ~DOOR_COPY_BACK;
1531 new_door_state = MoveDoor(door_state);
1537 return(new_door_state);
1540 unsigned int CloseDoor(unsigned int door_state)
1542 unsigned int new_door_state;
1544 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1545 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1546 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1547 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1549 new_door_state = MoveDoor(door_state);
1555 return(new_door_state);
1558 unsigned int GetDoorState()
1560 return(MoveDoor(DOOR_GET_STATE));
1563 unsigned int MoveDoor(unsigned int door_state)
1565 static unsigned int door1 = DOOR_OPEN_1;
1566 static unsigned int door2 = DOOR_CLOSE_2;
1567 int x, start, stepsize = 4, door_anim_delay = stepsize*5000;
1573 if (door_state == DOOR_GET_STATE)
1574 return(door1 | door2);
1576 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1577 door_state &= ~DOOR_OPEN_1;
1578 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1579 door_state &= ~DOOR_CLOSE_1;
1580 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1581 door_state &= ~DOOR_OPEN_2;
1582 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1583 door_state &= ~DOOR_CLOSE_2;
1588 door_anim_delay = 0;
1589 StopSound(SND_OEFFNEN);
1592 if (door_state & DOOR_ACTION)
1594 if (!(door_state & DOOR_NO_DELAY))
1595 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1597 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1599 for(x=start;x<=DXSIZE;x+=stepsize)
1601 if (door_state & DOOR_ACTION_1)
1603 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1604 int j = (DXSIZE - i)/3;
1606 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1607 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1608 DXSIZE,DYSIZE-i/2, DX,DY);
1610 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1612 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1613 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1614 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1615 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1616 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1617 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1618 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1619 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1620 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1621 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1622 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1623 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1625 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1626 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1628 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1629 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1631 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1632 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1633 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1634 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1635 DX+DXSIZE-i,DY+77+j);
1636 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1637 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1638 DX+DXSIZE-i,DY+203+j);
1640 redraw_mask |= REDRAW_DOOR_1;
1643 if (door_state & DOOR_ACTION_2)
1645 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1646 int j = (VXSIZE - i)/3;
1648 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1649 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1650 VXSIZE,VYSIZE-i/2, VX,VY);
1652 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1654 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1655 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1656 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1657 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1658 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1659 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1660 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1661 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1663 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1664 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1666 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1667 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1668 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1669 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1670 VX+VXSIZE-i,VY+VYSIZE/2+j);
1672 redraw_mask |= REDRAW_DOOR_2;
1677 Delay(door_anim_delay);
1680 if (game_status==MAINMENU)
1685 if (door_state & DOOR_ACTION_1)
1686 door1 = door_state & DOOR_ACTION_1;
1687 if (door_state & DOOR_ACTION_2)
1688 door2 = door_state & DOOR_ACTION_2;
1690 return(door1 | door2);
1693 int ReadPixel(Drawable d, int x, int y)
1695 static XImage *pixelimage;
1697 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1698 return(XGetPixel(pixelimage,0,0));
1701 int el2gfx(int element)
1705 case EL_LEERRAUM: return(-1);
1706 case EL_ERDREICH: return(GFX_ERDREICH);
1707 case EL_MAUERWERK: return(GFX_MAUERWERK);
1708 case EL_FELSBODEN: return(GFX_FELSBODEN);
1709 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1710 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1711 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1712 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1713 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1714 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1715 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1716 case EL_SPIELER1: return(GFX_SPIELER1);
1717 case EL_SPIELER2: return(GFX_SPIELER2);
1718 case EL_SPIELER3: return(GFX_SPIELER3);
1719 case EL_SPIELER4: return(GFX_SPIELER4);
1720 case EL_KAEFER: return(GFX_KAEFER);
1721 case EL_KAEFER_R: return(GFX_KAEFER_R);
1722 case EL_KAEFER_O: return(GFX_KAEFER_O);
1723 case EL_KAEFER_L: return(GFX_KAEFER_L);
1724 case EL_KAEFER_U: return(GFX_KAEFER_U);
1725 case EL_FLIEGER: return(GFX_FLIEGER);
1726 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1727 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1728 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1729 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1730 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1731 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1732 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1733 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1734 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1735 case EL_FIREFLY: return(GFX_FIREFLY);
1736 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1737 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1738 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1739 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1740 case EL_MAMPFER: return(GFX_MAMPFER);
1741 case EL_ROBOT: return(GFX_ROBOT);
1742 case EL_BETON: return(GFX_BETON);
1743 case EL_DIAMANT: return(GFX_DIAMANT);
1744 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1745 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1746 case EL_TROPFEN: return(GFX_TROPFEN);
1747 case EL_BOMBE: return(GFX_BOMBE);
1748 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1749 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1750 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1751 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1752 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1753 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1754 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1755 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1756 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1757 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1758 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1759 case EL_LIFE: return(GFX_LIFE);
1760 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1761 case EL_DYNAMIT: return(GFX_DYNAMIT);
1762 case EL_BADEWANNE: return(GFX_BADEWANNE);
1763 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1764 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1765 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1766 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1767 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1768 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1769 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1770 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1771 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1772 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1773 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1774 case EL_PFORTE1: return(GFX_PFORTE1);
1775 case EL_PFORTE2: return(GFX_PFORTE2);
1776 case EL_PFORTE3: return(GFX_PFORTE3);
1777 case EL_PFORTE4: return(GFX_PFORTE4);
1778 case EL_PFORTE1X: return(GFX_PFORTE1X);
1779 case EL_PFORTE2X: return(GFX_PFORTE2X);
1780 case EL_PFORTE3X: return(GFX_PFORTE3X);
1781 case EL_PFORTE4X: return(GFX_PFORTE4X);
1782 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1783 case EL_PACMAN: return(GFX_PACMAN);
1784 case EL_PACMAN_R: return(GFX_PACMAN_R);
1785 case EL_PACMAN_O: return(GFX_PACMAN_O);
1786 case EL_PACMAN_L: return(GFX_PACMAN_L);
1787 case EL_PACMAN_U: return(GFX_PACMAN_U);
1788 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1789 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1790 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1791 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1792 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1793 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1794 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1795 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1796 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1797 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1798 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1799 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1800 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1801 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1802 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1803 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1804 case EL_MAMPFER2: return(GFX_MAMPFER2);
1805 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1806 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1807 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1808 case EL_DYNABOMB: return(GFX_DYNABOMB);
1809 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1810 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1811 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1812 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1813 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1814 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1815 case EL_MAULWURF: return(GFX_MAULWURF);
1816 case EL_PINGUIN: return(GFX_PINGUIN);
1817 case EL_SCHWEIN: return(GFX_SCHWEIN);
1818 case EL_DRACHE: return(GFX_DRACHE);
1819 case EL_SONDE: return(GFX_SONDE);
1820 case EL_PFEIL_L: return(GFX_PFEIL_L);
1821 case EL_PFEIL_R: return(GFX_PFEIL_R);
1822 case EL_PFEIL_O: return(GFX_PFEIL_O);
1823 case EL_PFEIL_U: return(GFX_PFEIL_U);
1826 if (IS_CHAR(element))
1827 return(GFX_CHAR_START + (element-EL_CHAR_START));