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>
30 void SetDrawtoField(int mode)
32 if (mode == DRAW_BUFFERED && soft_scrolling_on)
43 drawto_field = fieldbuffer;
45 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
56 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
63 Drawable buffer = (drawto_field != window ? drawto_field : backbuffer);
65 if (direct_draw_on && game_status == PLAYING)
66 redraw_mask &= ~REDRAW_MAIN;
68 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
69 redraw_mask |= REDRAW_FIELD;
71 if (redraw_mask & REDRAW_FIELD || ScreenMovPos)
72 redraw_mask &= ~REDRAW_TILES;
77 if (redraw_mask & REDRAW_ALL)
79 XCopyArea(display,backbuffer,window,gc,
80 0,0, WIN_XSIZE,WIN_YSIZE,
85 if (redraw_mask & REDRAW_FIELD)
87 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
88 XCopyArea(display,backbuffer,window,gc,
89 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
95 if (soft_scrolling_on)
97 fx += (PlayerMovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0);
98 fy += (PlayerMovDir & (MV_UP|MV_DOWN) ? ScreenMovPos : 0);
101 XCopyArea(display,buffer,window,gc,
102 fx,fy, SXSIZE,SYSIZE,
108 printf("FULL SCREEN REDRAW [%d]\n", ScreenMovPos);
114 redraw_mask &= ~REDRAW_MAIN;
117 if (redraw_mask & REDRAW_DOORS)
119 if (redraw_mask & REDRAW_DOOR_1)
120 XCopyArea(display,backbuffer,window,gc,
121 DX,DY, DXSIZE,DYSIZE,
123 if (redraw_mask & REDRAW_DOOR_2)
125 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
126 XCopyArea(display,backbuffer,window,gc,
127 VX,VY, VXSIZE,VYSIZE,
131 if (redraw_mask & REDRAW_VIDEO_1)
132 XCopyArea(display,backbuffer,window,gc,
133 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
134 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
135 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
136 if (redraw_mask & REDRAW_VIDEO_2)
137 XCopyArea(display,backbuffer,window,gc,
138 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
139 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
140 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
141 if (redraw_mask & REDRAW_VIDEO_3)
142 XCopyArea(display,backbuffer,window,gc,
143 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
144 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
145 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
148 redraw_mask &= ~REDRAW_DOORS;
151 if (redraw_mask & REDRAW_MICROLEV)
153 XCopyArea(display,backbuffer,window,gc,
154 MICROLEV_XPOS,MICROLEV_YPOS, MICROLEV_XSIZE,MICROLEV_YSIZE,
155 MICROLEV_XPOS,MICROLEV_YPOS);
156 XCopyArea(display,backbuffer,window,gc,
157 SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE,
159 redraw_mask &= ~REDRAW_MICROLEV;
162 if (redraw_mask & REDRAW_TILES)
164 for(x=0; x<SCR_FIELDX; x++)
165 for(y=0; y<SCR_FIELDY; y++)
166 if (redraw[redraw_x1 + x][redraw_y1 + y])
167 XCopyArea(display,buffer,window,gc,
168 FX+x*TILEX,FX+y*TILEY, TILEX,TILEY,
169 SX+x*TILEX,SY+y*TILEY);
174 for(x=0; x<MAX_BUF_XSIZE; x++)
175 for(y=0; y<MAX_BUF_YSIZE; y++)
184 long fading_delay = 300000;
186 if (fading_on && (redraw_mask & REDRAW_FIELD))
193 XFillRectangle(display,window,gc,
194 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
197 for(i=0;i<2*FULL_SYSIZE;i++)
199 for(y=0;y<FULL_SYSIZE;y++)
201 XCopyArea(display,backbuffer,window,gc,
202 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
210 for(i=1;i<FULL_SYSIZE;i+=2)
211 XCopyArea(display,backbuffer,window,gc,
212 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
218 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
219 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
220 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
224 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
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],0,-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],-1,0);
237 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
238 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
242 redraw_mask &= ~REDRAW_MAIN;
251 XFillRectangle(display,backbuffer,gc,
252 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
254 if (soft_scrolling_on && game_status==PLAYING)
256 XFillRectangle(display,fieldbuffer,gc,
258 SetDrawtoField(DRAW_BUFFERED);
261 SetDrawtoField(DRAW_BACKBUFFER);
263 if (direct_draw_on && game_status==PLAYING)
265 XFillRectangle(display,window,gc,
266 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
267 SetDrawtoField(DRAW_DIRECT);
270 redraw_mask |= REDRAW_FIELD;
273 void DrawText(int x, int y, char *text, int font, int col)
275 DrawTextExt(drawto, gc, x, y, text, font, col);
277 redraw_mask |= REDRAW_FIELD;
279 redraw_mask |= REDRAW_DOOR_1;
282 void DrawTextExt(Drawable d, GC gc, int x, int y,
283 char *text, int font, int font_color)
285 int font_width, font_height, font_start;
288 if (font!=FS_SMALL && font!=FS_BIG)
290 if (font_color<FC_RED || font_color>FC_SPECIAL2)
294 (font==FS_BIG ? FONT1_XSIZE :
295 font_color<FC_SPECIAL1 ? FONT2_XSIZE :
296 font_color<FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
298 (font==FS_BIG ? FONT1_XSIZE :
299 font_color<FC_SPECIAL2 ? FONT2_XSIZE: FONT4_XSIZE);
300 font_pixmap = (font==FS_BIG ? PIX_BIGFONT : PIX_SMALLFONT);
302 font_color*(font==FS_BIG ? FONT1_YSIZE : FONT2_YSIZE)*FONT_LINES_PER_FONT;
308 if (c>='a' && c<='z')
310 else if (c=='ä' || c=='Ä')
312 else if (c=='ö' || c=='Ö')
314 else if (c=='ü' || c=='Ü')
318 XCopyArea(display,pix[font_pixmap],d,gc,
319 ((c-32) % FONT_CHARS_PER_LINE)*font_width,
320 ((c-32) / FONT_CHARS_PER_LINE)*font_height + font_start,
321 font_width,font_height, x,y);
327 void DrawPlayerField()
330 int sx = SCROLLX(x), sy = SCROLLY(y);
332 int sxx = 0, syy = 0;
334 int element = Feld[x][y];
336 BOOL draw_thru_mask = FALSE;
342 if (!IN_LEV_FIELD(x,y) || !IN_SCR_FIELD(sx,sy))
344 printf("DrawPlayerField(): x = %d, y = %d\n",x,y);
345 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
346 printf("DrawPlayerField(): This should never happen!\n");
351 if (element == EL_EXPLODING)
355 SetDrawtoField(DRAW_BUFFERED);
357 /* draw things behind the player (EL_PFORTE* || mole/penguin/pig/dragon) */
368 DrawGraphic(sx,sy, el2gfx(Store[x][y]));
369 draw_thru_mask = TRUE;
371 else if (element!=EL_DYNAMIT && element!=EL_DYNABOMB)
374 draw_thru_mask = TRUE;
378 else if (element!=EL_LEERRAUM && element!=EL_DYNAMIT && element!=EL_DYNABOMB)
381 draw_thru_mask = TRUE;
386 draw_thru_mask = TRUE;
391 /* draw player himself */
393 if (PlayerMovDir==MV_LEFT)
394 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT);
395 else if (PlayerMovDir==MV_RIGHT)
396 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT);
397 else if (PlayerMovDir==MV_UP)
398 graphic = GFX_SPIELER_UP;
399 else /* MV_DOWN || MV_NO_MOVING */
400 graphic = GFX_SPIELER_DOWN;
402 graphic += PlayerFrame;
407 if (PlayerMovDir == MV_LEFT || PlayerMovDir == MV_RIGHT)
414 if (!soft_scrolling_on && ScreenMovPos)
423 DrawGraphicShiftedThruMask(sx,sy,sxx,syy,graphic,CUT_NO_CUTTING);
425 DrawGraphicThruMask(sx, sy, graphic);
428 DrawGraphicShifted(sx,sy,sxx,syy,graphic,CUT_NO_CUTTING);
430 DrawGraphic(sx, sy, graphic);
435 MarkTileDirty(sx,sy);
439 if (PlayerPushing && PlayerGfxPos)
441 int nextJX = JX + (JX - lastJX);
442 int nextJY = JY + (JY - lastJY);
443 int px = SCROLLX(nextJX), py = SCROLLY(nextJY);
445 if (Feld[JX][JY] == EL_SOKOBAN_FELD_LEER ||
446 Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
447 DrawGraphicShiftedThruMask(px,py,sxx,syy,
452 int element = Feld[nextJX][nextJY];
453 int graphic = el2gfx(element);
455 if (element == EL_FELSBROCKEN && sxx)
457 int phase = (PlayerGfxPos / (TILEX/4));
459 if (PlayerMovDir == MV_LEFT)
462 graphic += (phase+4)%4;
466 printf("----> (%d, %d, %d)\n",
467 PlayerGfxPos, phase, graphic);
472 DrawGraphicShifted(px,py, sxx,syy, graphic, CUT_NO_CUTTING);
478 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
480 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
482 graphic = el2gfx(element);
484 if (element == EL_DYNAMIT)
486 if ((phase = (96-MovDelay[x][y])/12) > 6)
491 if ((phase = ((96-MovDelay[x][y])/6) % 8) > 3)
495 DrawGraphicThruMask(sx,sy, graphic + phase);
500 int dest_x = SX+SCROLLX(x)*TILEX;
501 int dest_y = SY+SCROLLY(y)*TILEY;
507 dest_x = SX + SCROLLX(MIN(JX,lastJX))*TILEX;
508 dest_y = SY + SCROLLY(MIN(JY,lastJY))*TILEY;
509 x_size = TILEX * (1 + ABS(JX - lastJX));
510 y_size = TILEY * (1 + ABS(JY - lastJY));
513 XCopyArea(display,drawto_field,window,gc,
514 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
515 SetDrawtoField(DRAW_DIRECT);
519 static int getGraphicAnimationPhase(int frames, int delay, int mode)
523 if (mode == ANIM_OSCILLATE)
525 int max_anim_frames = frames*2 - 2;
526 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
527 phase = (phase < frames ? phase : max_anim_frames - phase);
530 phase = (FrameCounter % (delay * frames)) / delay;
532 if (mode == ANIM_REVERSE)
538 void DrawGraphicAnimation(int x, int y, int graphic,
539 int frames, int delay, int mode)
541 int phase = getGraphicAnimationPhase(frames, delay, mode);
543 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
544 DrawGraphic(SCROLLX(x),SCROLLY(y), graphic + phase);
547 void DrawGraphic(int x, int y, int graphic)
551 if (!IN_SCR_FIELD(x,y))
553 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
554 printf("DrawGraphic(): This should never happen!\n");
559 DrawGraphicExt(drawto_field, gc, x, y, graphic);
563 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
565 DrawGraphicExtHiRes(d, gc, FX+x*TILEX, FY+y*TILEY, graphic);
568 void DrawGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
570 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
572 graphic -= GFX_START_ROCKSSCREEN;
573 XCopyArea(display,pix[PIX_BACK],d,gc,
574 SX+(graphic % GFX_PER_LINE)*TILEX,
575 SY+(graphic / GFX_PER_LINE)*TILEY,
578 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
580 graphic -= GFX_START_ROCKSHEROES;
581 XCopyArea(display,pix[PIX_HEROES],d,gc,
582 (graphic % HEROES_PER_LINE)*TILEX,
583 (graphic / HEROES_PER_LINE)*TILEY,
586 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
588 graphic -= GFX_START_ROCKSFONT;
589 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
590 (graphic % FONT_CHARS_PER_LINE)*TILEX,
591 (graphic / FONT_CHARS_PER_LINE)*TILEY +
592 FC_SPECIAL1*TILEY*FONT_LINES_PER_FONT,
596 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
599 void DrawGraphicThruMask(int x, int y, int graphic)
601 int src_x,src_y, dest_x,dest_y;
604 if (!IN_SCR_FIELD(x,y))
606 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
607 printf("DrawGraphicThruMask(): This should never happen!\n");
612 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
614 graphic -= GFX_START_ROCKSSCREEN;
615 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
616 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
620 XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y);
621 XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK],
622 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
624 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
626 graphic -= GFX_START_ROCKSHEROES;
627 src_x = (graphic % HEROES_PER_LINE)*TILEX;
628 src_y = (graphic / HEROES_PER_LINE)*TILEY;
632 XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
633 XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
634 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
638 DrawGraphic(x,y,graphic);
645 void DrawElementThruMask(int x, int y, int element)
647 DrawGraphicThruMask(x,y,el2gfx(element));
650 void DrawMiniGraphic(int x, int y, int graphic)
652 DrawMiniGraphicExt(drawto, gc, x, y, graphic);
653 MarkTileDirty(x/2, y/2);
656 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
658 DrawMiniGraphicExtHiRes(d,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
661 void DrawMiniGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
663 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
665 graphic -= GFX_START_ROCKSSCREEN;
666 XCopyArea(display,pix[PIX_BACK],d,gc,
667 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
668 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
669 MINI_TILEX,MINI_TILEY, x,y);
671 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
673 graphic -= GFX_START_ROCKSFONT;
674 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
675 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
676 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
677 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
678 MINI_TILEX,MINI_TILEY, x,y);
681 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
684 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, int cut_mode)
686 int width = TILEX, height = TILEY;
691 DrawGraphic(x,y,graphic);
695 if (dx || dy) /* Verschiebung der Grafik? */
697 if (x < BX1) /* Element kommt von links ins Bild */
704 else if (x > BX2) /* Element kommt von rechts ins Bild */
710 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
716 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
718 else if (dx) /* allg. Bewegung in x-Richtung */
719 MarkTileDirty(x + SIGN(dx), y);
721 if (y < BY1) /* Element kommt von oben ins Bild */
723 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
731 else if (y > BY2) /* Element kommt von unten ins Bild */
737 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
743 else if (dy > 0 && cut_mode==CUT_ABOVE)
745 if (y == BY2) /* Element unterhalb des Bildes */
751 MarkTileDirty(x, y + 1);
752 } /* Element verläßt unten das Bild */
753 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
755 else if (dy) /* allg. Bewegung in y-Richtung */
756 MarkTileDirty(x, y + SIGN(dy));
759 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
761 graphic -= GFX_START_ROCKSSCREEN;
762 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
763 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
764 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
765 width,height, FX+x*TILEX+dx,FY+y*TILEY+dy);
767 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
769 graphic -= GFX_START_ROCKSHEROES;
770 XCopyArea(display,pix[PIX_HEROES],drawto_field,gc,
771 (graphic % HEROES_PER_LINE)*TILEX+cx,
772 (graphic / HEROES_PER_LINE)*TILEY+cy,
773 width,height, FX+x*TILEX+dx,FY+y*TILEY+dy);
777 if (!IN_SCR_FIELD(x,y))
779 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
780 printf("DrawGraphicShifted(): This should never happen!\n");
788 void DrawElementShifted(int x, int y, int dx, int dy, int element,int cut_mode)
790 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
791 int graphic = el2gfx(element);
792 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
793 int phase = phase4 / 2;
794 int dir = MovDir[ux][uy];
796 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
802 else if (dir == MV_LEFT)
804 else if (dir == MV_DOWN)
807 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
808 element==EL_SCHWEIN || element==EL_DRACHE)
811 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
812 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
813 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
814 else if (dir==MV_RIGHT)
815 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
816 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
817 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
819 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
820 element==EL_PINGUIN ? GFX_PINGUIN_UP :
821 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
823 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
824 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
825 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
829 else if (element==EL_SONDE)
831 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
833 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
837 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
839 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
841 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
842 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
844 graphic += 3-(SiebAktiv%8)/2;
846 else if (IS_AMOEBOID(element))
848 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
849 graphic += (x+2*y) % 4;
851 else if (element==EL_MAUER_LEBT)
853 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
855 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
857 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
858 rechts_massiv = TRUE;
860 if (links_massiv && rechts_massiv)
861 graphic = GFX_MAUERWERK;
862 else if (links_massiv)
863 graphic = GFX_MAUER_R;
864 else if (rechts_massiv)
865 graphic = GFX_MAUER_L;
869 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode);
871 DrawGraphic(x,y, graphic);
874 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
877 int width = TILEX, height = TILEY;
879 int src_x,src_y, dest_x,dest_y;
883 DrawGraphic(x,y,graphic);
887 if (dx || dy) /* Verschiebung der Grafik? */
889 if (x < BX1) /* Element kommt von links ins Bild */
896 else if (x > BX2) /* Element kommt von rechts ins Bild */
902 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
908 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
910 else if (dx) /* allg. Bewegung in x-Richtung */
911 MarkTileDirty(x + SIGN(dx), y);
913 if (y < BY1) /* Element kommt von oben ins Bild */
915 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
923 else if (y > BY2) /* Element kommt von unten ins Bild */
929 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
935 else if (dy > 0 && cut_mode==CUT_ABOVE)
937 if (y == BY2) /* Element unterhalb des Bildes */
943 MarkTileDirty(x, y + 1);
944 } /* Element verläßt unten das Bild */
945 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
947 else if (dy) /* allg. Bewegung in y-Richtung */
948 MarkTileDirty(x, y + SIGN(dy));
951 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
953 graphic -= GFX_START_ROCKSSCREEN;
954 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
955 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
956 dest_x = FX+x*TILEX+dx;
957 dest_y = FY+y*TILEY+dy;
959 XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y);
960 XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK],
961 src_x,src_y, width,height, dest_x,dest_y);
963 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
965 graphic -= GFX_START_ROCKSHEROES;
966 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
967 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
968 dest_x = FX+x*TILEX+dx;
969 dest_y = FY+y*TILEY+dy;
971 XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
972 XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
973 src_x,src_y, width,height, dest_x,dest_y);
977 if (!IN_SCR_FIELD(x,y))
979 printf("DrawGraphicShiftedThruMask(): x = %d, y = %d, graphic = %d\n",
981 printf("DrawGraphicShifted(): This should never happen!\n");
989 void ErdreichAnbroeckeln(int x, int y)
991 int i, width, height, cx,cy;
992 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
993 int element, graphic;
995 static int xy[4][2] =
1003 if (!IN_LEV_FIELD(ux,uy))
1006 element = Feld[ux][uy];
1008 if (element==EL_ERDREICH)
1010 if (!IN_SCR_FIELD(x,y))
1013 graphic = GFX_ERDENRAND;
1021 if (!IN_LEV_FIELD(uxx,uyy))
1024 element = Feld[uxx][uyy];
1027 if (element==EL_ERDREICH || IS_SOLID(element))
1030 if (element==EL_ERDREICH)
1037 cx = (i==2 ? TILEX-snip : 0);
1045 cy = (i==3 ? TILEY-snip : 0);
1048 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1049 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1050 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1051 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1058 graphic = GFX_ERDENRAND;
1069 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1070 !IN_SCR_FIELD(xx,yy) || IS_SOLID(element))
1074 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1075 !IN_SCR_FIELD(xx,yy))
1082 cx = (i==1 ? TILEX-snip : 0);
1090 cy = (i==0 ? TILEY-snip : 0);
1093 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1094 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1095 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1096 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1098 MarkTileDirty(xx,yy);
1103 void DrawScreenElement(int x, int y, int element)
1105 DrawElementShifted(x,y,0,0,element,CUT_NO_CUTTING);
1106 ErdreichAnbroeckeln(x,y);
1109 void DrawLevelElement(int x, int y, int element)
1111 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1112 DrawScreenElement(SCROLLX(x),SCROLLY(y),element);
1115 void DrawScreenField(int x, int y)
1117 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
1120 if (!IN_LEV_FIELD(ux,uy))
1122 DrawScreenElement(x,y,EL_BETON);
1126 element = Feld[ux][uy];
1128 if (IS_MOVING(ux,uy))
1130 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1131 BOOL cut_mode = CUT_NO_CUTTING;
1133 if (Store[ux][uy]==EL_MORAST_LEER ||
1134 Store[ux][uy]==EL_SIEB_LEER ||
1135 Store[ux][uy]==EL_SIEB2_LEER ||
1136 Store[ux][uy]==EL_AMOEBE_NASS)
1137 cut_mode = CUT_ABOVE;
1138 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1139 Store[ux][uy]==EL_SIEB_VOLL ||
1140 Store[ux][uy]==EL_SIEB2_VOLL ||
1141 Store[ux][uy]==EL_SALZSAEURE)
1142 cut_mode = CUT_BELOW;
1144 if (cut_mode==CUT_ABOVE)
1145 DrawElementShifted(x,y,0,0,Store[ux][uy],CUT_NO_CUTTING);
1147 DrawScreenElement(x,y,EL_LEERRAUM);
1150 DrawElementShifted(x,y,MovPos[ux][uy],0,element,CUT_NO_CUTTING);
1152 DrawElementShifted(x,y,0,MovPos[ux][uy],element,cut_mode);
1154 else if (IS_BLOCKED(ux,uy))
1159 BOOL cut_mode = CUT_NO_CUTTING;
1161 Blocked2Moving(ux,uy,&oldx,&oldy);
1164 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1166 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1167 Store[oldx][oldy]==EL_SIEB_LEER ||
1168 Store[oldx][oldy]==EL_SIEB2_LEER ||
1169 Store[oldx][oldy]==EL_AMOEBE_NASS)
1170 cut_mode = CUT_ABOVE;
1172 DrawScreenElement(x,y,EL_LEERRAUM);
1173 element = Feld[oldx][oldy];
1176 DrawElementShifted(sx,sy,MovPos[oldx][oldy],0,element,CUT_NO_CUTTING);
1178 DrawElementShifted(sx,sy,0,MovPos[oldx][oldy],element,cut_mode);
1180 else if (IS_DRAWABLE(element))
1181 DrawScreenElement(x,y,element);
1183 DrawScreenElement(x,y,EL_LEERRAUM);
1186 void DrawLevelField(int x, int y)
1188 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1189 DrawScreenField(SCROLLX(x),SCROLLY(y));
1190 else if (IS_MOVING(x,y))
1194 Moving2Blocked(x,y,&newx,&newy);
1195 if (IN_SCR_FIELD(SCROLLX(newx),SCROLLY(newy)))
1196 DrawScreenField(SCROLLX(newx),SCROLLY(newy));
1198 else if (IS_BLOCKED(x,y))
1202 Blocked2Moving(x,y,&oldx,&oldy);
1203 if (IN_SCR_FIELD(SCROLLX(oldx),SCROLLY(oldy)))
1204 DrawScreenField(SCROLLX(oldx),SCROLLY(oldy));
1208 void DrawMiniElement(int x, int y, int element)
1214 DrawMiniGraphic(x,y,-1);
1218 graphic = el2gfx(element);
1219 DrawMiniGraphic(x,y,graphic);
1222 void DrawMiniElementOrWall(int x, int y, int scroll_x, int scroll_y)
1224 if (x+scroll_x<-1 || x+scroll_x>lev_fieldx ||
1225 y+scroll_y<-1 || y+scroll_y>lev_fieldy)
1226 DrawMiniElement(x,y,EL_LEERRAUM);
1227 else if (x+scroll_x==-1 || x+scroll_x==lev_fieldx ||
1228 y+scroll_y==-1 || y+scroll_y==lev_fieldy)
1229 DrawMiniElement(x,y,EL_BETON);
1231 DrawMiniElement(x,y,Feld[x+scroll_x][y+scroll_y]);
1234 void DrawMicroElement(int xpos, int ypos, int element)
1238 if (element==EL_LEERRAUM)
1241 graphic = el2gfx(element);
1243 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1244 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1245 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1246 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1255 for(x=BX1; x<=BX2; x++)
1256 for(y=BY1; y<=BY2; y++)
1257 DrawScreenField(x,y);
1259 if (soft_scrolling_on)
1260 XCopyArea(display,fieldbuffer,backbuffer,gc,
1261 FX,FY, SXSIZE,SYSIZE,
1264 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1267 void DrawMiniLevel(int scroll_x, int scroll_y)
1273 for(x=0;x<2*SCR_FIELDX;x++)
1274 for(y=0;y<2*SCR_FIELDY;y++)
1275 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1277 redraw_mask |= REDRAW_FIELD;
1280 void DrawMicroLevel(int xpos, int ypos)
1284 XFillRectangle(display,drawto,gc,
1285 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1286 MICRO_TILEX*(STD_LEV_FIELDX+2),
1287 MICRO_TILEY*(STD_LEV_FIELDY+2));
1288 if (lev_fieldx < STD_LEV_FIELDX)
1289 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1290 if (lev_fieldy < STD_LEV_FIELDY)
1291 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1293 for(x=-1;x<=STD_LEV_FIELDX;x++)
1294 for(y=-1;y<=STD_LEV_FIELDY;y++)
1295 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1296 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1297 Feld[x][y]=Ur[x][y]);
1298 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1299 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1302 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1306 int len = strlen(level.name);
1307 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1308 int lypos = MICROLABEL_YPOS;
1310 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1313 redraw_mask |= REDRAW_MICROLEV;
1316 int AYS_in_range(int x, int y)
1318 if (y>DY+249 && y<DY+278)
1320 if (x>DX+1 && x<DX+48)
1322 else if (x>DX+51 && x<DX+98)
1328 BOOL AreYouSure(char *text, unsigned int ays_state)
1330 int mx,my, ty, result = -1;
1331 unsigned int old_door_state;
1333 old_door_state = GetDoorState();
1335 CloseDoor(DOOR_CLOSE_1);
1337 /* Alten Türinhalt sichern */
1338 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1339 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1340 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1342 /* Fragetext schreiben */
1343 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1344 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1346 for(ty=0;ty<13;ty++)
1353 for(tl=0,tx=0;tx<7;tl++,tx++)
1367 DrawTextExt(pix[PIX_DB_DOOR],gc,
1368 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1369 text+=(tl+(tc==32));
1372 if (ays_state & AYS_ASK)
1373 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1374 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1375 DXSIZE,OK_BUTTON_YSIZE,
1376 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1377 else if (ays_state & AYS_CONFIRM)
1378 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1379 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1380 DXSIZE,CONFIRM_BUTTON_YSIZE,
1381 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1383 OpenDoor(DOOR_OPEN_1);
1386 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1389 if (game_status != MAINMENU)
1392 button_status = MB_RELEASED;
1399 if (XPending(display))
1403 XNextEvent(display, &event);
1407 HandleExposeEvent((XExposeEvent *) &event);
1410 SleepWhileUnmapped();
1418 if (event.type == MotionNotify)
1420 motion_status = TRUE;
1421 mx = ((XMotionEvent *) &event)->x;
1422 my = ((XMotionEvent *) &event)->y;
1426 motion_status = FALSE;
1427 mx = ((XButtonEvent *) &event)->x;
1428 my = ((XButtonEvent *) &event)->y;
1429 if (event.type==ButtonPress)
1430 button_status = ((XButtonEvent *) &event)->button;
1432 button_status = MB_RELEASED;
1435 if (ays_state & AYS_ASK)
1436 choice = CheckChooseButtons(mx,my,button_status);
1438 choice = CheckConfirmButton(mx,my,button_status);
1448 case BUTTON_CONFIRM:
1449 result = TRUE|FALSE;
1457 switch(XLookupKeysym((XKeyEvent *)&event,
1458 ((XKeyEvent *)&event)->state))
1470 HandleFocusEvent((XFocusChangeEvent *) &event);
1476 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1480 if (joy & JOY_BUTTON_1)
1482 else if (joy & JOY_BUTTON_2)
1487 if (game_status != MAINMENU)
1490 if (!(ays_state & AYS_STAY_OPEN))
1492 CloseDoor(DOOR_CLOSE_1);
1494 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1496 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1497 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1498 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1499 OpenDoor(DOOR_OPEN_1);
1506 unsigned int OpenDoor(unsigned int door_state)
1508 unsigned int new_door_state;
1510 if (door_state & DOOR_COPY_BACK)
1512 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1513 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1514 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1515 door_state &= ~DOOR_COPY_BACK;
1518 new_door_state = MoveDoor(door_state);
1524 return(new_door_state);
1527 unsigned int CloseDoor(unsigned int door_state)
1529 unsigned int new_door_state;
1531 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1532 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1533 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1534 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1536 new_door_state = MoveDoor(door_state);
1542 return(new_door_state);
1545 unsigned int GetDoorState()
1547 return(MoveDoor(DOOR_GET_STATE));
1550 unsigned int MoveDoor(unsigned int door_state)
1552 static unsigned int door1 = DOOR_OPEN_1;
1553 static unsigned int door2 = DOOR_CLOSE_2;
1554 int x, start, stepsize = 4, door_anim_delay = stepsize*5000;
1556 if (door_state == DOOR_GET_STATE)
1557 return(door1 | door2);
1559 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1560 door_state &= ~DOOR_OPEN_1;
1561 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1562 door_state &= ~DOOR_CLOSE_1;
1563 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1564 door_state &= ~DOOR_OPEN_2;
1565 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1566 door_state &= ~DOOR_CLOSE_2;
1571 door_anim_delay = 0;
1572 StopSound(SND_OEFFNEN);
1575 if (door_state & DOOR_ACTION)
1577 if (!(door_state & DOOR_NO_DELAY))
1578 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1580 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1582 for(x=start;x<=DXSIZE;x+=stepsize)
1584 if (door_state & DOOR_ACTION_1)
1586 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1587 int j = (DXSIZE - i)/3;
1589 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1590 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1591 DXSIZE,DYSIZE-i/2, DX,DY);
1593 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1595 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1596 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1597 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1598 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1599 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1600 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1601 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1602 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1603 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1604 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1605 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1606 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1608 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1609 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1611 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1612 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1614 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1615 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1616 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1617 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1618 DX+DXSIZE-i,DY+77+j);
1619 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1620 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1621 DX+DXSIZE-i,DY+203+j);
1623 redraw_mask |= REDRAW_DOOR_1;
1626 if (door_state & DOOR_ACTION_2)
1628 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1629 int j = (VXSIZE - i)/3;
1631 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1632 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1633 VXSIZE,VYSIZE-i/2, VX,VY);
1635 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1637 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1638 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1639 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1640 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1641 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1642 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1643 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1644 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1646 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1647 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1649 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1650 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1651 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1652 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1653 VX+VXSIZE-i,VY+VYSIZE/2+j);
1655 redraw_mask |= REDRAW_DOOR_2;
1659 Delay(door_anim_delay);
1661 if (game_status==MAINMENU)
1666 if (door_state & DOOR_ACTION_1)
1667 door1 = door_state & DOOR_ACTION_1;
1668 if (door_state & DOOR_ACTION_2)
1669 door2 = door_state & DOOR_ACTION_2;
1671 return(door1 | door2);
1674 int ReadPixel(Drawable d, int x, int y)
1676 static XImage *pixelimage;
1678 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1679 return(XGetPixel(pixelimage,0,0));
1682 int el2gfx(int element)
1686 case EL_LEERRAUM: return(-1);
1687 case EL_ERDREICH: return(GFX_ERDREICH);
1688 case EL_MAUERWERK: return(GFX_MAUERWERK);
1689 case EL_FELSBODEN: return(GFX_FELSBODEN);
1690 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1691 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1692 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1693 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1694 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1695 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1696 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1697 case EL_SPIELER1: return(GFX_SPIELER1);
1698 case EL_SPIELER2: return(GFX_SPIELER2);
1699 case EL_SPIELER3: return(GFX_SPIELER3);
1700 case EL_SPIELER4: return(GFX_SPIELER4);
1701 case EL_KAEFER: return(GFX_KAEFER);
1702 case EL_KAEFER_R: return(GFX_KAEFER_R);
1703 case EL_KAEFER_O: return(GFX_KAEFER_O);
1704 case EL_KAEFER_L: return(GFX_KAEFER_L);
1705 case EL_KAEFER_U: return(GFX_KAEFER_U);
1706 case EL_FLIEGER: return(GFX_FLIEGER);
1707 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1708 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1709 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1710 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1711 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1712 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1713 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1714 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1715 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1716 case EL_FIREFLY: return(GFX_FIREFLY);
1717 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1718 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1719 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1720 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1721 case EL_MAMPFER: return(GFX_MAMPFER);
1722 case EL_ROBOT: return(GFX_ROBOT);
1723 case EL_BETON: return(GFX_BETON);
1724 case EL_DIAMANT: return(GFX_DIAMANT);
1725 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1726 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1727 case EL_TROPFEN: return(GFX_TROPFEN);
1728 case EL_BOMBE: return(GFX_BOMBE);
1729 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1730 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1731 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1732 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1733 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1734 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1735 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1736 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1737 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1738 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1739 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1740 case EL_LIFE: return(GFX_LIFE);
1741 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1742 case EL_DYNAMIT: return(GFX_DYNAMIT);
1743 case EL_BADEWANNE: return(GFX_BADEWANNE);
1744 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1745 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1746 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1747 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1748 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1749 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1750 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1751 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1752 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1753 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1754 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1755 case EL_PFORTE1: return(GFX_PFORTE1);
1756 case EL_PFORTE2: return(GFX_PFORTE2);
1757 case EL_PFORTE3: return(GFX_PFORTE3);
1758 case EL_PFORTE4: return(GFX_PFORTE4);
1759 case EL_PFORTE1X: return(GFX_PFORTE1X);
1760 case EL_PFORTE2X: return(GFX_PFORTE2X);
1761 case EL_PFORTE3X: return(GFX_PFORTE3X);
1762 case EL_PFORTE4X: return(GFX_PFORTE4X);
1763 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1764 case EL_PACMAN: return(GFX_PACMAN);
1765 case EL_PACMAN_R: return(GFX_PACMAN_R);
1766 case EL_PACMAN_O: return(GFX_PACMAN_O);
1767 case EL_PACMAN_L: return(GFX_PACMAN_L);
1768 case EL_PACMAN_U: return(GFX_PACMAN_U);
1769 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1770 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1771 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1772 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1773 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1774 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1775 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1776 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1777 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1778 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1779 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1780 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1781 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1782 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1783 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1784 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1785 case EL_MAMPFER2: return(GFX_MAMPFER2);
1786 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1787 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1788 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1789 case EL_DYNABOMB: return(GFX_DYNABOMB);
1790 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1791 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1792 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1793 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1794 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1795 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1796 case EL_MAULWURF: return(GFX_MAULWURF);
1797 case EL_PINGUIN: return(GFX_PINGUIN);
1798 case EL_SCHWEIN: return(GFX_SCHWEIN);
1799 case EL_DRACHE: return(GFX_DRACHE);
1800 case EL_SONDE: return(GFX_SONDE);
1801 case EL_PFEIL_L: return(GFX_PFEIL_L);
1802 case EL_PFEIL_R: return(GFX_PFEIL_R);
1803 case EL_PFEIL_O: return(GFX_PFEIL_O);
1804 case EL_PFEIL_U: return(GFX_PFEIL_U);
1807 if (IS_CHAR(element))
1808 return(GFX_CHAR_START + (element-EL_CHAR_START));