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 = 300;
192 if (fading_on && (redraw_mask & REDRAW_FIELD))
199 XFillRectangle(display,window,gc,
200 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
203 for(i=0;i<2*FULL_SYSIZE;i++)
205 for(y=0;y<FULL_SYSIZE;y++)
207 XCopyArea(display,backbuffer,window,gc,
208 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
216 for(i=1;i<FULL_SYSIZE;i+=2)
217 XCopyArea(display,backbuffer,window,gc,
218 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
224 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
225 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
226 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
230 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
231 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
232 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
236 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
237 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
238 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
242 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
243 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
244 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
248 redraw_mask &= ~REDRAW_MAIN;
257 XFillRectangle(display,backbuffer,gc,
258 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
260 if (soft_scrolling_on && game_status==PLAYING)
262 XFillRectangle(display,fieldbuffer,gc,
264 SetDrawtoField(DRAW_BUFFERED);
267 SetDrawtoField(DRAW_BACKBUFFER);
269 if (direct_draw_on && game_status==PLAYING)
271 XFillRectangle(display,window,gc,
272 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
273 SetDrawtoField(DRAW_DIRECT);
276 redraw_mask |= REDRAW_FIELD;
279 void DrawText(int x, int y, char *text, int font, int col)
281 DrawTextExt(drawto, gc, x, y, text, font, col);
283 redraw_mask |= REDRAW_FIELD;
285 redraw_mask |= REDRAW_DOOR_1;
288 void DrawTextExt(Drawable d, GC gc, int x, int y,
289 char *text, int font, int font_color)
291 int font_width, font_height, font_start;
294 if (font!=FS_SMALL && font!=FS_BIG)
296 if (font_color<FC_RED || font_color>FC_SPECIAL2)
300 (font==FS_BIG ? FONT1_XSIZE :
301 font_color<FC_SPECIAL1 ? FONT2_XSIZE :
302 font_color<FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
304 (font==FS_BIG ? FONT1_XSIZE :
305 font_color<FC_SPECIAL2 ? FONT2_XSIZE: FONT4_XSIZE);
306 font_pixmap = (font==FS_BIG ? PIX_BIGFONT : PIX_SMALLFONT);
308 font_color*(font==FS_BIG ? FONT1_YSIZE : FONT2_YSIZE)*FONT_LINES_PER_FONT;
314 if (c>='a' && c<='z')
316 else if (c=='ä' || c=='Ä')
318 else if (c=='ö' || c=='Ö')
320 else if (c=='ü' || c=='Ü')
324 XCopyArea(display,pix[font_pixmap],d,gc,
325 ((c-32) % FONT_CHARS_PER_LINE)*font_width,
326 ((c-32) / FONT_CHARS_PER_LINE)*font_height + font_start,
327 font_width,font_height, x,y);
333 void DrawPlayerField()
336 int sx = SCROLLX(x), sy = SCROLLY(y);
338 int sxx = 0, syy = 0;
340 int element = Feld[x][y];
347 if (!IN_LEV_FIELD(x,y) || !IN_SCR_FIELD(sx,sy))
349 printf("DrawPlayerField(): x = %d, y = %d\n",x,y);
350 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
351 printf("DrawPlayerField(): This should never happen!\n");
356 if (element == EL_EXPLODING)
360 SetDrawtoField(DRAW_BUFFERED);
362 /* draw things in the field the player is leaving, if needed */
364 if (lastJX != JX || lastJY != JY)
366 if (Store[lastJX][lastJY])
368 DrawLevelElement(lastJX,lastJY, Store[lastJX][lastJY]);
369 DrawLevelElementThruMask(lastJX,lastJY, Feld[lastJX][lastJY]);
371 else if (Feld[lastJX][lastJY] == EL_DYNAMIT)
372 DrawDynamite(lastJX,lastJY);
374 DrawLevelField(lastJX,lastJY);
378 int nextJX = JX + (JX - lastJX);
379 int nextJY = JY + (JY - lastJY);
383 if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
384 DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER);
386 DrawLevelElement(nextJX,nextJY, EL_LEERRAUM);
389 DrawLevelField(nextJX,nextJY);
393 /* draw things behind the player, if needed */
396 DrawLevelElement(x,y, Store[x][y]);
397 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
400 /* draw player himself */
402 if (PlayerMovDir==MV_LEFT)
403 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT);
404 else if (PlayerMovDir==MV_RIGHT)
405 graphic = (PlayerPushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT);
406 else if (PlayerMovDir==MV_UP)
407 graphic = GFX_SPIELER_UP;
408 else /* MV_DOWN || MV_NO_MOVING */
409 graphic = GFX_SPIELER_DOWN;
411 graphic += PlayerFrame;
415 if (PlayerMovDir == MV_LEFT || PlayerMovDir == MV_RIGHT)
421 if (!soft_scrolling_on && ScreenMovPos)
424 DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING);
426 if (PlayerPushing && PlayerGfxPos)
428 int nextJX = JX + (JX - lastJX);
429 int nextJY = JY + (JY - lastJY);
430 int px = SCROLLX(nextJX), py = SCROLLY(nextJY);
432 if (Feld[JX][JY] == EL_SOKOBAN_FELD_LEER ||
433 Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
434 DrawGraphicShiftedThruMask(px,py,sxx,syy, GFX_SOKOBAN_OBJEKT,NO_CUTTING);
437 int element = Feld[nextJX][nextJY];
438 int graphic = el2gfx(element);
440 if (element == EL_FELSBROCKEN && sxx)
442 int phase = (PlayerGfxPos / (TILEX/4));
444 if (PlayerMovDir == MV_LEFT)
447 graphic += (phase+4)%4;
450 DrawGraphicShifted(px,py, sxx,syy, graphic, NO_CUTTING, NO_MASKING);
454 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
456 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
458 graphic = el2gfx(element);
460 if (element == EL_DYNAMIT)
462 if ((phase = (96-MovDelay[x][y])/12) > 6)
467 if ((phase = ((96-MovDelay[x][y])/6) % 8) > 3)
471 DrawGraphicThruMask(sx,sy, graphic + phase);
476 int dest_x = SX+SCROLLX(x)*TILEX;
477 int dest_y = SY+SCROLLY(y)*TILEY;
483 dest_x = SX + SCROLLX(MIN(JX,lastJX))*TILEX;
484 dest_y = SY + SCROLLY(MIN(JY,lastJY))*TILEY;
485 x_size = TILEX * (1 + ABS(JX - lastJX));
486 y_size = TILEY * (1 + ABS(JY - lastJY));
489 XCopyArea(display,drawto_field,window,gc,
490 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
491 SetDrawtoField(DRAW_DIRECT);
494 MarkTileDirty(sx,sy);
497 static int getGraphicAnimationPhase(int frames, int delay, int mode)
501 if (mode == ANIM_OSCILLATE)
503 int max_anim_frames = frames*2 - 2;
504 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
505 phase = (phase < frames ? phase : max_anim_frames - phase);
508 phase = (FrameCounter % (delay * frames)) / delay;
510 if (mode == ANIM_REVERSE)
516 void DrawGraphicAnimationExt(int x, int y, int graphic,
517 int frames, int delay, int mode, int mask_mode)
519 int phase = getGraphicAnimationPhase(frames, delay, mode);
521 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
523 if (mask_mode == USE_MASKING)
524 DrawGraphicThruMask(SCROLLX(x),SCROLLY(y), graphic + phase);
526 DrawGraphic(SCROLLX(x),SCROLLY(y), graphic + phase);
530 void DrawGraphicAnimation(int x, int y, int graphic,
531 int frames, int delay, int mode)
533 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, NO_MASKING);
536 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
537 int frames, int delay, int mode)
539 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, USE_MASKING);
542 void DrawGraphic(int x, int y, int graphic)
546 if (!IN_SCR_FIELD(x,y))
548 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
549 printf("DrawGraphic(): This should never happen!\n");
554 DrawGraphicExt(drawto_field, gc, FX+x*TILEX, FY+y*TILEY, graphic);
558 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
560 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
562 graphic -= GFX_START_ROCKSSCREEN;
563 XCopyArea(display,pix[PIX_BACK],d,gc,
564 SX + (graphic % GFX_PER_LINE) * TILEX,
565 SY + (graphic / GFX_PER_LINE) * TILEY,
568 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
570 graphic -= GFX_START_ROCKSHEROES;
571 XCopyArea(display,pix[PIX_HEROES],d,gc,
572 (graphic % HEROES_PER_LINE) * TILEX,
573 (graphic / HEROES_PER_LINE) * TILEY,
576 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
578 graphic -= GFX_START_ROCKSFONT;
579 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
580 (graphic % FONT_CHARS_PER_LINE) * TILEX,
581 (graphic / FONT_CHARS_PER_LINE) * TILEY +
582 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
586 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
589 void DrawGraphicThruMask(int x, int y, int graphic)
591 int src_x,src_y, dest_x,dest_y;
597 if (!IN_SCR_FIELD(x,y))
599 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
600 printf("DrawGraphicThruMask(): This should never happen!\n");
605 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
607 src_pixmap = pix[PIX_BACK];
608 drawing_gc = clip_gc[PIX_BACK];
609 graphic -= GFX_START_ROCKSSCREEN;
610 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
611 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
613 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
615 src_pixmap = pix[PIX_HEROES];
616 drawing_gc = clip_gc[PIX_HEROES];
617 graphic -= GFX_START_ROCKSHEROES;
618 src_x = (graphic % HEROES_PER_LINE)*TILEX;
619 src_y = (graphic / HEROES_PER_LINE)*TILEY;
623 DrawGraphic(x,y,graphic);
627 dest_x = FX + x*TILEX;
628 dest_y = FY + y*TILEY;
630 if (tile_clipmask[tile] != None)
632 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
633 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
634 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
635 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
640 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
643 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
644 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
645 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
651 void DrawMiniGraphic(int x, int y, int graphic)
653 DrawMiniGraphicExt(drawto,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
654 MarkTileDirty(x/2, y/2);
657 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
659 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
661 graphic -= GFX_START_ROCKSSCREEN;
662 XCopyArea(display,pix[PIX_BACK],d,gc,
663 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
664 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
665 MINI_TILEX,MINI_TILEY, x,y);
667 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
669 graphic -= GFX_START_ROCKSFONT;
670 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
671 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
672 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
673 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
674 MINI_TILEX,MINI_TILEY, x,y);
677 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
680 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
681 int cut_mode, int mask_mode)
683 int width = TILEX, height = TILEY;
685 int src_x,src_y, dest_x,dest_y;
692 DrawGraphic(x,y,graphic);
696 if (dx || dy) /* Verschiebung der Grafik? */
698 if (x < BX1) /* Element kommt von links ins Bild */
705 else if (x > BX2) /* Element kommt von rechts ins Bild */
711 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
717 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
719 else if (dx) /* allg. Bewegung in x-Richtung */
720 MarkTileDirty(x + SIGN(dx), y);
722 if (y < BY1) /* Element kommt von oben ins Bild */
724 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
732 else if (y > BY2) /* Element kommt von unten ins Bild */
738 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
744 else if (dy > 0 && cut_mode==CUT_ABOVE)
746 if (y == BY2) /* Element unterhalb des Bildes */
752 MarkTileDirty(x, y + 1);
753 } /* Element verläßt unten das Bild */
754 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
756 else if (dy) /* allg. Bewegung in y-Richtung */
757 MarkTileDirty(x, y + SIGN(dy));
760 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
762 src_pixmap = pix[PIX_BACK];
763 drawing_gc = clip_gc[PIX_BACK];
764 graphic -= GFX_START_ROCKSSCREEN;
765 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
766 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
768 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
770 src_pixmap = pix[PIX_HEROES];
771 drawing_gc = clip_gc[PIX_HEROES];
772 graphic -= GFX_START_ROCKSHEROES;
773 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
774 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
777 dest_x = FX + x*TILEX + dx;
778 dest_y = FY + y*TILEY + dy;
781 if (!IN_SCR_FIELD(x,y))
783 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
784 printf("DrawGraphicShifted(): This should never happen!\n");
789 if (mask_mode == USE_MASKING)
791 if (tile_clipmask[tile] != None)
793 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
794 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
795 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
796 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
801 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
804 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
805 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
806 src_x,src_y, width,height, dest_x,dest_y);
810 XCopyArea(display, src_pixmap, drawto_field, gc,
811 src_x,src_y, width,height, dest_x,dest_y);
816 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
819 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
822 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
823 int cut_mode, int mask_mode)
825 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
826 int graphic = el2gfx(element);
827 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
828 int phase = phase4 / 2;
829 int dir = MovDir[ux][uy];
831 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
837 else if (dir == MV_LEFT)
839 else if (dir == MV_DOWN)
842 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
843 element==EL_SCHWEIN || element==EL_DRACHE)
846 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
847 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
848 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
849 else if (dir==MV_RIGHT)
850 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
851 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
852 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
854 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
855 element==EL_PINGUIN ? GFX_PINGUIN_UP :
856 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
858 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
859 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
860 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
864 else if (element==EL_SONDE)
866 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
868 else if (element==EL_SALZSAEURE)
870 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
872 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
876 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
878 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
880 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
881 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
883 graphic += 3-(SiebAktiv%8)/2;
885 else if (IS_AMOEBOID(element))
887 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
888 graphic += (x+2*y) % 4;
890 else if (element==EL_MAUER_LEBT)
892 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
894 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
896 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
897 rechts_massiv = TRUE;
899 if (links_massiv && rechts_massiv)
900 graphic = GFX_MAUERWERK;
901 else if (links_massiv)
902 graphic = GFX_MAUER_R;
903 else if (rechts_massiv)
904 graphic = GFX_MAUER_L;
908 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, mask_mode);
909 else if (mask_mode == USE_MASKING)
910 DrawGraphicThruMask(x,y, graphic);
912 DrawGraphic(x,y, graphic);
915 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
916 int cut_mode, int mask_mode)
918 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
919 DrawScreenElementExt(SCROLLX(x),SCROLLY(y), dx,dy, element,
920 cut_mode, mask_mode);
923 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
926 DrawScreenElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
929 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
932 DrawLevelElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
935 void DrawScreenElementThruMask(int x, int y, int element)
937 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
940 void DrawLevelElementThruMask(int x, int y, int element)
942 DrawLevelElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
945 void ErdreichAnbroeckeln(int x, int y)
947 int i, width, height, cx,cy;
948 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
949 int element, graphic;
951 static int xy[4][2] =
959 if (!IN_LEV_FIELD(ux,uy))
962 element = Feld[ux][uy];
964 if (element==EL_ERDREICH)
966 if (!IN_SCR_FIELD(x,y))
969 graphic = GFX_ERDENRAND;
977 if (!IN_LEV_FIELD(uxx,uyy))
980 element = Feld[uxx][uyy];
982 if (element==EL_ERDREICH)
989 cx = (i==2 ? TILEX-snip : 0);
997 cy = (i==3 ? TILEY-snip : 0);
1000 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1001 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1002 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1003 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1010 graphic = GFX_ERDENRAND;
1021 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1022 !IN_SCR_FIELD(xx,yy))
1029 cx = (i==1 ? TILEX-snip : 0);
1037 cy = (i==0 ? TILEY-snip : 0);
1040 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1041 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1042 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1043 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1045 MarkTileDirty(xx,yy);
1050 void DrawScreenElement(int x, int y, int element)
1052 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, NO_MASKING);
1053 ErdreichAnbroeckeln(x,y);
1056 void DrawLevelElement(int x, int y, int element)
1058 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1059 DrawScreenElement(SCROLLX(x),SCROLLY(y),element);
1062 void DrawScreenField(int x, int y)
1064 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
1067 if (!IN_LEV_FIELD(ux,uy))
1069 DrawScreenElement(x,y,EL_BETON);
1073 element = Feld[ux][uy];
1075 if (IS_MOVING(ux,uy))
1077 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1078 BOOL cut_mode = NO_CUTTING;
1080 if (Store[ux][uy]==EL_MORAST_LEER ||
1081 Store[ux][uy]==EL_SIEB_LEER ||
1082 Store[ux][uy]==EL_SIEB2_LEER ||
1083 Store[ux][uy]==EL_AMOEBE_NASS)
1084 cut_mode = CUT_ABOVE;
1085 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1088 Store[ux][uy]==EL_SALZSAEURE ||
1091 Store[ux][uy]==EL_SIEB_VOLL ||
1092 Store[ux][uy]==EL_SIEB2_VOLL)
1093 cut_mode = CUT_BELOW;
1095 if (cut_mode==CUT_ABOVE)
1096 DrawScreenElementShifted(x,y, 0,0, Store[ux][uy], NO_CUTTING);
1098 DrawScreenElement(x,y,EL_LEERRAUM);
1101 DrawScreenElementShifted(x,y, MovPos[ux][uy],0, element, NO_CUTTING);
1103 DrawScreenElementShifted(x,y, 0,MovPos[ux][uy], element, cut_mode);
1106 if (Store[ux][uy] == EL_SALZSAEURE)
1107 DrawLevelElementThruMask(ux,uy+1, EL_SALZSAEURE);
1111 else if (IS_BLOCKED(ux,uy))
1116 BOOL cut_mode = NO_CUTTING;
1118 Blocked2Moving(ux,uy,&oldx,&oldy);
1121 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1123 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1124 Store[oldx][oldy]==EL_SIEB_LEER ||
1125 Store[oldx][oldy]==EL_SIEB2_LEER ||
1126 Store[oldx][oldy]==EL_AMOEBE_NASS)
1127 cut_mode = CUT_ABOVE;
1129 DrawScreenElement(x,y,EL_LEERRAUM);
1130 element = Feld[oldx][oldy];
1133 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1135 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1137 else if (IS_DRAWABLE(element))
1138 DrawScreenElement(x,y,element);
1140 DrawScreenElement(x,y,EL_LEERRAUM);
1143 void DrawLevelField(int x, int y)
1145 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1146 DrawScreenField(SCROLLX(x),SCROLLY(y));
1147 else if (IS_MOVING(x,y))
1151 Moving2Blocked(x,y,&newx,&newy);
1152 if (IN_SCR_FIELD(SCROLLX(newx),SCROLLY(newy)))
1153 DrawScreenField(SCROLLX(newx),SCROLLY(newy));
1155 else if (IS_BLOCKED(x,y))
1159 Blocked2Moving(x,y,&oldx,&oldy);
1160 if (IN_SCR_FIELD(SCROLLX(oldx),SCROLLY(oldy)))
1161 DrawScreenField(SCROLLX(oldx),SCROLLY(oldy));
1165 void DrawMiniElement(int x, int y, int element)
1171 DrawMiniGraphic(x,y,-1);
1175 graphic = el2gfx(element);
1176 DrawMiniGraphic(x,y,graphic);
1179 void DrawMiniElementOrWall(int x, int y, int scroll_x, int scroll_y)
1181 if (x+scroll_x<-1 || x+scroll_x>lev_fieldx ||
1182 y+scroll_y<-1 || y+scroll_y>lev_fieldy)
1183 DrawMiniElement(x,y,EL_LEERRAUM);
1184 else if (x+scroll_x==-1 || x+scroll_x==lev_fieldx ||
1185 y+scroll_y==-1 || y+scroll_y==lev_fieldy)
1186 DrawMiniElement(x,y,EL_BETON);
1188 DrawMiniElement(x,y,Feld[x+scroll_x][y+scroll_y]);
1191 void DrawMicroElement(int xpos, int ypos, int element)
1195 if (element==EL_LEERRAUM)
1198 graphic = el2gfx(element);
1200 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1201 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1202 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1203 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1212 for(x=BX1; x<=BX2; x++)
1213 for(y=BY1; y<=BY2; y++)
1214 DrawScreenField(x,y);
1216 if (soft_scrolling_on)
1217 XCopyArea(display,fieldbuffer,backbuffer,gc,
1218 FX,FY, SXSIZE,SYSIZE,
1221 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1224 void DrawMiniLevel(int scroll_x, int scroll_y)
1230 for(x=0;x<2*SCR_FIELDX;x++)
1231 for(y=0;y<2*SCR_FIELDY;y++)
1232 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1234 redraw_mask |= REDRAW_FIELD;
1237 void DrawMicroLevel(int xpos, int ypos)
1241 XFillRectangle(display,drawto,gc,
1242 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1243 MICRO_TILEX*(STD_LEV_FIELDX+2),
1244 MICRO_TILEY*(STD_LEV_FIELDY+2));
1245 if (lev_fieldx < STD_LEV_FIELDX)
1246 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1247 if (lev_fieldy < STD_LEV_FIELDY)
1248 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1250 for(x=-1;x<=STD_LEV_FIELDX;x++)
1251 for(y=-1;y<=STD_LEV_FIELDY;y++)
1252 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1253 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1254 Feld[x][y]=Ur[x][y]);
1255 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1256 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1259 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1263 int len = strlen(level.name);
1264 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1265 int lypos = MICROLABEL_YPOS;
1267 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1270 redraw_mask |= REDRAW_MICROLEV;
1273 int AYS_in_range(int x, int y)
1275 if (y>DY+249 && y<DY+278)
1277 if (x>DX+1 && x<DX+48)
1279 else if (x>DX+51 && x<DX+98)
1285 BOOL AreYouSure(char *text, unsigned int ays_state)
1287 int mx,my, ty, result = -1;
1288 unsigned int old_door_state;
1290 old_door_state = GetDoorState();
1292 CloseDoor(DOOR_CLOSE_1);
1294 /* Alten Türinhalt sichern */
1295 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1296 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1297 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1299 /* Fragetext schreiben */
1300 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1301 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1303 for(ty=0;ty<13;ty++)
1310 for(tl=0,tx=0;tx<7;tl++,tx++)
1324 DrawTextExt(pix[PIX_DB_DOOR],gc,
1325 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1326 text+=(tl+(tc==32));
1329 if (ays_state & AYS_ASK)
1330 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1331 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1332 DXSIZE,OK_BUTTON_YSIZE,
1333 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1334 else if (ays_state & AYS_CONFIRM)
1335 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1336 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1337 DXSIZE,CONFIRM_BUTTON_YSIZE,
1338 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1340 OpenDoor(DOOR_OPEN_1);
1343 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1346 if (game_status != MAINMENU)
1349 button_status = MB_RELEASED;
1356 if (XPending(display))
1360 XNextEvent(display, &event);
1364 HandleExposeEvent((XExposeEvent *) &event);
1367 SleepWhileUnmapped();
1375 if (event.type == MotionNotify)
1377 motion_status = TRUE;
1378 mx = ((XMotionEvent *) &event)->x;
1379 my = ((XMotionEvent *) &event)->y;
1383 motion_status = FALSE;
1384 mx = ((XButtonEvent *) &event)->x;
1385 my = ((XButtonEvent *) &event)->y;
1386 if (event.type==ButtonPress)
1387 button_status = ((XButtonEvent *) &event)->button;
1389 button_status = MB_RELEASED;
1392 if (ays_state & AYS_ASK)
1393 choice = CheckChooseButtons(mx,my,button_status);
1395 choice = CheckConfirmButton(mx,my,button_status);
1405 case BUTTON_CONFIRM:
1406 result = TRUE|FALSE;
1414 switch(XLookupKeysym((XKeyEvent *)&event,
1415 ((XKeyEvent *)&event)->state))
1426 key_joystick_mapping = 0;
1430 HandleFocusEvent((XFocusChangeEvent *) &event);
1433 HandleClientMessageEvent((XClientMessageEvent *) &event);
1439 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1443 if (joy & JOY_BUTTON_1)
1445 else if (joy & JOY_BUTTON_2)
1450 if (game_status != MAINMENU)
1453 if (!(ays_state & AYS_STAY_OPEN))
1455 CloseDoor(DOOR_CLOSE_1);
1457 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1459 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1460 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1461 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1462 OpenDoor(DOOR_OPEN_1);
1469 unsigned int OpenDoor(unsigned int door_state)
1471 unsigned int new_door_state;
1473 if (door_state & DOOR_COPY_BACK)
1475 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1476 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1477 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1478 door_state &= ~DOOR_COPY_BACK;
1481 new_door_state = MoveDoor(door_state);
1483 return(new_door_state);
1486 unsigned int CloseDoor(unsigned int door_state)
1488 unsigned int new_door_state;
1490 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1491 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1492 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1493 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1495 new_door_state = MoveDoor(door_state);
1497 return(new_door_state);
1500 unsigned int GetDoorState()
1502 return(MoveDoor(DOOR_GET_STATE));
1505 unsigned int MoveDoor(unsigned int door_state)
1507 static unsigned int door1 = DOOR_OPEN_1;
1508 static unsigned int door2 = DOOR_CLOSE_2;
1509 static long door_delay = 0;
1510 int x, start, stepsize = 2;
1511 long door_delay_value = stepsize * 5;
1513 if (door_state == DOOR_GET_STATE)
1514 return(door1 | door2);
1516 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1517 door_state &= ~DOOR_OPEN_1;
1518 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1519 door_state &= ~DOOR_CLOSE_1;
1520 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1521 door_state &= ~DOOR_OPEN_2;
1522 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1523 door_state &= ~DOOR_CLOSE_2;
1528 door_delay_value = 0;
1529 StopSound(SND_OEFFNEN);
1532 if (door_state & DOOR_ACTION)
1534 if (!(door_state & DOOR_NO_DELAY))
1535 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1537 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1539 for(x=start; x<=DXSIZE; x+=stepsize)
1541 WaitUntilDelayReached(&door_delay, door_delay_value);
1543 if (door_state & DOOR_ACTION_1)
1545 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1546 int j = (DXSIZE - i)/3;
1548 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1549 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1550 DXSIZE,DYSIZE-i/2, DX,DY);
1552 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1554 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1555 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1556 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1557 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1558 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1559 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1560 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1561 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1562 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1563 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1564 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1565 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1567 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1568 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1570 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1571 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1573 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1574 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1575 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1576 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1577 DX+DXSIZE-i,DY+77+j);
1578 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1579 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1580 DX+DXSIZE-i,DY+203+j);
1582 redraw_mask |= REDRAW_DOOR_1;
1585 if (door_state & DOOR_ACTION_2)
1587 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1588 int j = (VXSIZE - i)/3;
1590 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1591 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1592 VXSIZE,VYSIZE-i/2, VX,VY);
1594 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1596 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1597 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1598 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1599 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1600 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1601 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1602 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1603 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1605 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1606 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1608 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1609 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1610 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1611 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1612 VX+VXSIZE-i,VY+VYSIZE/2+j);
1614 redraw_mask |= REDRAW_DOOR_2;
1619 if (game_status == MAINMENU)
1624 if (door_state & DOOR_ACTION_1)
1625 door1 = door_state & DOOR_ACTION_1;
1626 if (door_state & DOOR_ACTION_2)
1627 door2 = door_state & DOOR_ACTION_2;
1629 return(door1 | door2);
1632 int ReadPixel(Drawable d, int x, int y)
1634 static XImage *pixelimage;
1636 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1637 return(XGetPixel(pixelimage,0,0));
1640 int el2gfx(int element)
1644 case EL_LEERRAUM: return(-1);
1645 case EL_ERDREICH: return(GFX_ERDREICH);
1646 case EL_MAUERWERK: return(GFX_MAUERWERK);
1647 case EL_FELSBODEN: return(GFX_FELSBODEN);
1648 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1649 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1650 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1651 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1652 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1653 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1654 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1655 case EL_SPIELER1: return(GFX_SPIELER1);
1656 case EL_SPIELER2: return(GFX_SPIELER2);
1657 case EL_SPIELER3: return(GFX_SPIELER3);
1658 case EL_SPIELER4: return(GFX_SPIELER4);
1659 case EL_KAEFER: return(GFX_KAEFER);
1660 case EL_KAEFER_R: return(GFX_KAEFER_R);
1661 case EL_KAEFER_O: return(GFX_KAEFER_O);
1662 case EL_KAEFER_L: return(GFX_KAEFER_L);
1663 case EL_KAEFER_U: return(GFX_KAEFER_U);
1664 case EL_FLIEGER: return(GFX_FLIEGER);
1665 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1666 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1667 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1668 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1669 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1670 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1671 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1672 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1673 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1674 case EL_FIREFLY: return(GFX_FIREFLY);
1675 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1676 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1677 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1678 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1679 case EL_MAMPFER: return(GFX_MAMPFER);
1680 case EL_ROBOT: return(GFX_ROBOT);
1681 case EL_BETON: return(GFX_BETON);
1682 case EL_DIAMANT: return(GFX_DIAMANT);
1683 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1684 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1685 case EL_TROPFEN: return(GFX_TROPFEN);
1686 case EL_BOMBE: return(GFX_BOMBE);
1687 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1688 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1689 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1690 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1691 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1692 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1693 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1694 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1695 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1696 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1697 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1698 case EL_LIFE: return(GFX_LIFE);
1699 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1700 case EL_DYNAMIT: return(GFX_DYNAMIT);
1701 case EL_BADEWANNE: return(GFX_BADEWANNE);
1702 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1703 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1704 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1705 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1706 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1707 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1708 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1709 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1710 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1711 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1712 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1713 case EL_PFORTE1: return(GFX_PFORTE1);
1714 case EL_PFORTE2: return(GFX_PFORTE2);
1715 case EL_PFORTE3: return(GFX_PFORTE3);
1716 case EL_PFORTE4: return(GFX_PFORTE4);
1717 case EL_PFORTE1X: return(GFX_PFORTE1X);
1718 case EL_PFORTE2X: return(GFX_PFORTE2X);
1719 case EL_PFORTE3X: return(GFX_PFORTE3X);
1720 case EL_PFORTE4X: return(GFX_PFORTE4X);
1721 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1722 case EL_PACMAN: return(GFX_PACMAN);
1723 case EL_PACMAN_R: return(GFX_PACMAN_R);
1724 case EL_PACMAN_O: return(GFX_PACMAN_O);
1725 case EL_PACMAN_L: return(GFX_PACMAN_L);
1726 case EL_PACMAN_U: return(GFX_PACMAN_U);
1727 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1728 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1729 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1730 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1731 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1732 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1733 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1734 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1735 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1736 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1737 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1738 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1739 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1740 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1741 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1742 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1743 case EL_MAMPFER2: return(GFX_MAMPFER2);
1744 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1745 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1746 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1747 case EL_DYNABOMB: return(GFX_DYNABOMB);
1748 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1749 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1750 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1751 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1752 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1753 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1754 case EL_MAULWURF: return(GFX_MAULWURF);
1755 case EL_PINGUIN: return(GFX_PINGUIN);
1756 case EL_SCHWEIN: return(GFX_SCHWEIN);
1757 case EL_DRACHE: return(GFX_DRACHE);
1758 case EL_SONDE: return(GFX_SONDE);
1759 case EL_PFEIL_L: return(GFX_PFEIL_L);
1760 case EL_PFEIL_R: return(GFX_PFEIL_R);
1761 case EL_PFEIL_O: return(GFX_PFEIL_O);
1762 case EL_PFEIL_U: return(GFX_PFEIL_U);
1765 if (IS_CHAR(element))
1766 return(GFX_CHAR_START + (element-EL_CHAR_START));