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 += (local_player->MovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0);
113 fy += (local_player->MovDir & (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(int x, int y)
335 int lastJX = player->lastJX, lastJY = player->lastJY;
336 int sx = SCROLLX(x), sy = SCROLLY(y);
337 int sxx = 0, syy = 0;
338 int element = Feld[x][y];
348 if (!IN_LEV_FIELD(x,y) || !IN_SCR_FIELD(sx,sy))
350 printf("DrawPlayerField(): x = %d, y = %d\n",x,y);
351 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
352 printf("DrawPlayerField(): This should never happen!\n");
357 if (element == EL_EXPLODING)
361 SetDrawtoField(DRAW_BUFFERED);
363 /* draw things in the field the player is leaving, if needed */
365 if (lastJX != JX || lastJY != JY)
367 if (Store[lastJX][lastJY])
369 DrawLevelElement(lastJX,lastJY, Store[lastJX][lastJY]);
370 DrawLevelElementThruMask(lastJX,lastJY, Feld[lastJX][lastJY]);
372 else if (Feld[lastJX][lastJY] == EL_DYNAMIT)
373 DrawDynamite(lastJX,lastJY);
375 DrawLevelField(lastJX,lastJY);
379 int nextJX = JX + (JX - lastJX);
380 int nextJY = JY + (JY - lastJY);
384 if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
385 DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER);
387 DrawLevelElement(nextJX,nextJY, EL_LEERRAUM);
390 DrawLevelField(nextJX,nextJY);
394 /* draw things behind the player, if needed */
397 DrawLevelElement(x,y, Store[x][y]);
398 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
401 /* draw player himself */
403 if (player->MovDir==MV_LEFT)
404 graphic = (player->Pushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT);
405 else if (player->MovDir==MV_RIGHT)
406 graphic = (player->Pushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT);
407 else if (player->MovDir==MV_UP)
408 graphic = GFX_SPIELER_UP;
409 else /* MV_DOWN || MV_NO_MOVING */
410 graphic = GFX_SPIELER_DOWN;
412 graphic += player->Frame;
416 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
417 sxx = player->GfxPos;
419 syy = player->GfxPos;
422 if (!soft_scrolling_on && ScreenMovPos)
425 DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING);
427 if (player->Pushing && player->GfxPos)
429 int nextJX = JX + (JX - lastJX);
430 int nextJY = JY + (JY - lastJY);
431 int px = SCROLLX(nextJX), py = SCROLLY(nextJY);
433 if (Feld[JX][JY] == EL_SOKOBAN_FELD_LEER ||
434 Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
435 DrawGraphicShiftedThruMask(px,py,sxx,syy, GFX_SOKOBAN_OBJEKT,NO_CUTTING);
438 int element = Feld[nextJX][nextJY];
439 int graphic = el2gfx(element);
441 if (element == EL_FELSBROCKEN && sxx)
443 int phase = (player->GfxPos / (TILEX/4));
445 if (player->MovDir == MV_LEFT)
448 graphic += (phase+4)%4;
451 DrawGraphicShifted(px,py, sxx,syy, graphic, NO_CUTTING, NO_MASKING);
455 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
457 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
459 graphic = el2gfx(element);
461 if (element == EL_DYNAMIT)
463 if ((phase = (96-MovDelay[x][y])/12) > 6)
468 if ((phase = ((96-MovDelay[x][y])/6) % 8) > 3)
472 DrawGraphicThruMask(sx,sy, graphic + phase);
477 int dest_x = SX+SCROLLX(x)*TILEX;
478 int dest_y = SY+SCROLLY(y)*TILEY;
484 dest_x = SX + SCROLLX(MIN(JX,lastJX))*TILEX;
485 dest_y = SY + SCROLLY(MIN(JY,lastJY))*TILEY;
486 x_size = TILEX * (1 + ABS(JX - lastJX));
487 y_size = TILEY * (1 + ABS(JY - lastJY));
490 XCopyArea(display,drawto_field,window,gc,
491 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
492 SetDrawtoField(DRAW_DIRECT);
495 MarkTileDirty(sx,sy);
498 static int getGraphicAnimationPhase(int frames, int delay, int mode)
502 if (mode == ANIM_OSCILLATE)
504 int max_anim_frames = frames*2 - 2;
505 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
506 phase = (phase < frames ? phase : max_anim_frames - phase);
509 phase = (FrameCounter % (delay * frames)) / delay;
511 if (mode == ANIM_REVERSE)
517 void DrawGraphicAnimationExt(int x, int y, int graphic,
518 int frames, int delay, int mode, int mask_mode)
520 int phase = getGraphicAnimationPhase(frames, delay, mode);
522 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
524 if (mask_mode == USE_MASKING)
525 DrawGraphicThruMask(SCROLLX(x),SCROLLY(y), graphic + phase);
527 DrawGraphic(SCROLLX(x),SCROLLY(y), graphic + phase);
531 void DrawGraphicAnimation(int x, int y, int graphic,
532 int frames, int delay, int mode)
534 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, NO_MASKING);
537 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
538 int frames, int delay, int mode)
540 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, USE_MASKING);
543 void DrawGraphic(int x, int y, int graphic)
547 if (!IN_SCR_FIELD(x,y))
549 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
550 printf("DrawGraphic(): This should never happen!\n");
555 DrawGraphicExt(drawto_field, gc, FX+x*TILEX, FY+y*TILEY, graphic);
559 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
561 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
563 graphic -= GFX_START_ROCKSSCREEN;
564 XCopyArea(display,pix[PIX_BACK],d,gc,
565 SX + (graphic % GFX_PER_LINE) * TILEX,
566 SY + (graphic / GFX_PER_LINE) * TILEY,
569 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
571 graphic -= GFX_START_ROCKSHEROES;
572 XCopyArea(display,pix[PIX_HEROES],d,gc,
573 (graphic % HEROES_PER_LINE) * TILEX,
574 (graphic / HEROES_PER_LINE) * TILEY,
577 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
579 graphic -= GFX_START_ROCKSFONT;
580 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
581 (graphic % FONT_CHARS_PER_LINE) * TILEX,
582 (graphic / FONT_CHARS_PER_LINE) * TILEY +
583 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
587 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
590 void DrawGraphicThruMask(int x, int y, int graphic)
592 int src_x,src_y, dest_x,dest_y;
598 if (!IN_SCR_FIELD(x,y))
600 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
601 printf("DrawGraphicThruMask(): This should never happen!\n");
606 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
608 src_pixmap = pix[PIX_BACK];
609 drawing_gc = clip_gc[PIX_BACK];
610 graphic -= GFX_START_ROCKSSCREEN;
611 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
612 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
614 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
616 src_pixmap = pix[PIX_HEROES];
617 drawing_gc = clip_gc[PIX_HEROES];
618 graphic -= GFX_START_ROCKSHEROES;
619 src_x = (graphic % HEROES_PER_LINE)*TILEX;
620 src_y = (graphic / HEROES_PER_LINE)*TILEY;
624 DrawGraphic(x,y,graphic);
628 dest_x = FX + x*TILEX;
629 dest_y = FY + y*TILEY;
631 if (tile_clipmask[tile] != None)
633 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
634 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
635 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
636 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
641 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
644 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
645 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
646 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
652 void DrawMiniGraphic(int x, int y, int graphic)
654 DrawMiniGraphicExt(drawto,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
655 MarkTileDirty(x/2, y/2);
658 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
660 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
662 graphic -= GFX_START_ROCKSSCREEN;
663 XCopyArea(display,pix[PIX_BACK],d,gc,
664 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
665 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
666 MINI_TILEX,MINI_TILEY, x,y);
668 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
670 graphic -= GFX_START_ROCKSFONT;
671 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
672 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
673 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
674 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
675 MINI_TILEX,MINI_TILEY, x,y);
678 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
681 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
682 int cut_mode, int mask_mode)
684 int width = TILEX, height = TILEY;
686 int src_x,src_y, dest_x,dest_y;
693 DrawGraphic(x,y,graphic);
697 if (dx || dy) /* Verschiebung der Grafik? */
699 if (x < BX1) /* Element kommt von links ins Bild */
706 else if (x > BX2) /* Element kommt von rechts ins Bild */
712 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
718 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
720 else if (dx) /* allg. Bewegung in x-Richtung */
721 MarkTileDirty(x + SIGN(dx), y);
723 if (y < BY1) /* Element kommt von oben ins Bild */
725 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
733 else if (y > BY2) /* Element kommt von unten ins Bild */
739 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
745 else if (dy > 0 && cut_mode==CUT_ABOVE)
747 if (y == BY2) /* Element unterhalb des Bildes */
753 MarkTileDirty(x, y + 1);
754 } /* Element verläßt unten das Bild */
755 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
757 else if (dy) /* allg. Bewegung in y-Richtung */
758 MarkTileDirty(x, y + SIGN(dy));
761 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
763 src_pixmap = pix[PIX_BACK];
764 drawing_gc = clip_gc[PIX_BACK];
765 graphic -= GFX_START_ROCKSSCREEN;
766 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
767 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
769 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
771 src_pixmap = pix[PIX_HEROES];
772 drawing_gc = clip_gc[PIX_HEROES];
773 graphic -= GFX_START_ROCKSHEROES;
774 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
775 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
778 dest_x = FX + x*TILEX + dx;
779 dest_y = FY + y*TILEY + dy;
782 if (!IN_SCR_FIELD(x,y))
784 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
785 printf("DrawGraphicShifted(): This should never happen!\n");
790 if (mask_mode == USE_MASKING)
792 if (tile_clipmask[tile] != None)
794 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
795 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
796 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
797 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
802 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
805 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
806 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
807 src_x,src_y, width,height, dest_x,dest_y);
811 XCopyArea(display, src_pixmap, drawto_field, gc,
812 src_x,src_y, width,height, dest_x,dest_y);
817 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
820 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
823 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
824 int cut_mode, int mask_mode)
826 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
827 int graphic = el2gfx(element);
828 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
829 int phase = phase4 / 2;
830 int dir = MovDir[ux][uy];
832 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
838 else if (dir == MV_LEFT)
840 else if (dir == MV_DOWN)
843 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
844 element==EL_SCHWEIN || element==EL_DRACHE)
847 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
848 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
849 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
850 else if (dir==MV_RIGHT)
851 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
852 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
853 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
855 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
856 element==EL_PINGUIN ? GFX_PINGUIN_UP :
857 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
859 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
860 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
861 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
865 else if (element==EL_SONDE)
867 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
869 else if (element==EL_SALZSAEURE)
871 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
873 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
877 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
879 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
881 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
882 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
884 graphic += 3-(SiebAktiv%8)/2;
886 else if (IS_AMOEBOID(element))
888 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
889 graphic += (x+2*y) % 4;
891 else if (element==EL_MAUER_LEBT)
893 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
895 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
897 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
898 rechts_massiv = TRUE;
900 if (links_massiv && rechts_massiv)
901 graphic = GFX_MAUERWERK;
902 else if (links_massiv)
903 graphic = GFX_MAUER_R;
904 else if (rechts_massiv)
905 graphic = GFX_MAUER_L;
909 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, mask_mode);
910 else if (mask_mode == USE_MASKING)
911 DrawGraphicThruMask(x,y, graphic);
913 DrawGraphic(x,y, graphic);
916 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
917 int cut_mode, int mask_mode)
919 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
920 DrawScreenElementExt(SCROLLX(x),SCROLLY(y), dx,dy, element,
921 cut_mode, mask_mode);
924 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
927 DrawScreenElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
930 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
933 DrawLevelElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
936 void DrawScreenElementThruMask(int x, int y, int element)
938 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
941 void DrawLevelElementThruMask(int x, int y, int element)
943 DrawLevelElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
946 void ErdreichAnbroeckeln(int x, int y)
948 int i, width, height, cx,cy;
949 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
950 int element, graphic;
952 static int xy[4][2] =
960 if (!IN_LEV_FIELD(ux,uy))
963 element = Feld[ux][uy];
965 if (element==EL_ERDREICH)
967 if (!IN_SCR_FIELD(x,y))
970 graphic = GFX_ERDENRAND;
978 if (!IN_LEV_FIELD(uxx,uyy))
981 element = Feld[uxx][uyy];
983 if (element==EL_ERDREICH)
990 cx = (i==2 ? TILEX-snip : 0);
998 cy = (i==3 ? TILEY-snip : 0);
1001 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1002 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1003 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1004 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1011 graphic = GFX_ERDENRAND;
1022 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1023 !IN_SCR_FIELD(xx,yy))
1030 cx = (i==1 ? TILEX-snip : 0);
1038 cy = (i==0 ? TILEY-snip : 0);
1041 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1042 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1043 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1044 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1046 MarkTileDirty(xx,yy);
1051 void DrawScreenElement(int x, int y, int element)
1053 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, NO_MASKING);
1054 ErdreichAnbroeckeln(x,y);
1057 void DrawLevelElement(int x, int y, int element)
1059 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1060 DrawScreenElement(SCROLLX(x),SCROLLY(y),element);
1063 void DrawScreenField(int x, int y)
1065 int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
1068 if (!IN_LEV_FIELD(ux,uy))
1070 DrawScreenElement(x,y,EL_BETON);
1074 element = Feld[ux][uy];
1076 if (IS_MOVING(ux,uy))
1078 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1079 BOOL cut_mode = NO_CUTTING;
1081 if (Store[ux][uy]==EL_MORAST_LEER ||
1082 Store[ux][uy]==EL_SIEB_LEER ||
1083 Store[ux][uy]==EL_SIEB2_LEER ||
1084 Store[ux][uy]==EL_AMOEBE_NASS)
1085 cut_mode = CUT_ABOVE;
1086 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1089 Store[ux][uy]==EL_SALZSAEURE ||
1092 Store[ux][uy]==EL_SIEB_VOLL ||
1093 Store[ux][uy]==EL_SIEB2_VOLL)
1094 cut_mode = CUT_BELOW;
1096 if (cut_mode==CUT_ABOVE)
1097 DrawScreenElementShifted(x,y, 0,0, Store[ux][uy], NO_CUTTING);
1099 DrawScreenElement(x,y,EL_LEERRAUM);
1102 DrawScreenElementShifted(x,y, MovPos[ux][uy],0, element, NO_CUTTING);
1104 DrawScreenElementShifted(x,y, 0,MovPos[ux][uy], element, cut_mode);
1107 if (Store[ux][uy] == EL_SALZSAEURE)
1108 DrawLevelElementThruMask(ux,uy+1, EL_SALZSAEURE);
1112 else if (IS_BLOCKED(ux,uy))
1117 BOOL cut_mode = NO_CUTTING;
1119 Blocked2Moving(ux,uy,&oldx,&oldy);
1122 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1124 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1125 Store[oldx][oldy]==EL_SIEB_LEER ||
1126 Store[oldx][oldy]==EL_SIEB2_LEER ||
1127 Store[oldx][oldy]==EL_AMOEBE_NASS)
1128 cut_mode = CUT_ABOVE;
1130 DrawScreenElement(x,y,EL_LEERRAUM);
1131 element = Feld[oldx][oldy];
1134 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1136 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1138 else if (IS_DRAWABLE(element))
1139 DrawScreenElement(x,y,element);
1141 DrawScreenElement(x,y,EL_LEERRAUM);
1144 void DrawLevelField(int x, int y)
1146 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1147 DrawScreenField(SCROLLX(x),SCROLLY(y));
1148 else if (IS_MOVING(x,y))
1152 Moving2Blocked(x,y,&newx,&newy);
1153 if (IN_SCR_FIELD(SCROLLX(newx),SCROLLY(newy)))
1154 DrawScreenField(SCROLLX(newx),SCROLLY(newy));
1156 else if (IS_BLOCKED(x,y))
1160 Blocked2Moving(x,y,&oldx,&oldy);
1161 if (IN_SCR_FIELD(SCROLLX(oldx),SCROLLY(oldy)))
1162 DrawScreenField(SCROLLX(oldx),SCROLLY(oldy));
1166 void DrawMiniElement(int x, int y, int element)
1172 DrawMiniGraphic(x,y,-1);
1176 graphic = el2gfx(element);
1177 DrawMiniGraphic(x,y,graphic);
1180 void DrawMiniElementOrWall(int x, int y, int scroll_x, int scroll_y)
1182 if (x+scroll_x<-1 || x+scroll_x>lev_fieldx ||
1183 y+scroll_y<-1 || y+scroll_y>lev_fieldy)
1184 DrawMiniElement(x,y,EL_LEERRAUM);
1185 else if (x+scroll_x==-1 || x+scroll_x==lev_fieldx ||
1186 y+scroll_y==-1 || y+scroll_y==lev_fieldy)
1187 DrawMiniElement(x,y,EL_BETON);
1189 DrawMiniElement(x,y,Feld[x+scroll_x][y+scroll_y]);
1192 void DrawMicroElement(int xpos, int ypos, int element)
1196 if (element==EL_LEERRAUM)
1199 graphic = el2gfx(element);
1201 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1202 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1203 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1204 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1213 for(x=BX1; x<=BX2; x++)
1214 for(y=BY1; y<=BY2; y++)
1215 DrawScreenField(x,y);
1217 if (soft_scrolling_on)
1218 XCopyArea(display,fieldbuffer,backbuffer,gc,
1219 FX,FY, SXSIZE,SYSIZE,
1222 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1225 void DrawMiniLevel(int scroll_x, int scroll_y)
1231 for(x=0;x<2*SCR_FIELDX;x++)
1232 for(y=0;y<2*SCR_FIELDY;y++)
1233 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1235 redraw_mask |= REDRAW_FIELD;
1238 void DrawMicroLevel(int xpos, int ypos)
1242 XFillRectangle(display,drawto,gc,
1243 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1244 MICRO_TILEX*(STD_LEV_FIELDX+2),
1245 MICRO_TILEY*(STD_LEV_FIELDY+2));
1246 if (lev_fieldx < STD_LEV_FIELDX)
1247 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1248 if (lev_fieldy < STD_LEV_FIELDY)
1249 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1251 for(x=-1;x<=STD_LEV_FIELDX;x++)
1252 for(y=-1;y<=STD_LEV_FIELDY;y++)
1253 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1254 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1255 Feld[x][y]=Ur[x][y]);
1256 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1257 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1260 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1264 int len = strlen(level.name);
1265 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1266 int lypos = MICROLABEL_YPOS;
1268 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1271 redraw_mask |= REDRAW_MICROLEV;
1274 int AYS_in_range(int x, int y)
1276 if (y>DY+249 && y<DY+278)
1278 if (x>DX+1 && x<DX+48)
1280 else if (x>DX+51 && x<DX+98)
1286 BOOL AreYouSure(char *text, unsigned int ays_state)
1288 int mx,my, ty, result = -1;
1289 unsigned int old_door_state;
1291 old_door_state = GetDoorState();
1293 CloseDoor(DOOR_CLOSE_1);
1295 /* Alten Türinhalt sichern */
1296 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1297 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1298 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1300 /* Fragetext schreiben */
1301 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1302 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1304 for(ty=0;ty<13;ty++)
1311 for(tl=0,tx=0;tx<7;tl++,tx++)
1325 DrawTextExt(pix[PIX_DB_DOOR],gc,
1326 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1327 text+=(tl+(tc==32));
1330 if (ays_state & AYS_ASK)
1331 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1332 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1333 DXSIZE,OK_BUTTON_YSIZE,
1334 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1335 else if (ays_state & AYS_CONFIRM)
1336 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1337 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1338 DXSIZE,CONFIRM_BUTTON_YSIZE,
1339 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1341 OpenDoor(DOOR_OPEN_1);
1344 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1347 if (game_status != MAINMENU)
1350 button_status = MB_RELEASED;
1357 if (XPending(display))
1361 XNextEvent(display, &event);
1365 HandleExposeEvent((XExposeEvent *) &event);
1368 SleepWhileUnmapped();
1376 if (event.type == MotionNotify)
1378 motion_status = TRUE;
1379 mx = ((XMotionEvent *) &event)->x;
1380 my = ((XMotionEvent *) &event)->y;
1384 motion_status = FALSE;
1385 mx = ((XButtonEvent *) &event)->x;
1386 my = ((XButtonEvent *) &event)->y;
1387 if (event.type==ButtonPress)
1388 button_status = ((XButtonEvent *) &event)->button;
1390 button_status = MB_RELEASED;
1393 if (ays_state & AYS_ASK)
1394 choice = CheckChooseButtons(mx,my,button_status);
1396 choice = CheckConfirmButton(mx,my,button_status);
1406 case BUTTON_CONFIRM:
1407 result = TRUE|FALSE;
1415 switch(XLookupKeysym((XKeyEvent *)&event,
1416 ((XKeyEvent *)&event)->state))
1427 key_joystick_mapping = 0;
1431 HandleFocusEvent((XFocusChangeEvent *) &event);
1434 HandleClientMessageEvent((XClientMessageEvent *) &event);
1440 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1444 if (joy & JOY_BUTTON_1)
1446 else if (joy & JOY_BUTTON_2)
1451 if (game_status != MAINMENU)
1454 if (!(ays_state & AYS_STAY_OPEN))
1456 CloseDoor(DOOR_CLOSE_1);
1458 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1460 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1461 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1462 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1463 OpenDoor(DOOR_OPEN_1);
1470 unsigned int OpenDoor(unsigned int door_state)
1472 unsigned int new_door_state;
1474 if (door_state & DOOR_COPY_BACK)
1476 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1477 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1478 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1479 door_state &= ~DOOR_COPY_BACK;
1482 new_door_state = MoveDoor(door_state);
1484 return(new_door_state);
1487 unsigned int CloseDoor(unsigned int door_state)
1489 unsigned int new_door_state;
1491 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1492 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1493 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1494 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1496 new_door_state = MoveDoor(door_state);
1498 return(new_door_state);
1501 unsigned int GetDoorState()
1503 return(MoveDoor(DOOR_GET_STATE));
1506 unsigned int MoveDoor(unsigned int door_state)
1508 static unsigned int door1 = DOOR_OPEN_1;
1509 static unsigned int door2 = DOOR_CLOSE_2;
1510 static long door_delay = 0;
1511 int x, start, stepsize = 2;
1512 long door_delay_value = stepsize * 5;
1514 if (door_state == DOOR_GET_STATE)
1515 return(door1 | door2);
1517 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1518 door_state &= ~DOOR_OPEN_1;
1519 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1520 door_state &= ~DOOR_CLOSE_1;
1521 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1522 door_state &= ~DOOR_OPEN_2;
1523 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1524 door_state &= ~DOOR_CLOSE_2;
1529 door_delay_value = 0;
1530 StopSound(SND_OEFFNEN);
1533 if (door_state & DOOR_ACTION)
1535 if (!(door_state & DOOR_NO_DELAY))
1536 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1538 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1540 for(x=start; x<=DXSIZE; x+=stepsize)
1542 WaitUntilDelayReached(&door_delay, door_delay_value);
1544 if (door_state & DOOR_ACTION_1)
1546 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1547 int j = (DXSIZE - i)/3;
1549 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1550 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1551 DXSIZE,DYSIZE-i/2, DX,DY);
1553 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1555 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1556 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1557 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1558 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1559 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1560 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1561 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1562 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1563 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1564 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1565 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1566 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1568 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1569 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1571 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1572 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1574 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1575 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1576 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1577 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1578 DX+DXSIZE-i,DY+77+j);
1579 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1580 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1581 DX+DXSIZE-i,DY+203+j);
1583 redraw_mask |= REDRAW_DOOR_1;
1586 if (door_state & DOOR_ACTION_2)
1588 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1589 int j = (VXSIZE - i)/3;
1591 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1592 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1593 VXSIZE,VYSIZE-i/2, VX,VY);
1595 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1597 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1598 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1599 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1600 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1601 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1602 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1603 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1604 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1606 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1607 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1609 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1610 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1611 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1612 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1613 VX+VXSIZE-i,VY+VYSIZE/2+j);
1615 redraw_mask |= REDRAW_DOOR_2;
1620 if (game_status == MAINMENU)
1625 if (door_state & DOOR_ACTION_1)
1626 door1 = door_state & DOOR_ACTION_1;
1627 if (door_state & DOOR_ACTION_2)
1628 door2 = door_state & DOOR_ACTION_2;
1630 return(door1 | door2);
1633 int ReadPixel(Drawable d, int x, int y)
1635 static XImage *pixelimage;
1637 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1638 return(XGetPixel(pixelimage,0,0));
1641 int el2gfx(int element)
1645 case EL_LEERRAUM: return(-1);
1646 case EL_ERDREICH: return(GFX_ERDREICH);
1647 case EL_MAUERWERK: return(GFX_MAUERWERK);
1648 case EL_FELSBODEN: return(GFX_FELSBODEN);
1649 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1650 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1651 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1652 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1653 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1654 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1655 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1656 case EL_SPIELER1: return(GFX_SPIELER1);
1657 case EL_SPIELER2: return(GFX_SPIELER2);
1658 case EL_SPIELER3: return(GFX_SPIELER3);
1659 case EL_SPIELER4: return(GFX_SPIELER4);
1660 case EL_KAEFER: return(GFX_KAEFER);
1661 case EL_KAEFER_R: return(GFX_KAEFER_R);
1662 case EL_KAEFER_O: return(GFX_KAEFER_O);
1663 case EL_KAEFER_L: return(GFX_KAEFER_L);
1664 case EL_KAEFER_U: return(GFX_KAEFER_U);
1665 case EL_FLIEGER: return(GFX_FLIEGER);
1666 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1667 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1668 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1669 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1670 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1671 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1672 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1673 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1674 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1675 case EL_FIREFLY: return(GFX_FIREFLY);
1676 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1677 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1678 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1679 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1680 case EL_MAMPFER: return(GFX_MAMPFER);
1681 case EL_ROBOT: return(GFX_ROBOT);
1682 case EL_BETON: return(GFX_BETON);
1683 case EL_DIAMANT: return(GFX_DIAMANT);
1684 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1685 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1686 case EL_TROPFEN: return(GFX_TROPFEN);
1687 case EL_BOMBE: return(GFX_BOMBE);
1688 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1689 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1690 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1691 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1692 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1693 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1694 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1695 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1696 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1697 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1698 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1699 case EL_LIFE: return(GFX_LIFE);
1700 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1701 case EL_DYNAMIT: return(GFX_DYNAMIT);
1702 case EL_BADEWANNE: return(GFX_BADEWANNE);
1703 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1704 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1705 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1706 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1707 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1708 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1709 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1710 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1711 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1712 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1713 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1714 case EL_PFORTE1: return(GFX_PFORTE1);
1715 case EL_PFORTE2: return(GFX_PFORTE2);
1716 case EL_PFORTE3: return(GFX_PFORTE3);
1717 case EL_PFORTE4: return(GFX_PFORTE4);
1718 case EL_PFORTE1X: return(GFX_PFORTE1X);
1719 case EL_PFORTE2X: return(GFX_PFORTE2X);
1720 case EL_PFORTE3X: return(GFX_PFORTE3X);
1721 case EL_PFORTE4X: return(GFX_PFORTE4X);
1722 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1723 case EL_PACMAN: return(GFX_PACMAN);
1724 case EL_PACMAN_R: return(GFX_PACMAN_R);
1725 case EL_PACMAN_O: return(GFX_PACMAN_O);
1726 case EL_PACMAN_L: return(GFX_PACMAN_L);
1727 case EL_PACMAN_U: return(GFX_PACMAN_U);
1728 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1729 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1730 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1731 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1732 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1733 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1734 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1735 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1736 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1737 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1738 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1739 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1740 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1741 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1742 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1743 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1744 case EL_MAMPFER2: return(GFX_MAMPFER2);
1745 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1746 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1747 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1748 case EL_DYNABOMB: return(GFX_DYNABOMB);
1749 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1750 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1751 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1752 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1753 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1754 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1755 case EL_MAULWURF: return(GFX_MAULWURF);
1756 case EL_PINGUIN: return(GFX_PINGUIN);
1757 case EL_SCHWEIN: return(GFX_SCHWEIN);
1758 case EL_DRACHE: return(GFX_DRACHE);
1759 case EL_SONDE: return(GFX_SONDE);
1760 case EL_PFEIL_L: return(GFX_PFEIL_L);
1761 case EL_PFEIL_R: return(GFX_PFEIL_R);
1762 case EL_PFEIL_O: return(GFX_PFEIL_O);
1763 case EL_PFEIL_U: return(GFX_PFEIL_U);
1766 if (IS_CHAR(element))
1767 return(GFX_CHAR_START + (element-EL_CHAR_START));