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 DrawAllPlayers()
337 for(i=0; i<MAX_PLAYERS; i++)
338 if (stored_player[i].active)
339 DrawPlayer(&stored_player[i]);
342 void DrawPlayerField(int x, int y)
347 DrawPlayer(PLAYERINFO(x,y));
350 void DrawPlayer(struct PlayerInfo *player)
352 int jx = player->jx, jy = player->jy;
353 int last_jx = player->last_jx, last_jy = player->last_jy;
354 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
355 int sx = SCREENX(jx), sy = SCREENY(jy);
356 int sxx = 0, syy = 0;
357 int element = Feld[jx][jy];
360 if (!player->active || player->gone || !IN_SCR_FIELD(sx,sy))
364 if (!IN_LEV_FIELD(jx,jy) || !IN_SCR_FIELD(sx,sy))
366 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
367 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
368 printf("DrawPlayerField(): This should never happen!\n");
373 if (element == EL_EXPLODING)
377 SetDrawtoField(DRAW_BUFFERED);
379 /* draw things in the field the player is leaving, if needed */
381 if (last_jx != jx || last_jy != jy)
383 if (Store[last_jx][last_jy])
385 DrawLevelElement(last_jx,last_jy, Store[last_jx][last_jy]);
386 DrawLevelElementThruMask(last_jx,last_jy, Feld[last_jx][last_jy]);
388 else if (Feld[last_jx][last_jy] == EL_DYNAMIT)
389 DrawDynamite(last_jx,last_jy);
391 DrawLevelField(last_jx,last_jy);
397 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
398 DrawLevelElement(next_jx,next_jy, EL_SOKOBAN_FELD_LEER);
400 DrawLevelElement(next_jx,next_jy, EL_LEERRAUM);
403 DrawLevelField(next_jx,next_jy);
407 /* draw things behind the player, if needed */
410 DrawLevelElement(jx,jy, Store[jx][jy]);
411 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
412 DrawLevelField(jx,jy);
414 /* draw player himself */
416 if (player->MovDir==MV_LEFT)
417 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
418 else if (player->MovDir==MV_RIGHT)
419 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
420 else if (player->MovDir==MV_UP)
421 graphic = GFX_SPIELER1_UP;
422 else /* MV_DOWN || MV_NO_MOVING */
423 graphic = GFX_SPIELER1_DOWN;
425 graphic += player->nr * 3*HEROES_PER_LINE;
426 graphic += player->Frame;
430 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
431 sxx = player->GfxPos;
433 syy = player->GfxPos;
436 if (!soft_scrolling_on && ScreenMovPos)
439 DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING);
441 if (player->Pushing && player->GfxPos)
443 int px = SCREENX(next_jx), py = SCREENY(next_jy);
445 if (Feld[jx][jy] == EL_SOKOBAN_FELD_LEER ||
446 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
447 DrawGraphicShiftedThruMask(px,py,sxx,syy, GFX_SOKOBAN_OBJEKT,NO_CUTTING);
450 int element = Feld[next_jx][next_jy];
451 int graphic = el2gfx(element);
453 if (element == EL_FELSBROCKEN && sxx)
455 int phase = (player->GfxPos / (TILEX/4));
457 if (player->MovDir == MV_LEFT)
460 graphic += (phase+4)%4;
463 DrawGraphicShifted(px,py, sxx,syy, graphic, NO_CUTTING, NO_MASKING);
467 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
469 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
471 graphic = el2gfx(element);
473 if (element == EL_DYNAMIT)
475 if ((phase = (96-MovDelay[jx][jy])/12) > 6)
480 if ((phase = ((96-MovDelay[jx][jy])/6) % 8) > 3)
484 DrawGraphicThruMask(sx,sy, graphic + phase);
489 int dest_x = SX + sx*TILEX;
490 int dest_y = SY + sy*TILEY;
496 dest_x = SX + SCREENX(MIN(jx,last_jx))*TILEX;
497 dest_y = SY + SCREENY(MIN(jy,last_jy))*TILEY;
498 x_size = TILEX * (1 + ABS(jx - last_jx));
499 y_size = TILEY * (1 + ABS(jy - last_jy));
502 XCopyArea(display,drawto_field,window,gc,
503 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
504 SetDrawtoField(DRAW_DIRECT);
507 MarkTileDirty(sx,sy);
510 static int getGraphicAnimationPhase(int frames, int delay, int mode)
514 if (mode == ANIM_OSCILLATE)
516 int max_anim_frames = frames*2 - 2;
517 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
518 phase = (phase < frames ? phase : max_anim_frames - phase);
521 phase = (FrameCounter % (delay * frames)) / delay;
523 if (mode == ANIM_REVERSE)
529 void DrawGraphicAnimationExt(int x, int y, int graphic,
530 int frames, int delay, int mode, int mask_mode)
532 int phase = getGraphicAnimationPhase(frames, delay, mode);
534 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
536 if (mask_mode == USE_MASKING)
537 DrawGraphicThruMask(SCREENX(x),SCREENY(y), graphic + phase);
539 DrawGraphic(SCREENX(x),SCREENY(y), graphic + phase);
543 void DrawGraphicAnimation(int x, int y, int graphic,
544 int frames, int delay, int mode)
546 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, NO_MASKING);
549 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
550 int frames, int delay, int mode)
552 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, USE_MASKING);
555 void DrawGraphic(int x, int y, int graphic)
559 if (!IN_SCR_FIELD(x,y))
561 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
562 printf("DrawGraphic(): This should never happen!\n");
567 DrawGraphicExt(drawto_field, gc, FX+x*TILEX, FY+y*TILEY, graphic);
571 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
573 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
575 graphic -= GFX_START_ROCKSSCREEN;
576 XCopyArea(display,pix[PIX_BACK],d,gc,
577 SX + (graphic % GFX_PER_LINE) * TILEX,
578 SY + (graphic / GFX_PER_LINE) * TILEY,
581 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
583 graphic -= GFX_START_ROCKSHEROES;
584 XCopyArea(display,pix[PIX_HEROES],d,gc,
585 (graphic % HEROES_PER_LINE) * TILEX,
586 (graphic / HEROES_PER_LINE) * TILEY,
589 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
591 graphic -= GFX_START_ROCKSFONT;
592 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
593 (graphic % FONT_CHARS_PER_LINE) * TILEX,
594 (graphic / FONT_CHARS_PER_LINE) * TILEY +
595 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
599 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
602 void DrawGraphicThruMask(int x, int y, int graphic)
604 int src_x,src_y, dest_x,dest_y;
610 if (!IN_SCR_FIELD(x,y))
612 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
613 printf("DrawGraphicThruMask(): This should never happen!\n");
618 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
620 src_pixmap = pix[PIX_BACK];
621 drawing_gc = clip_gc[PIX_BACK];
622 graphic -= GFX_START_ROCKSSCREEN;
623 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
624 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
626 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
628 src_pixmap = pix[PIX_HEROES];
629 drawing_gc = clip_gc[PIX_HEROES];
630 graphic -= GFX_START_ROCKSHEROES;
631 src_x = (graphic % HEROES_PER_LINE)*TILEX;
632 src_y = (graphic / HEROES_PER_LINE)*TILEY;
636 DrawGraphic(x,y,graphic);
640 dest_x = FX + x*TILEX;
641 dest_y = FY + y*TILEY;
643 if (tile_clipmask[tile] != None)
645 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
646 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
647 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
648 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
653 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
656 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
657 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
658 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
664 void DrawMiniGraphic(int x, int y, int graphic)
666 DrawMiniGraphicExt(drawto,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
667 MarkTileDirty(x/2, y/2);
670 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
672 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
674 graphic -= GFX_START_ROCKSSCREEN;
675 XCopyArea(display,pix[PIX_BACK],d,gc,
676 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
677 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
678 MINI_TILEX,MINI_TILEY, x,y);
680 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
682 graphic -= GFX_START_ROCKSFONT;
683 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
684 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
685 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
686 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
687 MINI_TILEX,MINI_TILEY, x,y);
690 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
693 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
694 int cut_mode, int mask_mode)
696 int width = TILEX, height = TILEY;
698 int src_x,src_y, dest_x,dest_y;
705 DrawGraphic(x,y,graphic);
709 if (dx || dy) /* Verschiebung der Grafik? */
711 if (x < BX1) /* Element kommt von links ins Bild */
718 else if (x > BX2) /* Element kommt von rechts ins Bild */
724 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
730 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
732 else if (dx) /* allg. Bewegung in x-Richtung */
733 MarkTileDirty(x + SIGN(dx), y);
735 if (y < BY1) /* Element kommt von oben ins Bild */
737 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
745 else if (y > BY2) /* Element kommt von unten ins Bild */
751 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
757 else if (dy > 0 && cut_mode==CUT_ABOVE)
759 if (y == BY2) /* Element unterhalb des Bildes */
765 MarkTileDirty(x, y + 1);
766 } /* Element verläßt unten das Bild */
767 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
769 else if (dy) /* allg. Bewegung in y-Richtung */
770 MarkTileDirty(x, y + SIGN(dy));
773 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
775 src_pixmap = pix[PIX_BACK];
776 drawing_gc = clip_gc[PIX_BACK];
777 graphic -= GFX_START_ROCKSSCREEN;
778 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
779 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
781 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
783 src_pixmap = pix[PIX_HEROES];
784 drawing_gc = clip_gc[PIX_HEROES];
785 graphic -= GFX_START_ROCKSHEROES;
786 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
787 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
790 dest_x = FX + x*TILEX + dx;
791 dest_y = FY + y*TILEY + dy;
794 if (!IN_SCR_FIELD(x,y))
796 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
797 printf("DrawGraphicShifted(): This should never happen!\n");
802 if (mask_mode == USE_MASKING)
804 if (tile_clipmask[tile] != None)
806 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
807 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
808 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
809 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
814 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
817 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
818 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
819 src_x,src_y, width,height, dest_x,dest_y);
823 XCopyArea(display, src_pixmap, drawto_field, gc,
824 src_x,src_y, width,height, dest_x,dest_y);
829 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
832 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
835 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
836 int cut_mode, int mask_mode)
838 int ux = LEVELX(x), uy = LEVELY(y);
839 int graphic = el2gfx(element);
840 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
841 int phase = phase4 / 2;
842 int dir = MovDir[ux][uy];
844 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
850 else if (dir == MV_LEFT)
852 else if (dir == MV_DOWN)
855 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
856 element==EL_SCHWEIN || element==EL_DRACHE)
859 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
860 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
861 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
862 else if (dir==MV_RIGHT)
863 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
864 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
865 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
867 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
868 element==EL_PINGUIN ? GFX_PINGUIN_UP :
869 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
871 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
872 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
873 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
877 else if (element==EL_SONDE)
879 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
881 else if (element==EL_SALZSAEURE)
883 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
885 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
889 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
891 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
893 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
894 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
896 graphic += 3-(SiebAktiv%8)/2;
898 else if (IS_AMOEBOID(element))
900 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
901 graphic += (x+2*y) % 4;
903 else if (element==EL_MAUER_LEBT)
905 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
907 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
909 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
910 rechts_massiv = TRUE;
912 if (links_massiv && rechts_massiv)
913 graphic = GFX_MAUERWERK;
914 else if (links_massiv)
915 graphic = GFX_MAUER_R;
916 else if (rechts_massiv)
917 graphic = GFX_MAUER_L;
921 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, mask_mode);
922 else if (mask_mode == USE_MASKING)
923 DrawGraphicThruMask(x,y, graphic);
925 DrawGraphic(x,y, graphic);
928 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
929 int cut_mode, int mask_mode)
931 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
932 DrawScreenElementExt(SCREENX(x),SCREENY(y), dx,dy, element,
933 cut_mode, mask_mode);
936 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
939 DrawScreenElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
942 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
945 DrawLevelElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
948 void DrawScreenElementThruMask(int x, int y, int element)
950 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
953 void DrawLevelElementThruMask(int x, int y, int element)
955 DrawLevelElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
958 void ErdreichAnbroeckeln(int x, int y)
960 int i, width, height, cx,cy;
961 int ux = LEVELX(x), uy = LEVELY(y);
962 int element, graphic;
964 static int xy[4][2] =
972 if (!IN_LEV_FIELD(ux,uy))
975 element = Feld[ux][uy];
977 if (element==EL_ERDREICH)
979 if (!IN_SCR_FIELD(x,y))
982 graphic = GFX_ERDENRAND;
990 if (!IN_LEV_FIELD(uxx,uyy))
993 element = Feld[uxx][uyy];
995 if (element==EL_ERDREICH)
1002 cx = (i==2 ? TILEX-snip : 0);
1010 cy = (i==3 ? TILEY-snip : 0);
1013 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1014 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1015 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1016 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1023 graphic = GFX_ERDENRAND;
1034 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1035 !IN_SCR_FIELD(xx,yy))
1042 cx = (i==1 ? TILEX-snip : 0);
1050 cy = (i==0 ? TILEY-snip : 0);
1053 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1054 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1055 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1056 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1058 MarkTileDirty(xx,yy);
1063 void DrawScreenElement(int x, int y, int element)
1065 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, NO_MASKING);
1066 ErdreichAnbroeckeln(x,y);
1069 void DrawLevelElement(int x, int y, int element)
1071 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1072 DrawScreenElement(SCREENX(x),SCREENY(y),element);
1075 void DrawScreenField(int x, int y)
1077 int ux = LEVELX(x), uy = LEVELY(y);
1080 if (!IN_LEV_FIELD(ux,uy))
1082 DrawScreenElement(x,y,EL_BETON);
1086 element = Feld[ux][uy];
1088 if (IS_MOVING(ux,uy))
1090 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1091 BOOL cut_mode = NO_CUTTING;
1093 if (Store[ux][uy]==EL_MORAST_LEER ||
1094 Store[ux][uy]==EL_SIEB_LEER ||
1095 Store[ux][uy]==EL_SIEB2_LEER ||
1096 Store[ux][uy]==EL_AMOEBE_NASS)
1097 cut_mode = CUT_ABOVE;
1098 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1101 Store[ux][uy]==EL_SALZSAEURE ||
1104 Store[ux][uy]==EL_SIEB_VOLL ||
1105 Store[ux][uy]==EL_SIEB2_VOLL)
1106 cut_mode = CUT_BELOW;
1108 if (cut_mode==CUT_ABOVE)
1109 DrawScreenElementShifted(x,y, 0,0, Store[ux][uy], NO_CUTTING);
1111 DrawScreenElement(x,y,EL_LEERRAUM);
1114 DrawScreenElementShifted(x,y, MovPos[ux][uy],0, element, NO_CUTTING);
1116 DrawScreenElementShifted(x,y, 0,MovPos[ux][uy], element, cut_mode);
1119 if (Store[ux][uy] == EL_SALZSAEURE)
1120 DrawLevelElementThruMask(ux,uy+1, EL_SALZSAEURE);
1124 else if (IS_BLOCKED(ux,uy))
1129 BOOL cut_mode = NO_CUTTING;
1131 Blocked2Moving(ux,uy,&oldx,&oldy);
1134 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1136 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1137 Store[oldx][oldy]==EL_SIEB_LEER ||
1138 Store[oldx][oldy]==EL_SIEB2_LEER ||
1139 Store[oldx][oldy]==EL_AMOEBE_NASS)
1140 cut_mode = CUT_ABOVE;
1142 DrawScreenElement(x,y,EL_LEERRAUM);
1143 element = Feld[oldx][oldy];
1146 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1148 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1150 else if (IS_DRAWABLE(element))
1151 DrawScreenElement(x,y,element);
1153 DrawScreenElement(x,y,EL_LEERRAUM);
1156 void DrawLevelField(int x, int y)
1158 if (IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1159 DrawScreenField(SCREENX(x),SCREENY(y));
1160 else if (IS_MOVING(x,y))
1164 Moving2Blocked(x,y,&newx,&newy);
1165 if (IN_SCR_FIELD(SCREENX(newx),SCREENY(newy)))
1166 DrawScreenField(SCREENX(newx),SCREENY(newy));
1168 else if (IS_BLOCKED(x,y))
1172 Blocked2Moving(x,y,&oldx,&oldy);
1173 if (IN_SCR_FIELD(SCREENX(oldx),SCREENY(oldy)))
1174 DrawScreenField(SCREENX(oldx),SCREENY(oldy));
1178 void DrawMiniElement(int x, int y, int element)
1184 DrawMiniGraphic(x,y,-1);
1188 graphic = el2gfx(element);
1189 DrawMiniGraphic(x,y,graphic);
1192 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1194 int x = sx + scroll_x, y = sy + scroll_y;
1196 if (x<-1 || x>lev_fieldx || y<-1 || y>lev_fieldy)
1197 DrawMiniElement(sx,sy,EL_LEERRAUM);
1198 else if (x==-1 || x==lev_fieldx || y==-1 || y==lev_fieldy)
1199 DrawMiniElement(sx,sy,EL_BETON);
1201 DrawMiniElement(sx,sy,Feld[x][y]);
1204 void DrawMicroElement(int xpos, int ypos, int element)
1208 if (element==EL_LEERRAUM)
1211 graphic = el2gfx(element);
1213 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1214 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1215 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1216 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1225 for(x=BX1; x<=BX2; x++)
1226 for(y=BY1; y<=BY2; y++)
1227 DrawScreenField(x,y);
1229 if (soft_scrolling_on)
1230 XCopyArea(display,fieldbuffer,backbuffer,gc,
1231 FX,FY, SXSIZE,SYSIZE,
1234 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1237 void DrawMiniLevel(int scroll_x, int scroll_y)
1243 for(x=0;x<2*SCR_FIELDX;x++)
1244 for(y=0;y<2*SCR_FIELDY;y++)
1245 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1247 redraw_mask |= REDRAW_FIELD;
1250 void DrawMicroLevel(int xpos, int ypos)
1254 XFillRectangle(display,drawto,gc,
1255 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1256 MICRO_TILEX*(STD_LEV_FIELDX+2),
1257 MICRO_TILEY*(STD_LEV_FIELDY+2));
1258 if (lev_fieldx < STD_LEV_FIELDX)
1259 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1260 if (lev_fieldy < STD_LEV_FIELDY)
1261 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1263 for(x=-1;x<=STD_LEV_FIELDX;x++)
1264 for(y=-1;y<=STD_LEV_FIELDY;y++)
1265 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1266 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1267 Feld[x][y]=Ur[x][y]);
1268 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1269 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1272 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1276 int len = strlen(level.name);
1277 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1278 int lypos = MICROLABEL_YPOS;
1280 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1283 redraw_mask |= REDRAW_MICROLEV;
1286 int AYS_in_range(int x, int y)
1288 if (y>DY+249 && y<DY+278)
1290 if (x>DX+1 && x<DX+48)
1292 else if (x>DX+51 && x<DX+98)
1298 BOOL AreYouSure(char *text, unsigned int ays_state)
1300 int mx,my, ty, result = -1;
1301 unsigned int old_door_state;
1303 old_door_state = GetDoorState();
1305 CloseDoor(DOOR_CLOSE_1);
1307 /* Alten Türinhalt sichern */
1308 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1309 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1310 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1312 /* Fragetext schreiben */
1313 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1314 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1316 for(ty=0;ty<13;ty++)
1323 for(tl=0,tx=0;tx<7;tl++,tx++)
1337 DrawTextExt(pix[PIX_DB_DOOR],gc,
1338 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1339 text+=(tl+(tc==32));
1342 if (ays_state & AYS_ASK)
1343 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1344 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1345 DXSIZE,OK_BUTTON_YSIZE,
1346 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1347 else if (ays_state & AYS_CONFIRM)
1348 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1349 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1350 DXSIZE,CONFIRM_BUTTON_YSIZE,
1351 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1353 OpenDoor(DOOR_OPEN_1);
1356 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1359 if (game_status != MAINMENU)
1362 button_status = MB_RELEASED;
1369 if (XPending(display))
1373 XNextEvent(display, &event);
1377 HandleExposeEvent((XExposeEvent *) &event);
1380 SleepWhileUnmapped();
1388 if (event.type == MotionNotify)
1390 motion_status = TRUE;
1391 mx = ((XMotionEvent *) &event)->x;
1392 my = ((XMotionEvent *) &event)->y;
1396 motion_status = FALSE;
1397 mx = ((XButtonEvent *) &event)->x;
1398 my = ((XButtonEvent *) &event)->y;
1399 if (event.type==ButtonPress)
1400 button_status = ((XButtonEvent *) &event)->button;
1402 button_status = MB_RELEASED;
1405 if (ays_state & AYS_ASK)
1406 choice = CheckChooseButtons(mx,my,button_status);
1408 choice = CheckConfirmButton(mx,my,button_status);
1418 case BUTTON_CONFIRM:
1419 result = TRUE|FALSE;
1427 switch(XLookupKeysym((XKeyEvent *)&event,
1428 ((XKeyEvent *)&event)->state))
1439 key_joystick_mapping = 0;
1443 HandleFocusEvent((XFocusChangeEvent *) &event);
1446 HandleClientMessageEvent((XClientMessageEvent *) &event);
1452 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1456 if (joy & JOY_BUTTON_1)
1458 else if (joy & JOY_BUTTON_2)
1463 if (game_status != MAINMENU)
1466 if (!(ays_state & AYS_STAY_OPEN))
1468 CloseDoor(DOOR_CLOSE_1);
1470 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1472 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1473 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1474 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1475 OpenDoor(DOOR_OPEN_1);
1482 unsigned int OpenDoor(unsigned int door_state)
1484 unsigned int new_door_state;
1486 if (door_state & DOOR_COPY_BACK)
1488 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1489 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1490 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1491 door_state &= ~DOOR_COPY_BACK;
1494 new_door_state = MoveDoor(door_state);
1496 return(new_door_state);
1499 unsigned int CloseDoor(unsigned int door_state)
1501 unsigned int new_door_state;
1503 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1504 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1505 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1506 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1508 new_door_state = MoveDoor(door_state);
1510 return(new_door_state);
1513 unsigned int GetDoorState()
1515 return(MoveDoor(DOOR_GET_STATE));
1518 unsigned int MoveDoor(unsigned int door_state)
1520 static unsigned int door1 = DOOR_OPEN_1;
1521 static unsigned int door2 = DOOR_CLOSE_2;
1522 static long door_delay = 0;
1523 int x, start, stepsize = 2;
1524 long door_delay_value = stepsize * 5;
1526 if (door_state == DOOR_GET_STATE)
1527 return(door1 | door2);
1529 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1530 door_state &= ~DOOR_OPEN_1;
1531 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1532 door_state &= ~DOOR_CLOSE_1;
1533 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1534 door_state &= ~DOOR_OPEN_2;
1535 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1536 door_state &= ~DOOR_CLOSE_2;
1541 door_delay_value = 0;
1542 StopSound(SND_OEFFNEN);
1545 if (door_state & DOOR_ACTION)
1547 if (!(door_state & DOOR_NO_DELAY))
1548 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1550 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1552 for(x=start; x<=DXSIZE; x+=stepsize)
1554 WaitUntilDelayReached(&door_delay, door_delay_value);
1556 if (door_state & DOOR_ACTION_1)
1558 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1559 int j = (DXSIZE - i)/3;
1561 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1562 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1563 DXSIZE,DYSIZE-i/2, DX,DY);
1565 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1567 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1568 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1569 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1570 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1571 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1572 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1573 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1574 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1575 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1576 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1577 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1578 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1580 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1581 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1583 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1584 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1586 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1587 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1588 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1589 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1590 DX+DXSIZE-i,DY+77+j);
1591 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1592 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1593 DX+DXSIZE-i,DY+203+j);
1595 redraw_mask |= REDRAW_DOOR_1;
1598 if (door_state & DOOR_ACTION_2)
1600 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1601 int j = (VXSIZE - i)/3;
1603 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1604 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1605 VXSIZE,VYSIZE-i/2, VX,VY);
1607 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/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, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1613 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1614 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1615 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1616 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1618 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1619 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1621 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1622 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1623 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1624 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1625 VX+VXSIZE-i,VY+VYSIZE/2+j);
1627 redraw_mask |= REDRAW_DOOR_2;
1632 if (game_status == MAINMENU)
1637 if (door_state & DOOR_ACTION_1)
1638 door1 = door_state & DOOR_ACTION_1;
1639 if (door_state & DOOR_ACTION_2)
1640 door2 = door_state & DOOR_ACTION_2;
1642 return(door1 | door2);
1645 int ReadPixel(Drawable d, int x, int y)
1647 static XImage *pixelimage;
1649 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1650 return(XGetPixel(pixelimage,0,0));
1653 int el2gfx(int element)
1657 case EL_LEERRAUM: return(-1);
1658 case EL_ERDREICH: return(GFX_ERDREICH);
1659 case EL_MAUERWERK: return(GFX_MAUERWERK);
1660 case EL_FELSBODEN: return(GFX_FELSBODEN);
1661 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1662 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1663 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1664 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1665 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1666 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1667 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1668 case EL_SPIELER1: return(GFX_SPIELER1);
1669 case EL_SPIELER2: return(GFX_SPIELER2);
1670 case EL_SPIELER3: return(GFX_SPIELER3);
1671 case EL_SPIELER4: return(GFX_SPIELER4);
1672 case EL_KAEFER: return(GFX_KAEFER);
1673 case EL_KAEFER_R: return(GFX_KAEFER_R);
1674 case EL_KAEFER_O: return(GFX_KAEFER_O);
1675 case EL_KAEFER_L: return(GFX_KAEFER_L);
1676 case EL_KAEFER_U: return(GFX_KAEFER_U);
1677 case EL_FLIEGER: return(GFX_FLIEGER);
1678 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1679 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1680 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1681 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1682 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1683 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1684 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1685 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1686 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1687 case EL_FIREFLY: return(GFX_FIREFLY);
1688 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1689 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1690 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1691 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1692 case EL_MAMPFER: return(GFX_MAMPFER);
1693 case EL_ROBOT: return(GFX_ROBOT);
1694 case EL_BETON: return(GFX_BETON);
1695 case EL_DIAMANT: return(GFX_DIAMANT);
1696 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1697 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1698 case EL_TROPFEN: return(GFX_TROPFEN);
1699 case EL_BOMBE: return(GFX_BOMBE);
1700 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1701 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1702 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1703 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1704 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1705 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1706 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1707 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1708 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1709 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1710 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1711 case EL_LIFE: return(GFX_LIFE);
1712 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1713 case EL_DYNAMIT: return(GFX_DYNAMIT);
1714 case EL_BADEWANNE: return(GFX_BADEWANNE);
1715 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1716 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1717 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1718 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1719 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1720 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1721 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1722 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1723 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1724 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1725 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1726 case EL_PFORTE1: return(GFX_PFORTE1);
1727 case EL_PFORTE2: return(GFX_PFORTE2);
1728 case EL_PFORTE3: return(GFX_PFORTE3);
1729 case EL_PFORTE4: return(GFX_PFORTE4);
1730 case EL_PFORTE1X: return(GFX_PFORTE1X);
1731 case EL_PFORTE2X: return(GFX_PFORTE2X);
1732 case EL_PFORTE3X: return(GFX_PFORTE3X);
1733 case EL_PFORTE4X: return(GFX_PFORTE4X);
1734 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1735 case EL_PACMAN: return(GFX_PACMAN);
1736 case EL_PACMAN_R: return(GFX_PACMAN_R);
1737 case EL_PACMAN_O: return(GFX_PACMAN_O);
1738 case EL_PACMAN_L: return(GFX_PACMAN_L);
1739 case EL_PACMAN_U: return(GFX_PACMAN_U);
1740 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1741 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1742 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1743 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1744 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1745 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1746 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1747 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1748 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1749 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1750 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1751 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1752 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1753 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1754 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1755 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1756 case EL_MAMPFER2: return(GFX_MAMPFER2);
1757 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1758 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1759 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1760 case EL_DYNABOMB: return(GFX_DYNABOMB);
1761 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1762 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1763 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1764 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1765 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1766 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1767 case EL_MAULWURF: return(GFX_MAULWURF);
1768 case EL_PINGUIN: return(GFX_PINGUIN);
1769 case EL_SCHWEIN: return(GFX_SCHWEIN);
1770 case EL_DRACHE: return(GFX_DRACHE);
1771 case EL_SONDE: return(GFX_SONDE);
1772 case EL_PFEIL_L: return(GFX_PFEIL_L);
1773 case EL_PFEIL_R: return(GFX_PFEIL_R);
1774 case EL_PFEIL_O: return(GFX_PFEIL_O);
1775 case EL_PFEIL_U: return(GFX_PFEIL_U);
1778 if (IS_CHAR(element))
1779 return(GFX_CHAR_START + (element-EL_CHAR_START));