1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
15 #include <machine/joystick.h>
30 extern BOOL wait_for_vsync;
33 void SetDrawtoField(int mode)
35 if (mode == DRAW_BUFFERED && soft_scrolling_on)
46 drawto_field = fieldbuffer;
48 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
59 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
66 Drawable buffer = (drawto_field != window ? drawto_field : backbuffer);
68 if (direct_draw_on && game_status == PLAYING)
69 redraw_mask &= ~REDRAW_MAIN;
71 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
72 redraw_mask |= REDRAW_FIELD;
74 if (redraw_mask & REDRAW_FIELD || ScreenGfxPos)
75 redraw_mask &= ~REDRAW_TILES;
80 /* synchronize X11 graphics at this point; if we would synchronize the
81 display immediately after the buffer switching (after the XFlush),
82 this could mean that we have to wait for the graphics to complete,
83 although we could go on doing calculations for the next frame */
88 wait_for_vsync = TRUE;
91 if (redraw_mask & REDRAW_ALL)
93 XCopyArea(display,backbuffer,window,gc,
94 0,0, WIN_XSIZE,WIN_YSIZE,
99 if (redraw_mask & REDRAW_FIELD)
101 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
102 XCopyArea(display,backbuffer,window,gc,
103 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
107 int fx = FX, fy = FY;
109 if (soft_scrolling_on)
111 fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
112 fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0);
115 XCopyArea(display,buffer,window,gc,
116 fx,fy, SXSIZE,SYSIZE,
119 redraw_mask &= ~REDRAW_MAIN;
122 if (redraw_mask & REDRAW_DOORS)
124 if (redraw_mask & REDRAW_DOOR_1)
125 XCopyArea(display,backbuffer,window,gc,
126 DX,DY, DXSIZE,DYSIZE,
128 if (redraw_mask & REDRAW_DOOR_2)
130 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
131 XCopyArea(display,backbuffer,window,gc,
132 VX,VY, VXSIZE,VYSIZE,
136 if (redraw_mask & REDRAW_VIDEO_1)
137 XCopyArea(display,backbuffer,window,gc,
138 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
139 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
140 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
141 if (redraw_mask & REDRAW_VIDEO_2)
142 XCopyArea(display,backbuffer,window,gc,
143 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
144 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
145 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
146 if (redraw_mask & REDRAW_VIDEO_3)
147 XCopyArea(display,backbuffer,window,gc,
148 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
149 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
150 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
153 redraw_mask &= ~REDRAW_DOORS;
156 if (redraw_mask & REDRAW_MICROLEV)
158 XCopyArea(display,backbuffer,window,gc,
159 MICROLEV_XPOS,MICROLEV_YPOS, MICROLEV_XSIZE,MICROLEV_YSIZE,
160 MICROLEV_XPOS,MICROLEV_YPOS);
161 XCopyArea(display,backbuffer,window,gc,
162 SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE,
164 redraw_mask &= ~REDRAW_MICROLEV;
167 if (redraw_mask & REDRAW_TILES)
169 for(x=0; x<SCR_FIELDX; x++)
170 for(y=0; y<SCR_FIELDY; y++)
171 if (redraw[redraw_x1 + x][redraw_y1 + y])
172 XCopyArea(display,buffer,window,gc,
173 FX+x*TILEX,FX+y*TILEY, TILEX,TILEY,
174 SX+x*TILEX,SY+y*TILEY);
179 for(x=0; x<MAX_BUF_XSIZE; x++)
180 for(y=0; y<MAX_BUF_YSIZE; y++)
189 long fading_delay = 300;
191 if (fading_on && (redraw_mask & REDRAW_FIELD))
198 XFillRectangle(display,window,gc,
199 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
202 for(i=0;i<2*FULL_SYSIZE;i++)
204 for(y=0;y<FULL_SYSIZE;y++)
206 XCopyArea(display,backbuffer,window,gc,
207 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
215 for(i=1;i<FULL_SYSIZE;i+=2)
216 XCopyArea(display,backbuffer,window,gc,
217 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
223 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
224 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
225 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
229 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
230 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
231 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
235 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
236 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
237 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
241 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
242 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
243 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
247 redraw_mask &= ~REDRAW_MAIN;
256 XFillRectangle(display,backbuffer,gc,
257 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
259 if (soft_scrolling_on && game_status==PLAYING)
261 XFillRectangle(display,fieldbuffer,gc,
263 SetDrawtoField(DRAW_BUFFERED);
266 SetDrawtoField(DRAW_BACKBUFFER);
268 if (direct_draw_on && game_status==PLAYING)
270 XFillRectangle(display,window,gc,
271 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
272 SetDrawtoField(DRAW_DIRECT);
275 redraw_mask |= REDRAW_FIELD;
278 void DrawText(int x, int y, char *text, int font, int col)
280 DrawTextExt(drawto, gc, x, y, text, font, col);
282 redraw_mask |= REDRAW_FIELD;
284 redraw_mask |= REDRAW_DOOR_1;
287 void DrawTextExt(Drawable d, GC gc, int x, int y,
288 char *text, int font, int font_color)
290 int font_width, font_height, font_start;
293 if (font!=FS_SMALL && font!=FS_BIG)
295 if (font_color<FC_RED || font_color>FC_SPECIAL2)
299 (font==FS_BIG ? FONT1_XSIZE :
300 font_color<FC_SPECIAL1 ? FONT2_XSIZE :
301 font_color<FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
303 (font==FS_BIG ? FONT1_XSIZE :
304 font_color<FC_SPECIAL2 ? FONT2_XSIZE: FONT4_XSIZE);
305 font_pixmap = (font==FS_BIG ? PIX_BIGFONT : PIX_SMALLFONT);
307 font_color*(font==FS_BIG ? FONT1_YSIZE : FONT2_YSIZE)*FONT_LINES_PER_FONT;
313 if (c>='a' && c<='z')
315 else if (c=='ä' || c=='Ä')
317 else if (c=='ö' || c=='Ö')
319 else if (c=='ü' || c=='Ü')
323 XCopyArea(display,pix[font_pixmap],d,gc,
324 ((c-32) % FONT_CHARS_PER_LINE)*font_width,
325 ((c-32) / FONT_CHARS_PER_LINE)*font_height + font_start,
326 font_width,font_height, x,y);
332 void DrawAllPlayers()
336 for(i=0; i<MAX_PLAYERS; i++)
337 if (stored_player[i].active)
338 DrawPlayer(&stored_player[i]);
341 void DrawPlayerField(int x, int y)
346 DrawPlayer(PLAYERINFO(x,y));
349 void DrawPlayer(struct PlayerInfo *player)
351 int jx = player->jx, jy = player->jy;
352 int last_jx = player->last_jx, last_jy = player->last_jy;
353 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
354 int sx = SCREENX(jx), sy = SCREENY(jy);
355 int sxx = 0, syy = 0;
356 int element = Feld[jx][jy];
359 if (!player->active || player->gone || !IN_SCR_FIELD(sx,sy))
363 if (!IN_LEV_FIELD(jx,jy) || !IN_SCR_FIELD(sx,sy))
365 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
366 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
367 printf("DrawPlayerField(): This should never happen!\n");
372 if (element == EL_EXPLODING)
376 SetDrawtoField(DRAW_BUFFERED);
378 /* draw things in the field the player is leaving, if needed */
380 if (last_jx != jx || last_jy != jy)
382 if (Store[last_jx][last_jy])
384 DrawLevelElement(last_jx,last_jy, Store[last_jx][last_jy]);
385 DrawLevelFieldThruMask(last_jx,last_jy);
387 else if (Feld[last_jx][last_jy] == EL_DYNAMIT)
388 DrawDynamite(last_jx,last_jy);
390 DrawLevelField(last_jx,last_jy);
396 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
397 DrawLevelElement(next_jx,next_jy, EL_SOKOBAN_FELD_LEER);
399 DrawLevelElement(next_jx,next_jy, EL_LEERRAUM);
402 DrawLevelField(next_jx,next_jy);
406 /* draw things behind the player, if needed */
409 DrawLevelElement(jx,jy, Store[jx][jy]);
410 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
411 DrawLevelField(jx,jy);
413 /* draw player himself */
415 if (player->MovDir==MV_LEFT)
416 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
417 else if (player->MovDir==MV_RIGHT)
418 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
419 else if (player->MovDir==MV_UP)
420 graphic = GFX_SPIELER1_UP;
421 else /* MV_DOWN || MV_NO_MOVING */
422 graphic = GFX_SPIELER1_DOWN;
424 graphic += player->nr * 3*HEROES_PER_LINE;
425 graphic += player->Frame;
429 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
430 sxx = player->GfxPos;
432 syy = player->GfxPos;
435 if (!soft_scrolling_on && ScreenMovPos)
438 DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING);
440 if (player->Pushing && player->GfxPos)
442 int px = SCREENX(next_jx), py = SCREENY(next_jy);
444 if (Feld[jx][jy] == EL_SOKOBAN_FELD_LEER ||
445 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
446 DrawGraphicShiftedThruMask(px,py,sxx,syy, GFX_SOKOBAN_OBJEKT,NO_CUTTING);
449 int element = Feld[next_jx][next_jy];
450 int graphic = el2gfx(element);
452 if (element == EL_FELSBROCKEN && sxx)
454 int phase = (player->GfxPos / (TILEX/4));
456 if (player->MovDir == MV_LEFT)
459 graphic += (phase+4)%4;
462 DrawGraphicShifted(px,py, sxx,syy, graphic, NO_CUTTING, NO_MASKING);
466 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
468 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
470 graphic = el2gfx(element);
472 if (element == EL_DYNAMIT)
474 if ((phase = (96-MovDelay[jx][jy])/12) > 6)
479 if ((phase = ((96-MovDelay[jx][jy])/6) % 8) > 3)
483 DrawGraphicThruMask(sx,sy, graphic + phase);
486 if ((last_jx != jx || last_jy != jy) && Feld[last_jx][last_jy]==EL_EXPLODING)
488 int phase = Frame[last_jx][last_jy];
492 DrawGraphicThruMask(SCREENX(last_jx),SCREENY(last_jy),
493 GFX_EXPLOSION + ((phase-1)/delay-1));
498 int dest_x = SX + SCREENX(MIN(jx,last_jx))*TILEX;
499 int dest_y = SY + SCREENY(MIN(jy,last_jy))*TILEY;
500 int x_size = TILEX * (1 + ABS(jx - last_jx));
501 int y_size = TILEY * (1 + ABS(jy - last_jy));
503 XCopyArea(display,drawto_field,window,gc,
504 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
505 SetDrawtoField(DRAW_DIRECT);
508 MarkTileDirty(sx,sy);
511 static int getGraphicAnimationPhase(int frames, int delay, int mode)
515 if (mode == ANIM_OSCILLATE)
517 int max_anim_frames = frames*2 - 2;
518 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
519 phase = (phase < frames ? phase : max_anim_frames - phase);
522 phase = (FrameCounter % (delay * frames)) / delay;
524 if (mode == ANIM_REVERSE)
530 void DrawGraphicAnimationExt(int x, int y, int graphic,
531 int frames, int delay, int mode, int mask_mode)
533 int phase = getGraphicAnimationPhase(frames, delay, mode);
535 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
537 if (mask_mode == USE_MASKING)
538 DrawGraphicThruMask(SCREENX(x),SCREENY(y), graphic + phase);
540 DrawGraphic(SCREENX(x),SCREENY(y), graphic + phase);
544 void DrawGraphicAnimation(int x, int y, int graphic,
545 int frames, int delay, int mode)
547 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, NO_MASKING);
550 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
551 int frames, int delay, int mode)
553 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, USE_MASKING);
556 void DrawGraphic(int x, int y, int graphic)
560 if (!IN_SCR_FIELD(x,y))
562 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
563 printf("DrawGraphic(): This should never happen!\n");
568 DrawGraphicExt(drawto_field, gc, FX+x*TILEX, FY+y*TILEY, graphic);
572 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
574 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
576 graphic -= GFX_START_ROCKSSCREEN;
577 XCopyArea(display,pix[PIX_BACK],d,gc,
578 SX + (graphic % GFX_PER_LINE) * TILEX,
579 SY + (graphic / GFX_PER_LINE) * TILEY,
582 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
584 graphic -= GFX_START_ROCKSHEROES;
585 XCopyArea(display,pix[PIX_HEROES],d,gc,
586 (graphic % HEROES_PER_LINE) * TILEX,
587 (graphic / HEROES_PER_LINE) * TILEY,
590 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
592 graphic -= GFX_START_ROCKSFONT;
593 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
594 (graphic % FONT_CHARS_PER_LINE) * TILEX,
595 (graphic / FONT_CHARS_PER_LINE) * TILEY +
596 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
600 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
603 void DrawGraphicThruMask(int x, int y, int graphic)
605 int src_x,src_y, dest_x,dest_y;
611 if (!IN_SCR_FIELD(x,y))
613 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
614 printf("DrawGraphicThruMask(): This should never happen!\n");
619 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
621 src_pixmap = pix[PIX_BACK];
622 drawing_gc = clip_gc[PIX_BACK];
623 graphic -= GFX_START_ROCKSSCREEN;
624 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
625 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
627 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
629 src_pixmap = pix[PIX_HEROES];
630 drawing_gc = clip_gc[PIX_HEROES];
631 graphic -= GFX_START_ROCKSHEROES;
632 src_x = (graphic % HEROES_PER_LINE)*TILEX;
633 src_y = (graphic / HEROES_PER_LINE)*TILEY;
637 DrawGraphic(x,y,graphic);
641 dest_x = FX + x*TILEX;
642 dest_y = FY + y*TILEY;
644 if (tile_clipmask[tile] != None)
646 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
647 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
648 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
649 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
654 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
657 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
658 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
659 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
665 void DrawMiniGraphic(int x, int y, int graphic)
667 DrawMiniGraphicExt(drawto,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
668 MarkTileDirty(x/2, y/2);
671 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
673 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
675 graphic -= GFX_START_ROCKSSCREEN;
676 XCopyArea(display,pix[PIX_BACK],d,gc,
677 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
678 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
679 MINI_TILEX,MINI_TILEY, x,y);
681 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
683 graphic -= GFX_START_ROCKSFONT;
684 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
685 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
686 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
687 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
688 MINI_TILEX,MINI_TILEY, x,y);
691 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
694 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
695 int cut_mode, int mask_mode)
697 int width = TILEX, height = TILEY;
699 int src_x,src_y, dest_x,dest_y;
706 DrawGraphic(x,y,graphic);
710 if (dx || dy) /* Verschiebung der Grafik? */
712 if (x < BX1) /* Element kommt von links ins Bild */
719 else if (x > BX2) /* Element kommt von rechts ins Bild */
725 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
731 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
733 else if (dx) /* allg. Bewegung in x-Richtung */
734 MarkTileDirty(x + SIGN(dx), y);
736 if (y < BY1) /* Element kommt von oben ins Bild */
738 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
746 else if (y > BY2) /* Element kommt von unten ins Bild */
752 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
758 else if (dy > 0 && cut_mode==CUT_ABOVE)
760 if (y == BY2) /* Element unterhalb des Bildes */
766 MarkTileDirty(x, y + 1);
767 } /* Element verläßt unten das Bild */
768 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
770 else if (dy) /* allg. Bewegung in y-Richtung */
771 MarkTileDirty(x, y + SIGN(dy));
774 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
776 src_pixmap = pix[PIX_BACK];
777 drawing_gc = clip_gc[PIX_BACK];
778 graphic -= GFX_START_ROCKSSCREEN;
779 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
780 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
782 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
784 src_pixmap = pix[PIX_HEROES];
785 drawing_gc = clip_gc[PIX_HEROES];
786 graphic -= GFX_START_ROCKSHEROES;
787 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
788 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
791 dest_x = FX + x*TILEX + dx;
792 dest_y = FY + y*TILEY + dy;
795 if (!IN_SCR_FIELD(x,y))
797 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
798 printf("DrawGraphicShifted(): This should never happen!\n");
803 if (mask_mode == USE_MASKING)
805 if (tile_clipmask[tile] != None)
807 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
808 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
809 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
810 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
815 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
818 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
819 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
820 src_x,src_y, width,height, dest_x,dest_y);
824 XCopyArea(display, src_pixmap, drawto_field, gc,
825 src_x,src_y, width,height, dest_x,dest_y);
830 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
833 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
836 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
837 int cut_mode, int mask_mode)
839 int ux = LEVELX(x), uy = LEVELY(y);
840 int graphic = el2gfx(element);
841 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
842 int phase = phase4 / 2;
843 int dir = MovDir[ux][uy];
845 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
851 else if (dir == MV_LEFT)
853 else if (dir == MV_DOWN)
856 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
857 element==EL_SCHWEIN || element==EL_DRACHE)
860 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
861 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
862 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
863 else if (dir==MV_RIGHT)
864 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
865 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
866 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
868 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
869 element==EL_PINGUIN ? GFX_PINGUIN_UP :
870 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
872 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
873 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
874 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
878 else if (element==EL_SONDE)
880 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
882 else if (element==EL_SALZSAEURE)
884 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
886 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
890 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
892 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
894 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
895 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
897 graphic += 3-(SiebAktiv%8)/2;
899 else if (IS_AMOEBOID(element))
901 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
902 graphic += (x+2*y) % 4;
904 else if (element==EL_MAUER_LEBT)
906 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
908 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
910 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
911 rechts_massiv = TRUE;
913 if (links_massiv && rechts_massiv)
914 graphic = GFX_MAUERWERK;
915 else if (links_massiv)
916 graphic = GFX_MAUER_R;
917 else if (rechts_massiv)
918 graphic = GFX_MAUER_L;
922 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, mask_mode);
923 else if (mask_mode == USE_MASKING)
924 DrawGraphicThruMask(x,y, graphic);
926 DrawGraphic(x,y, graphic);
929 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
930 int cut_mode, int mask_mode)
932 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
933 DrawScreenElementExt(SCREENX(x),SCREENY(y), dx,dy, element,
934 cut_mode, mask_mode);
937 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
940 DrawScreenElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
943 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
946 DrawLevelElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
949 void DrawScreenElementThruMask(int x, int y, int element)
951 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
954 void DrawLevelElementThruMask(int x, int y, int element)
956 DrawLevelElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
959 void DrawLevelFieldThruMask(int x, int y)
961 DrawLevelElementExt(x,y, 0,0, Feld[x][y], NO_CUTTING, USE_MASKING);
964 void ErdreichAnbroeckeln(int x, int y)
966 int i, width, height, cx,cy;
967 int ux = LEVELX(x), uy = LEVELY(y);
968 int element, graphic;
970 static int xy[4][2] =
978 if (!IN_LEV_FIELD(ux,uy))
981 element = Feld[ux][uy];
983 if (element==EL_ERDREICH)
985 if (!IN_SCR_FIELD(x,y))
988 graphic = GFX_ERDENRAND;
996 if (!IN_LEV_FIELD(uxx,uyy))
999 element = Feld[uxx][uyy];
1001 if (element==EL_ERDREICH)
1008 cx = (i==2 ? TILEX-snip : 0);
1016 cy = (i==3 ? TILEY-snip : 0);
1019 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1020 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1021 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1022 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1029 graphic = GFX_ERDENRAND;
1040 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1041 !IN_SCR_FIELD(xx,yy))
1048 cx = (i==1 ? TILEX-snip : 0);
1056 cy = (i==0 ? TILEY-snip : 0);
1059 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1060 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1061 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1062 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1064 MarkTileDirty(xx,yy);
1069 void DrawScreenElement(int x, int y, int element)
1071 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, NO_MASKING);
1072 ErdreichAnbroeckeln(x,y);
1075 void DrawLevelElement(int x, int y, int element)
1077 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1078 DrawScreenElement(SCREENX(x),SCREENY(y),element);
1081 void DrawScreenField(int x, int y)
1083 int ux = LEVELX(x), uy = LEVELY(y);
1086 if (!IN_LEV_FIELD(ux,uy))
1088 DrawScreenElement(x,y,EL_BETON);
1092 element = Feld[ux][uy];
1094 if (IS_MOVING(ux,uy))
1096 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1097 BOOL cut_mode = NO_CUTTING;
1099 if (Store[ux][uy]==EL_MORAST_LEER ||
1100 Store[ux][uy]==EL_SIEB_LEER ||
1101 Store[ux][uy]==EL_SIEB2_LEER ||
1102 Store[ux][uy]==EL_AMOEBE_NASS)
1103 cut_mode = CUT_ABOVE;
1104 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1105 Store[ux][uy]==EL_SIEB_VOLL ||
1106 Store[ux][uy]==EL_SIEB2_VOLL)
1107 cut_mode = CUT_BELOW;
1109 if (cut_mode==CUT_ABOVE)
1110 DrawScreenElementShifted(x,y, 0,0, Store[ux][uy], NO_CUTTING);
1112 DrawScreenElement(x,y,EL_LEERRAUM);
1115 DrawScreenElementShifted(x,y, MovPos[ux][uy],0, element, NO_CUTTING);
1117 DrawScreenElementShifted(x,y, 0,MovPos[ux][uy], element, cut_mode);
1119 if (Store[ux][uy] == EL_SALZSAEURE)
1120 DrawLevelElementThruMask(ux,uy+1, EL_SALZSAEURE);
1122 else if (IS_BLOCKED(ux,uy))
1127 BOOL cut_mode = NO_CUTTING;
1129 Blocked2Moving(ux,uy,&oldx,&oldy);
1132 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1134 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1135 Store[oldx][oldy]==EL_SIEB_LEER ||
1136 Store[oldx][oldy]==EL_SIEB2_LEER ||
1137 Store[oldx][oldy]==EL_AMOEBE_NASS)
1138 cut_mode = CUT_ABOVE;
1140 DrawScreenElement(x,y,EL_LEERRAUM);
1141 element = Feld[oldx][oldy];
1144 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1146 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1148 else if (IS_DRAWABLE(element))
1149 DrawScreenElement(x,y,element);
1151 DrawScreenElement(x,y,EL_LEERRAUM);
1154 void DrawLevelField(int x, int y)
1156 if (IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1157 DrawScreenField(SCREENX(x),SCREENY(y));
1158 else if (IS_MOVING(x,y))
1162 Moving2Blocked(x,y,&newx,&newy);
1163 if (IN_SCR_FIELD(SCREENX(newx),SCREENY(newy)))
1164 DrawScreenField(SCREENX(newx),SCREENY(newy));
1166 else if (IS_BLOCKED(x,y))
1170 Blocked2Moving(x,y,&oldx,&oldy);
1171 if (IN_SCR_FIELD(SCREENX(oldx),SCREENY(oldy)))
1172 DrawScreenField(SCREENX(oldx),SCREENY(oldy));
1176 void DrawMiniElement(int x, int y, int element)
1182 DrawMiniGraphic(x,y,-1);
1186 graphic = el2gfx(element);
1187 DrawMiniGraphic(x,y,graphic);
1190 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1192 int x = sx + scroll_x, y = sy + scroll_y;
1194 if (x<-1 || x>lev_fieldx || y<-1 || y>lev_fieldy)
1195 DrawMiniElement(sx,sy,EL_LEERRAUM);
1196 else if (x==-1 || x==lev_fieldx || y==-1 || y==lev_fieldy)
1197 DrawMiniElement(sx,sy,EL_BETON);
1199 DrawMiniElement(sx,sy,Feld[x][y]);
1202 void DrawMicroElement(int xpos, int ypos, int element)
1206 if (element==EL_LEERRAUM)
1209 graphic = el2gfx(element);
1211 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1212 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1213 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1214 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1223 for(x=BX1; x<=BX2; x++)
1224 for(y=BY1; y<=BY2; y++)
1225 DrawScreenField(x,y);
1227 if (soft_scrolling_on)
1228 XCopyArea(display,fieldbuffer,backbuffer,gc,
1229 FX,FY, SXSIZE,SYSIZE,
1232 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1235 void DrawMiniLevel(int scroll_x, int scroll_y)
1241 for(x=0;x<2*SCR_FIELDX;x++)
1242 for(y=0;y<2*SCR_FIELDY;y++)
1243 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1245 redraw_mask |= REDRAW_FIELD;
1248 void DrawMicroLevel(int xpos, int ypos)
1252 XFillRectangle(display,drawto,gc,
1253 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1254 MICRO_TILEX*(STD_LEV_FIELDX+2),
1255 MICRO_TILEY*(STD_LEV_FIELDY+2));
1256 if (lev_fieldx < STD_LEV_FIELDX)
1257 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1258 if (lev_fieldy < STD_LEV_FIELDY)
1259 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1261 for(x=-1;x<=STD_LEV_FIELDX;x++)
1262 for(y=-1;y<=STD_LEV_FIELDY;y++)
1263 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1264 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1265 Feld[x][y]=Ur[x][y]);
1266 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1267 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1270 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1274 int len = strlen(level.name);
1275 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1276 int lypos = MICROLABEL_YPOS;
1278 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1281 redraw_mask |= REDRAW_MICROLEV;
1284 int AYS_in_range(int x, int y)
1286 if (y>DY+249 && y<DY+278)
1288 if (x>DX+1 && x<DX+48)
1290 else if (x>DX+51 && x<DX+98)
1296 BOOL AreYouSure(char *text, unsigned int ays_state)
1298 int mx,my, ty, result = -1;
1299 unsigned int old_door_state;
1301 old_door_state = GetDoorState();
1303 CloseDoor(DOOR_CLOSE_1);
1305 /* Alten Türinhalt sichern */
1306 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1307 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1308 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1310 /* Fragetext schreiben */
1311 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1312 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1314 for(ty=0;ty<13;ty++)
1321 for(tl=0,tx=0;tx<7;tl++,tx++)
1335 DrawTextExt(pix[PIX_DB_DOOR],gc,
1336 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1337 text+=(tl+(tc==32));
1340 if (ays_state & AYS_ASK)
1341 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1342 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1343 DXSIZE,OK_BUTTON_YSIZE,
1344 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1345 else if (ays_state & AYS_CONFIRM)
1346 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1347 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1348 DXSIZE,CONFIRM_BUTTON_YSIZE,
1349 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1351 OpenDoor(DOOR_OPEN_1);
1354 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1357 if (game_status != MAINMENU)
1360 button_status = MB_RELEASED;
1367 if (XPending(display))
1371 XNextEvent(display, &event);
1375 HandleExposeEvent((XExposeEvent *) &event);
1378 SleepWhileUnmapped();
1386 if (event.type == MotionNotify)
1388 motion_status = TRUE;
1389 mx = ((XMotionEvent *) &event)->x;
1390 my = ((XMotionEvent *) &event)->y;
1394 motion_status = FALSE;
1395 mx = ((XButtonEvent *) &event)->x;
1396 my = ((XButtonEvent *) &event)->y;
1397 if (event.type==ButtonPress)
1398 button_status = ((XButtonEvent *) &event)->button;
1400 button_status = MB_RELEASED;
1403 if (ays_state & AYS_ASK)
1404 choice = CheckChooseButtons(mx,my,button_status);
1406 choice = CheckConfirmButton(mx,my,button_status);
1416 case BUTTON_CONFIRM:
1417 result = TRUE|FALSE;
1425 switch(XLookupKeysym((XKeyEvent *)&event,
1426 ((XKeyEvent *)&event)->state))
1437 key_joystick_mapping = 0;
1441 HandleFocusEvent((XFocusChangeEvent *) &event);
1444 HandleClientMessageEvent((XClientMessageEvent *) &event);
1450 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1454 if (joy & JOY_BUTTON_1)
1456 else if (joy & JOY_BUTTON_2)
1461 if (game_status != MAINMENU)
1464 if (!(ays_state & AYS_STAY_OPEN))
1466 CloseDoor(DOOR_CLOSE_1);
1468 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1470 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1471 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1472 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1473 OpenDoor(DOOR_OPEN_1);
1480 unsigned int OpenDoor(unsigned int door_state)
1482 unsigned int new_door_state;
1484 if (door_state & DOOR_COPY_BACK)
1486 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1487 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1488 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1489 door_state &= ~DOOR_COPY_BACK;
1492 new_door_state = MoveDoor(door_state);
1494 return(new_door_state);
1497 unsigned int CloseDoor(unsigned int door_state)
1499 unsigned int new_door_state;
1501 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1502 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1503 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1504 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1506 new_door_state = MoveDoor(door_state);
1508 return(new_door_state);
1511 unsigned int GetDoorState()
1513 return(MoveDoor(DOOR_GET_STATE));
1516 unsigned int MoveDoor(unsigned int door_state)
1518 static unsigned int door1 = DOOR_OPEN_1;
1519 static unsigned int door2 = DOOR_CLOSE_2;
1520 static long door_delay = 0;
1521 int x, start, stepsize = 2;
1522 long door_delay_value = stepsize * 5;
1524 if (door_state == DOOR_GET_STATE)
1525 return(door1 | door2);
1527 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1528 door_state &= ~DOOR_OPEN_1;
1529 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1530 door_state &= ~DOOR_CLOSE_1;
1531 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1532 door_state &= ~DOOR_OPEN_2;
1533 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1534 door_state &= ~DOOR_CLOSE_2;
1539 door_delay_value = 0;
1540 StopSound(SND_OEFFNEN);
1543 if (door_state & DOOR_ACTION)
1545 if (!(door_state & DOOR_NO_DELAY))
1546 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1548 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1550 for(x=start; x<=DXSIZE; x+=stepsize)
1552 WaitUntilDelayReached(&door_delay, door_delay_value);
1554 if (door_state & DOOR_ACTION_1)
1556 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1557 int j = (DXSIZE - i)/3;
1559 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1560 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1561 DXSIZE,DYSIZE-i/2, DX,DY);
1563 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1565 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1566 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1567 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1568 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1569 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1570 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1571 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1572 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1573 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1574 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1575 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1576 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1578 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1579 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1581 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1582 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1584 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1585 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1586 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1587 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1588 DX+DXSIZE-i,DY+77+j);
1589 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1590 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1591 DX+DXSIZE-i,DY+203+j);
1593 redraw_mask |= REDRAW_DOOR_1;
1596 if (door_state & DOOR_ACTION_2)
1598 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1599 int j = (VXSIZE - i)/3;
1601 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1602 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1603 VXSIZE,VYSIZE-i/2, VX,VY);
1605 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1607 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1608 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1609 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1610 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1611 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1612 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1613 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1614 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1616 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1617 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1619 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1620 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1621 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1622 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1623 VX+VXSIZE-i,VY+VYSIZE/2+j);
1625 redraw_mask |= REDRAW_DOOR_2;
1630 if (game_status == MAINMENU)
1635 if (door_state & DOOR_ACTION_1)
1636 door1 = door_state & DOOR_ACTION_1;
1637 if (door_state & DOOR_ACTION_2)
1638 door2 = door_state & DOOR_ACTION_2;
1640 return(door1 | door2);
1643 int ReadPixel(Drawable d, int x, int y)
1645 static XImage *pixelimage;
1647 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1648 return(XGetPixel(pixelimage,0,0));
1651 int el2gfx(int element)
1655 case EL_LEERRAUM: return(-1);
1656 case EL_ERDREICH: return(GFX_ERDREICH);
1657 case EL_MAUERWERK: return(GFX_MAUERWERK);
1658 case EL_FELSBODEN: return(GFX_FELSBODEN);
1659 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1660 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1661 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1662 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1663 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1664 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1665 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1666 case EL_SPIELER1: return(GFX_SPIELER1);
1667 case EL_SPIELER2: return(GFX_SPIELER2);
1668 case EL_SPIELER3: return(GFX_SPIELER3);
1669 case EL_SPIELER4: return(GFX_SPIELER4);
1670 case EL_KAEFER: return(GFX_KAEFER);
1671 case EL_KAEFER_R: return(GFX_KAEFER_R);
1672 case EL_KAEFER_O: return(GFX_KAEFER_O);
1673 case EL_KAEFER_L: return(GFX_KAEFER_L);
1674 case EL_KAEFER_U: return(GFX_KAEFER_U);
1675 case EL_FLIEGER: return(GFX_FLIEGER);
1676 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1677 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1678 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1679 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1680 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1681 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1682 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1683 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1684 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1685 case EL_FIREFLY: return(GFX_FIREFLY);
1686 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1687 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1688 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1689 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1690 case EL_MAMPFER: return(GFX_MAMPFER);
1691 case EL_ROBOT: return(GFX_ROBOT);
1692 case EL_BETON: return(GFX_BETON);
1693 case EL_DIAMANT: return(GFX_DIAMANT);
1694 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1695 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1696 case EL_TROPFEN: return(GFX_TROPFEN);
1697 case EL_BOMBE: return(GFX_BOMBE);
1698 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1699 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1700 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1701 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1702 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1703 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1704 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1705 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1706 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1707 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1708 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1709 case EL_LIFE: return(GFX_LIFE);
1710 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1711 case EL_DYNAMIT: return(GFX_DYNAMIT);
1712 case EL_BADEWANNE: return(GFX_BADEWANNE);
1713 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1714 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1715 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1716 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1717 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1718 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1719 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1720 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1721 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1722 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1723 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1724 case EL_PFORTE1: return(GFX_PFORTE1);
1725 case EL_PFORTE2: return(GFX_PFORTE2);
1726 case EL_PFORTE3: return(GFX_PFORTE3);
1727 case EL_PFORTE4: return(GFX_PFORTE4);
1728 case EL_PFORTE1X: return(GFX_PFORTE1X);
1729 case EL_PFORTE2X: return(GFX_PFORTE2X);
1730 case EL_PFORTE3X: return(GFX_PFORTE3X);
1731 case EL_PFORTE4X: return(GFX_PFORTE4X);
1732 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1733 case EL_PACMAN: return(GFX_PACMAN);
1734 case EL_PACMAN_R: return(GFX_PACMAN_R);
1735 case EL_PACMAN_O: return(GFX_PACMAN_O);
1736 case EL_PACMAN_L: return(GFX_PACMAN_L);
1737 case EL_PACMAN_U: return(GFX_PACMAN_U);
1738 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1739 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1740 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1741 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1742 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1743 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1744 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1745 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1746 case EL_MAUER_X: return(GFX_MAUER_X);
1747 case EL_MAUER_Y: return(GFX_MAUER_Y);
1748 case EL_MAUER_XY: return(GFX_MAUER_XY);
1749 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1750 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1751 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1752 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1753 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1754 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1755 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1756 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1757 case EL_MAMPFER2: return(GFX_MAMPFER2);
1758 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1759 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1760 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1761 case EL_DYNABOMB: return(GFX_DYNABOMB);
1762 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1763 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1764 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1765 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1766 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1767 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1768 case EL_MAULWURF: return(GFX_MAULWURF);
1769 case EL_PINGUIN: return(GFX_PINGUIN);
1770 case EL_SCHWEIN: return(GFX_SCHWEIN);
1771 case EL_DRACHE: return(GFX_DRACHE);
1772 case EL_SONDE: return(GFX_SONDE);
1773 case EL_PFEIL_L: return(GFX_PFEIL_L);
1774 case EL_PFEIL_R: return(GFX_PFEIL_R);
1775 case EL_PFEIL_O: return(GFX_PFEIL_O);
1776 case EL_PFEIL_U: return(GFX_PFEIL_U);
1779 if (IS_CHAR(element))
1780 return(GFX_CHAR_START + (element-EL_CHAR_START));