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 || ScreenGfxPos)
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 += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
113 fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 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 + SCREENX(MIN(jx,last_jx))*TILEX;
490 int dest_y = SY + SCREENY(MIN(jy,last_jy))*TILEY;
491 int x_size = TILEX * (1 + ABS(jx - last_jx));
492 int y_size = TILEY * (1 + ABS(jy - last_jy));
494 XCopyArea(display,drawto_field,window,gc,
495 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
496 SetDrawtoField(DRAW_DIRECT);
499 MarkTileDirty(sx,sy);
502 static int getGraphicAnimationPhase(int frames, int delay, int mode)
506 if (mode == ANIM_OSCILLATE)
508 int max_anim_frames = frames*2 - 2;
509 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
510 phase = (phase < frames ? phase : max_anim_frames - phase);
513 phase = (FrameCounter % (delay * frames)) / delay;
515 if (mode == ANIM_REVERSE)
521 void DrawGraphicAnimationExt(int x, int y, int graphic,
522 int frames, int delay, int mode, int mask_mode)
524 int phase = getGraphicAnimationPhase(frames, delay, mode);
526 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
528 if (mask_mode == USE_MASKING)
529 DrawGraphicThruMask(SCREENX(x),SCREENY(y), graphic + phase);
531 DrawGraphic(SCREENX(x),SCREENY(y), graphic + phase);
535 void DrawGraphicAnimation(int x, int y, int graphic,
536 int frames, int delay, int mode)
538 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, NO_MASKING);
541 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
542 int frames, int delay, int mode)
544 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, USE_MASKING);
547 void DrawGraphic(int x, int y, int graphic)
551 if (!IN_SCR_FIELD(x,y))
553 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
554 printf("DrawGraphic(): This should never happen!\n");
559 DrawGraphicExt(drawto_field, gc, FX+x*TILEX, FY+y*TILEY, graphic);
563 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
565 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
567 graphic -= GFX_START_ROCKSSCREEN;
568 XCopyArea(display,pix[PIX_BACK],d,gc,
569 SX + (graphic % GFX_PER_LINE) * TILEX,
570 SY + (graphic / GFX_PER_LINE) * TILEY,
573 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
575 graphic -= GFX_START_ROCKSHEROES;
576 XCopyArea(display,pix[PIX_HEROES],d,gc,
577 (graphic % HEROES_PER_LINE) * TILEX,
578 (graphic / HEROES_PER_LINE) * TILEY,
581 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
583 graphic -= GFX_START_ROCKSFONT;
584 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
585 (graphic % FONT_CHARS_PER_LINE) * TILEX,
586 (graphic / FONT_CHARS_PER_LINE) * TILEY +
587 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
591 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
594 void DrawGraphicThruMask(int x, int y, int graphic)
596 int src_x,src_y, dest_x,dest_y;
602 if (!IN_SCR_FIELD(x,y))
604 printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
605 printf("DrawGraphicThruMask(): This should never happen!\n");
610 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
612 src_pixmap = pix[PIX_BACK];
613 drawing_gc = clip_gc[PIX_BACK];
614 graphic -= GFX_START_ROCKSSCREEN;
615 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
616 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
618 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
620 src_pixmap = pix[PIX_HEROES];
621 drawing_gc = clip_gc[PIX_HEROES];
622 graphic -= GFX_START_ROCKSHEROES;
623 src_x = (graphic % HEROES_PER_LINE)*TILEX;
624 src_y = (graphic / HEROES_PER_LINE)*TILEY;
628 DrawGraphic(x,y,graphic);
632 dest_x = FX + x*TILEX;
633 dest_y = FY + y*TILEY;
635 if (tile_clipmask[tile] != None)
637 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
638 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
639 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
640 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
645 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
648 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
649 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
650 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
656 void DrawMiniGraphic(int x, int y, int graphic)
658 DrawMiniGraphicExt(drawto,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
659 MarkTileDirty(x/2, y/2);
662 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
664 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
666 graphic -= GFX_START_ROCKSSCREEN;
667 XCopyArea(display,pix[PIX_BACK],d,gc,
668 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
669 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
670 MINI_TILEX,MINI_TILEY, x,y);
672 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
674 graphic -= GFX_START_ROCKSFONT;
675 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
676 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
677 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
678 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
679 MINI_TILEX,MINI_TILEY, x,y);
682 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
685 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
686 int cut_mode, int mask_mode)
688 int width = TILEX, height = TILEY;
690 int src_x,src_y, dest_x,dest_y;
697 DrawGraphic(x,y,graphic);
701 if (dx || dy) /* Verschiebung der Grafik? */
703 if (x < BX1) /* Element kommt von links ins Bild */
710 else if (x > BX2) /* Element kommt von rechts ins Bild */
716 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
722 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
724 else if (dx) /* allg. Bewegung in x-Richtung */
725 MarkTileDirty(x + SIGN(dx), y);
727 if (y < BY1) /* Element kommt von oben ins Bild */
729 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
737 else if (y > BY2) /* Element kommt von unten ins Bild */
743 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
749 else if (dy > 0 && cut_mode==CUT_ABOVE)
751 if (y == BY2) /* Element unterhalb des Bildes */
757 MarkTileDirty(x, y + 1);
758 } /* Element verläßt unten das Bild */
759 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
761 else if (dy) /* allg. Bewegung in y-Richtung */
762 MarkTileDirty(x, y + SIGN(dy));
765 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
767 src_pixmap = pix[PIX_BACK];
768 drawing_gc = clip_gc[PIX_BACK];
769 graphic -= GFX_START_ROCKSSCREEN;
770 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
771 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
773 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
775 src_pixmap = pix[PIX_HEROES];
776 drawing_gc = clip_gc[PIX_HEROES];
777 graphic -= GFX_START_ROCKSHEROES;
778 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
779 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
782 dest_x = FX + x*TILEX + dx;
783 dest_y = FY + y*TILEY + dy;
786 if (!IN_SCR_FIELD(x,y))
788 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
789 printf("DrawGraphicShifted(): This should never happen!\n");
794 if (mask_mode == USE_MASKING)
796 if (tile_clipmask[tile] != None)
798 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
799 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
800 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
801 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
806 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
809 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
810 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
811 src_x,src_y, width,height, dest_x,dest_y);
815 XCopyArea(display, src_pixmap, drawto_field, gc,
816 src_x,src_y, width,height, dest_x,dest_y);
821 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
824 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
827 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
828 int cut_mode, int mask_mode)
830 int ux = LEVELX(x), uy = LEVELY(y);
831 int graphic = el2gfx(element);
832 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
833 int phase = phase4 / 2;
834 int dir = MovDir[ux][uy];
836 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
842 else if (dir == MV_LEFT)
844 else if (dir == MV_DOWN)
847 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
848 element==EL_SCHWEIN || element==EL_DRACHE)
851 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
852 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
853 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
854 else if (dir==MV_RIGHT)
855 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
856 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
857 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
859 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
860 element==EL_PINGUIN ? GFX_PINGUIN_UP :
861 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
863 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
864 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
865 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
869 else if (element==EL_SONDE)
871 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
873 else if (element==EL_SALZSAEURE)
875 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
877 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
881 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
883 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
885 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
886 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
888 graphic += 3-(SiebAktiv%8)/2;
890 else if (IS_AMOEBOID(element))
892 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
893 graphic += (x+2*y) % 4;
895 else if (element==EL_MAUER_LEBT)
897 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
899 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
901 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
902 rechts_massiv = TRUE;
904 if (links_massiv && rechts_massiv)
905 graphic = GFX_MAUERWERK;
906 else if (links_massiv)
907 graphic = GFX_MAUER_R;
908 else if (rechts_massiv)
909 graphic = GFX_MAUER_L;
913 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, mask_mode);
914 else if (mask_mode == USE_MASKING)
915 DrawGraphicThruMask(x,y, graphic);
917 DrawGraphic(x,y, graphic);
920 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
921 int cut_mode, int mask_mode)
923 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
924 DrawScreenElementExt(SCREENX(x),SCREENY(y), dx,dy, element,
925 cut_mode, mask_mode);
928 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
931 DrawScreenElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
934 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
937 DrawLevelElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
940 void DrawScreenElementThruMask(int x, int y, int element)
942 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
945 void DrawLevelElementThruMask(int x, int y, int element)
947 DrawLevelElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
950 void ErdreichAnbroeckeln(int x, int y)
952 int i, width, height, cx,cy;
953 int ux = LEVELX(x), uy = LEVELY(y);
954 int element, graphic;
956 static int xy[4][2] =
964 if (!IN_LEV_FIELD(ux,uy))
967 element = Feld[ux][uy];
969 if (element==EL_ERDREICH)
971 if (!IN_SCR_FIELD(x,y))
974 graphic = GFX_ERDENRAND;
982 if (!IN_LEV_FIELD(uxx,uyy))
985 element = Feld[uxx][uyy];
987 if (element==EL_ERDREICH)
994 cx = (i==2 ? TILEX-snip : 0);
1002 cy = (i==3 ? TILEY-snip : 0);
1005 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1006 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1007 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1008 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1015 graphic = GFX_ERDENRAND;
1026 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1027 !IN_SCR_FIELD(xx,yy))
1034 cx = (i==1 ? TILEX-snip : 0);
1042 cy = (i==0 ? TILEY-snip : 0);
1045 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1046 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1047 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1048 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1050 MarkTileDirty(xx,yy);
1055 void DrawScreenElement(int x, int y, int element)
1057 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, NO_MASKING);
1058 ErdreichAnbroeckeln(x,y);
1061 void DrawLevelElement(int x, int y, int element)
1063 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1064 DrawScreenElement(SCREENX(x),SCREENY(y),element);
1067 void DrawScreenField(int x, int y)
1069 int ux = LEVELX(x), uy = LEVELY(y);
1072 if (!IN_LEV_FIELD(ux,uy))
1074 DrawScreenElement(x,y,EL_BETON);
1078 element = Feld[ux][uy];
1080 if (IS_MOVING(ux,uy))
1082 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1083 BOOL cut_mode = NO_CUTTING;
1085 if (Store[ux][uy]==EL_MORAST_LEER ||
1086 Store[ux][uy]==EL_SIEB_LEER ||
1087 Store[ux][uy]==EL_SIEB2_LEER ||
1088 Store[ux][uy]==EL_AMOEBE_NASS)
1089 cut_mode = CUT_ABOVE;
1090 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1093 Store[ux][uy]==EL_SALZSAEURE ||
1096 Store[ux][uy]==EL_SIEB_VOLL ||
1097 Store[ux][uy]==EL_SIEB2_VOLL)
1098 cut_mode = CUT_BELOW;
1100 if (cut_mode==CUT_ABOVE)
1101 DrawScreenElementShifted(x,y, 0,0, Store[ux][uy], NO_CUTTING);
1103 DrawScreenElement(x,y,EL_LEERRAUM);
1106 DrawScreenElementShifted(x,y, MovPos[ux][uy],0, element, NO_CUTTING);
1108 DrawScreenElementShifted(x,y, 0,MovPos[ux][uy], element, cut_mode);
1111 if (Store[ux][uy] == EL_SALZSAEURE)
1112 DrawLevelElementThruMask(ux,uy+1, EL_SALZSAEURE);
1116 else if (IS_BLOCKED(ux,uy))
1121 BOOL cut_mode = NO_CUTTING;
1123 Blocked2Moving(ux,uy,&oldx,&oldy);
1126 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1128 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1129 Store[oldx][oldy]==EL_SIEB_LEER ||
1130 Store[oldx][oldy]==EL_SIEB2_LEER ||
1131 Store[oldx][oldy]==EL_AMOEBE_NASS)
1132 cut_mode = CUT_ABOVE;
1134 DrawScreenElement(x,y,EL_LEERRAUM);
1135 element = Feld[oldx][oldy];
1138 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1140 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1142 else if (IS_DRAWABLE(element))
1143 DrawScreenElement(x,y,element);
1145 DrawScreenElement(x,y,EL_LEERRAUM);
1148 void DrawLevelField(int x, int y)
1150 if (IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1151 DrawScreenField(SCREENX(x),SCREENY(y));
1152 else if (IS_MOVING(x,y))
1156 Moving2Blocked(x,y,&newx,&newy);
1157 if (IN_SCR_FIELD(SCREENX(newx),SCREENY(newy)))
1158 DrawScreenField(SCREENX(newx),SCREENY(newy));
1160 else if (IS_BLOCKED(x,y))
1164 Blocked2Moving(x,y,&oldx,&oldy);
1165 if (IN_SCR_FIELD(SCREENX(oldx),SCREENY(oldy)))
1166 DrawScreenField(SCREENX(oldx),SCREENY(oldy));
1170 void DrawMiniElement(int x, int y, int element)
1176 DrawMiniGraphic(x,y,-1);
1180 graphic = el2gfx(element);
1181 DrawMiniGraphic(x,y,graphic);
1184 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1186 int x = sx + scroll_x, y = sy + scroll_y;
1188 if (x<-1 || x>lev_fieldx || y<-1 || y>lev_fieldy)
1189 DrawMiniElement(sx,sy,EL_LEERRAUM);
1190 else if (x==-1 || x==lev_fieldx || y==-1 || y==lev_fieldy)
1191 DrawMiniElement(sx,sy,EL_BETON);
1193 DrawMiniElement(sx,sy,Feld[x][y]);
1196 void DrawMicroElement(int xpos, int ypos, int element)
1200 if (element==EL_LEERRAUM)
1203 graphic = el2gfx(element);
1205 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1206 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1207 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1208 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1217 for(x=BX1; x<=BX2; x++)
1218 for(y=BY1; y<=BY2; y++)
1219 DrawScreenField(x,y);
1221 if (soft_scrolling_on)
1222 XCopyArea(display,fieldbuffer,backbuffer,gc,
1223 FX,FY, SXSIZE,SYSIZE,
1226 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1229 void DrawMiniLevel(int scroll_x, int scroll_y)
1235 for(x=0;x<2*SCR_FIELDX;x++)
1236 for(y=0;y<2*SCR_FIELDY;y++)
1237 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1239 redraw_mask |= REDRAW_FIELD;
1242 void DrawMicroLevel(int xpos, int ypos)
1246 XFillRectangle(display,drawto,gc,
1247 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1248 MICRO_TILEX*(STD_LEV_FIELDX+2),
1249 MICRO_TILEY*(STD_LEV_FIELDY+2));
1250 if (lev_fieldx < STD_LEV_FIELDX)
1251 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1252 if (lev_fieldy < STD_LEV_FIELDY)
1253 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1255 for(x=-1;x<=STD_LEV_FIELDX;x++)
1256 for(y=-1;y<=STD_LEV_FIELDY;y++)
1257 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1258 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1259 Feld[x][y]=Ur[x][y]);
1260 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1261 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1264 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1268 int len = strlen(level.name);
1269 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1270 int lypos = MICROLABEL_YPOS;
1272 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1275 redraw_mask |= REDRAW_MICROLEV;
1278 int AYS_in_range(int x, int y)
1280 if (y>DY+249 && y<DY+278)
1282 if (x>DX+1 && x<DX+48)
1284 else if (x>DX+51 && x<DX+98)
1290 BOOL AreYouSure(char *text, unsigned int ays_state)
1292 int mx,my, ty, result = -1;
1293 unsigned int old_door_state;
1295 old_door_state = GetDoorState();
1297 CloseDoor(DOOR_CLOSE_1);
1299 /* Alten Türinhalt sichern */
1300 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1301 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1302 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1304 /* Fragetext schreiben */
1305 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1306 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1308 for(ty=0;ty<13;ty++)
1315 for(tl=0,tx=0;tx<7;tl++,tx++)
1329 DrawTextExt(pix[PIX_DB_DOOR],gc,
1330 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1331 text+=(tl+(tc==32));
1334 if (ays_state & AYS_ASK)
1335 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1336 DOOR_GFX_PAGEX4,OK_BUTTON_GFX_YPOS,
1337 DXSIZE,OK_BUTTON_YSIZE,
1338 DOOR_GFX_PAGEX1,OK_BUTTON_YPOS);
1339 else if (ays_state & AYS_CONFIRM)
1340 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1341 DOOR_GFX_PAGEX4,CONFIRM_BUTTON_GFX_YPOS,
1342 DXSIZE,CONFIRM_BUTTON_YSIZE,
1343 DOOR_GFX_PAGEX1,CONFIRM_BUTTON_YPOS);
1345 OpenDoor(DOOR_OPEN_1);
1348 if (!(ays_state & AYS_ASK) && !(ays_state & AYS_CONFIRM))
1351 if (game_status != MAINMENU)
1354 button_status = MB_RELEASED;
1361 if (XPending(display))
1365 XNextEvent(display, &event);
1369 HandleExposeEvent((XExposeEvent *) &event);
1372 SleepWhileUnmapped();
1380 if (event.type == MotionNotify)
1382 motion_status = TRUE;
1383 mx = ((XMotionEvent *) &event)->x;
1384 my = ((XMotionEvent *) &event)->y;
1388 motion_status = FALSE;
1389 mx = ((XButtonEvent *) &event)->x;
1390 my = ((XButtonEvent *) &event)->y;
1391 if (event.type==ButtonPress)
1392 button_status = ((XButtonEvent *) &event)->button;
1394 button_status = MB_RELEASED;
1397 if (ays_state & AYS_ASK)
1398 choice = CheckChooseButtons(mx,my,button_status);
1400 choice = CheckConfirmButton(mx,my,button_status);
1410 case BUTTON_CONFIRM:
1411 result = TRUE|FALSE;
1419 switch(XLookupKeysym((XKeyEvent *)&event,
1420 ((XKeyEvent *)&event)->state))
1431 key_joystick_mapping = 0;
1435 HandleFocusEvent((XFocusChangeEvent *) &event);
1438 HandleClientMessageEvent((XClientMessageEvent *) &event);
1444 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1448 if (joy & JOY_BUTTON_1)
1450 else if (joy & JOY_BUTTON_2)
1455 if (game_status != MAINMENU)
1458 if (!(ays_state & AYS_STAY_OPEN))
1460 CloseDoor(DOOR_CLOSE_1);
1462 if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1464 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1465 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1466 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1467 OpenDoor(DOOR_OPEN_1);
1474 unsigned int OpenDoor(unsigned int door_state)
1476 unsigned int new_door_state;
1478 if (door_state & DOOR_COPY_BACK)
1480 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1481 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1482 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1483 door_state &= ~DOOR_COPY_BACK;
1486 new_door_state = MoveDoor(door_state);
1488 return(new_door_state);
1491 unsigned int CloseDoor(unsigned int door_state)
1493 unsigned int new_door_state;
1495 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1496 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1497 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1498 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1500 new_door_state = MoveDoor(door_state);
1502 return(new_door_state);
1505 unsigned int GetDoorState()
1507 return(MoveDoor(DOOR_GET_STATE));
1510 unsigned int MoveDoor(unsigned int door_state)
1512 static unsigned int door1 = DOOR_OPEN_1;
1513 static unsigned int door2 = DOOR_CLOSE_2;
1514 static long door_delay = 0;
1515 int x, start, stepsize = 2;
1516 long door_delay_value = stepsize * 5;
1518 if (door_state == DOOR_GET_STATE)
1519 return(door1 | door2);
1521 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1522 door_state &= ~DOOR_OPEN_1;
1523 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1524 door_state &= ~DOOR_CLOSE_1;
1525 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1526 door_state &= ~DOOR_OPEN_2;
1527 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1528 door_state &= ~DOOR_CLOSE_2;
1533 door_delay_value = 0;
1534 StopSound(SND_OEFFNEN);
1537 if (door_state & DOOR_ACTION)
1539 if (!(door_state & DOOR_NO_DELAY))
1540 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1542 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1544 for(x=start; x<=DXSIZE; x+=stepsize)
1546 WaitUntilDelayReached(&door_delay, door_delay_value);
1548 if (door_state & DOOR_ACTION_1)
1550 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1551 int j = (DXSIZE - i)/3;
1553 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1554 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1555 DXSIZE,DYSIZE-i/2, DX,DY);
1557 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1559 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1560 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1561 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1562 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1563 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1564 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1565 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1566 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1567 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1568 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1569 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1570 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1572 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1573 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1575 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1576 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1578 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1579 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1580 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1581 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1582 DX+DXSIZE-i,DY+77+j);
1583 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1584 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1585 DX+DXSIZE-i,DY+203+j);
1587 redraw_mask |= REDRAW_DOOR_1;
1590 if (door_state & DOOR_ACTION_2)
1592 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1593 int j = (VXSIZE - i)/3;
1595 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1596 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1597 VXSIZE,VYSIZE-i/2, VX,VY);
1599 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1601 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1602 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1603 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1604 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1605 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1606 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1607 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1608 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1610 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1611 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1613 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1614 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1615 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1616 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1617 VX+VXSIZE-i,VY+VYSIZE/2+j);
1619 redraw_mask |= REDRAW_DOOR_2;
1624 if (game_status == MAINMENU)
1629 if (door_state & DOOR_ACTION_1)
1630 door1 = door_state & DOOR_ACTION_1;
1631 if (door_state & DOOR_ACTION_2)
1632 door2 = door_state & DOOR_ACTION_2;
1634 return(door1 | door2);
1637 int ReadPixel(Drawable d, int x, int y)
1639 static XImage *pixelimage;
1641 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1642 return(XGetPixel(pixelimage,0,0));
1645 int el2gfx(int element)
1649 case EL_LEERRAUM: return(-1);
1650 case EL_ERDREICH: return(GFX_ERDREICH);
1651 case EL_MAUERWERK: return(GFX_MAUERWERK);
1652 case EL_FELSBODEN: return(GFX_FELSBODEN);
1653 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1654 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1655 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1656 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1657 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1658 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1659 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1660 case EL_SPIELER1: return(GFX_SPIELER1);
1661 case EL_SPIELER2: return(GFX_SPIELER2);
1662 case EL_SPIELER3: return(GFX_SPIELER3);
1663 case EL_SPIELER4: return(GFX_SPIELER4);
1664 case EL_KAEFER: return(GFX_KAEFER);
1665 case EL_KAEFER_R: return(GFX_KAEFER_R);
1666 case EL_KAEFER_O: return(GFX_KAEFER_O);
1667 case EL_KAEFER_L: return(GFX_KAEFER_L);
1668 case EL_KAEFER_U: return(GFX_KAEFER_U);
1669 case EL_FLIEGER: return(GFX_FLIEGER);
1670 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1671 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1672 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1673 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1674 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1675 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1676 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1677 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1678 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1679 case EL_FIREFLY: return(GFX_FIREFLY);
1680 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1681 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1682 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1683 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1684 case EL_MAMPFER: return(GFX_MAMPFER);
1685 case EL_ROBOT: return(GFX_ROBOT);
1686 case EL_BETON: return(GFX_BETON);
1687 case EL_DIAMANT: return(GFX_DIAMANT);
1688 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1689 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1690 case EL_TROPFEN: return(GFX_TROPFEN);
1691 case EL_BOMBE: return(GFX_BOMBE);
1692 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1693 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1694 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1695 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1696 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1697 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1698 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1699 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1700 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1701 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1702 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1703 case EL_LIFE: return(GFX_LIFE);
1704 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1705 case EL_DYNAMIT: return(GFX_DYNAMIT);
1706 case EL_BADEWANNE: return(GFX_BADEWANNE);
1707 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1708 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1709 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1710 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1711 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1712 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1713 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1714 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1715 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1716 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1717 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1718 case EL_PFORTE1: return(GFX_PFORTE1);
1719 case EL_PFORTE2: return(GFX_PFORTE2);
1720 case EL_PFORTE3: return(GFX_PFORTE3);
1721 case EL_PFORTE4: return(GFX_PFORTE4);
1722 case EL_PFORTE1X: return(GFX_PFORTE1X);
1723 case EL_PFORTE2X: return(GFX_PFORTE2X);
1724 case EL_PFORTE3X: return(GFX_PFORTE3X);
1725 case EL_PFORTE4X: return(GFX_PFORTE4X);
1726 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1727 case EL_PACMAN: return(GFX_PACMAN);
1728 case EL_PACMAN_R: return(GFX_PACMAN_R);
1729 case EL_PACMAN_O: return(GFX_PACMAN_O);
1730 case EL_PACMAN_L: return(GFX_PACMAN_L);
1731 case EL_PACMAN_U: return(GFX_PACMAN_U);
1732 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1733 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1734 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1735 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1736 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1737 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1738 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1739 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1740 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1741 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1742 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1743 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1744 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1745 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1746 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1747 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1748 case EL_MAMPFER2: return(GFX_MAMPFER2);
1749 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1750 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1751 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1752 case EL_DYNABOMB: return(GFX_DYNABOMB);
1753 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1754 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1755 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1756 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1757 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1758 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1759 case EL_MAULWURF: return(GFX_MAULWURF);
1760 case EL_PINGUIN: return(GFX_PINGUIN);
1761 case EL_SCHWEIN: return(GFX_SCHWEIN);
1762 case EL_DRACHE: return(GFX_DRACHE);
1763 case EL_SONDE: return(GFX_SONDE);
1764 case EL_PFEIL_L: return(GFX_PFEIL_L);
1765 case EL_PFEIL_R: return(GFX_PFEIL_R);
1766 case EL_PFEIL_O: return(GFX_PFEIL_O);
1767 case EL_PFEIL_U: return(GFX_PFEIL_U);
1770 if (IS_CHAR(element))
1771 return(GFX_CHAR_START + (element-EL_CHAR_START));