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>
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];
361 if (!player->active || player->gone || !IN_SCR_FIELD(sx,sy))
365 if (!player->active || player->gone ||
366 !IN_SCR_FIELD(SCREENX(last_jx),SCREENY(last_jy)))
370 if (!IN_LEV_FIELD(jx,jy))
372 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
373 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
374 printf("DrawPlayerField(): This should never happen!\n");
379 if (element == EL_EXPLODING)
382 /* draw things in the field the player is leaving, if needed */
384 if (last_jx != jx || last_jy != jy)
386 if (Store[last_jx][last_jy])
388 DrawLevelElement(last_jx,last_jy, Store[last_jx][last_jy]);
389 DrawLevelFieldThruMask(last_jx,last_jy);
391 else if (Feld[last_jx][last_jy] == EL_DYNAMIT)
392 DrawDynamite(last_jx,last_jy);
394 DrawLevelField(last_jx,last_jy);
396 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx),SCREENY(next_jy)))
400 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
401 DrawLevelElement(next_jx,next_jy, EL_SOKOBAN_FELD_LEER);
403 DrawLevelElement(next_jx,next_jy, EL_LEERRAUM);
406 DrawLevelField(next_jx,next_jy);
410 if (!IN_SCR_FIELD(sx,sy))
414 SetDrawtoField(DRAW_BUFFERED);
416 /* draw things behind the player, if needed */
419 DrawLevelElement(jx,jy, Store[jx][jy]);
420 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
421 DrawLevelField(jx,jy);
423 /* draw player himself */
425 if (player->MovDir==MV_LEFT)
426 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
427 else if (player->MovDir==MV_RIGHT)
428 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
429 else if (player->MovDir==MV_UP)
430 graphic = GFX_SPIELER1_UP;
431 else /* MV_DOWN || MV_NO_MOVING */
432 graphic = GFX_SPIELER1_DOWN;
434 graphic += player->index_nr * 3*HEROES_PER_LINE;
435 graphic += player->Frame;
439 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
440 sxx = player->GfxPos;
442 syy = player->GfxPos;
445 if (!soft_scrolling_on && ScreenMovPos)
448 DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING);
450 if (player->Pushing && player->GfxPos)
452 int px = SCREENX(next_jx), py = SCREENY(next_jy);
454 if (Feld[jx][jy] == EL_SOKOBAN_FELD_LEER ||
455 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
456 DrawGraphicShiftedThruMask(px,py,sxx,syy, GFX_SOKOBAN_OBJEKT,NO_CUTTING);
459 int element = Feld[next_jx][next_jy];
460 int graphic = el2gfx(element);
462 if (element == EL_FELSBROCKEN && sxx)
464 int phase = (player->GfxPos / (TILEX/4));
466 if (player->MovDir == MV_LEFT)
469 graphic += (phase+4)%4;
472 DrawGraphicShifted(px,py, sxx,syy, graphic, NO_CUTTING, NO_MASKING);
476 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
478 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
480 graphic = el2gfx(element);
482 if (element == EL_DYNAMIT)
484 if ((phase = (96-MovDelay[jx][jy])/12) > 6)
489 if ((phase = ((96-MovDelay[jx][jy])/6) % 8) > 3)
493 DrawGraphicThruMask(sx,sy, graphic + phase);
496 if ((last_jx != jx || last_jy != jy) && Feld[last_jx][last_jy]==EL_EXPLODING)
498 int phase = Frame[last_jx][last_jy];
502 DrawGraphicThruMask(SCREENX(last_jx),SCREENY(last_jy),
503 GFX_EXPLOSION + ((phase-1)/delay-1));
508 int dest_x = SX + SCREENX(MIN(jx,last_jx))*TILEX;
509 int dest_y = SY + SCREENY(MIN(jy,last_jy))*TILEY;
510 int x_size = TILEX * (1 + ABS(jx - last_jx));
511 int y_size = TILEY * (1 + ABS(jy - last_jy));
513 XCopyArea(display,drawto_field,window,gc,
514 dest_x,dest_y, x_size,y_size, dest_x,dest_y);
515 SetDrawtoField(DRAW_DIRECT);
518 MarkTileDirty(sx,sy);
521 static int getGraphicAnimationPhase(int frames, int delay, int mode)
525 if (mode == ANIM_OSCILLATE)
527 int max_anim_frames = frames*2 - 2;
528 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
529 phase = (phase < frames ? phase : max_anim_frames - phase);
532 phase = (FrameCounter % (delay * frames)) / delay;
534 if (mode == ANIM_REVERSE)
540 void DrawGraphicAnimationExt(int x, int y, int graphic,
541 int frames, int delay, int mode, int mask_mode)
543 int phase = getGraphicAnimationPhase(frames, delay, mode);
545 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
547 if (mask_mode == USE_MASKING)
548 DrawGraphicThruMask(SCREENX(x),SCREENY(y), graphic + phase);
550 DrawGraphic(SCREENX(x),SCREENY(y), graphic + phase);
554 void DrawGraphicAnimation(int x, int y, int graphic,
555 int frames, int delay, int mode)
557 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, NO_MASKING);
560 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
561 int frames, int delay, int mode)
563 DrawGraphicAnimationExt(x,y, graphic, frames,delay,mode, USE_MASKING);
566 void DrawGraphic(int x, int y, int graphic)
569 if (!IN_SCR_FIELD(x,y))
571 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
572 printf("DrawGraphic(): This should never happen!\n");
577 DrawGraphicExt(drawto_field, gc, FX+x*TILEX, FY+y*TILEY, graphic);
581 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
583 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
585 graphic -= GFX_START_ROCKSSCREEN;
586 XCopyArea(display,pix[PIX_BACK],d,gc,
587 SX + (graphic % GFX_PER_LINE) * TILEX,
588 SY + (graphic / GFX_PER_LINE) * TILEY,
591 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
593 graphic -= GFX_START_ROCKSHEROES;
594 XCopyArea(display,pix[PIX_HEROES],d,gc,
595 (graphic % HEROES_PER_LINE) * TILEX,
596 (graphic / HEROES_PER_LINE) * TILEY,
599 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
601 graphic -= GFX_START_ROCKSFONT;
602 XCopyArea(display,pix[PIX_BIGFONT],d,gc,
603 (graphic % FONT_CHARS_PER_LINE) * TILEX,
604 (graphic / FONT_CHARS_PER_LINE) * TILEY +
605 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
609 XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
612 void DrawGraphicThruMask(int x, int y, int graphic)
615 if (!IN_SCR_FIELD(x,y))
617 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
618 printf("DrawGraphicThruMask(): This should never happen!\n");
623 DrawGraphicThruMaskExt(drawto_field, FX+x*TILEX, FY+y*TILEY, graphic);
627 void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
634 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
636 src_pixmap = pix[PIX_BACK];
637 drawing_gc = clip_gc[PIX_BACK];
638 graphic -= GFX_START_ROCKSSCREEN;
639 src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
640 src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
642 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
644 src_pixmap = pix[PIX_HEROES];
645 drawing_gc = clip_gc[PIX_HEROES];
646 graphic -= GFX_START_ROCKSHEROES;
647 src_x = (graphic % HEROES_PER_LINE)*TILEX;
648 src_y = (graphic / HEROES_PER_LINE)*TILEY;
652 DrawGraphicExt(d, gc, dest_x,dest_y, graphic);
656 if (tile_clipmask[tile] != None)
658 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
659 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
660 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
661 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
666 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
669 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
670 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
671 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
675 void DrawMiniGraphic(int x, int y, int graphic)
677 DrawMiniGraphicExt(drawto,gc, SX+x*MINI_TILEX,SY+y*MINI_TILEY, graphic);
678 MarkTileDirty(x/2, y/2);
681 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
683 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
685 graphic -= GFX_START_ROCKSSCREEN;
686 XCopyArea(display,pix[PIX_BACK],d,gc,
687 MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
688 MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
689 MINI_TILEX,MINI_TILEY, x,y);
691 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
693 graphic -= GFX_START_ROCKSFONT;
694 XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
695 (graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
696 (graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
697 FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
698 MINI_TILEX,MINI_TILEY, x,y);
701 XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
704 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
705 int cut_mode, int mask_mode)
707 int width = TILEX, height = TILEY;
709 int src_x,src_y, dest_x,dest_y;
716 DrawGraphic(x,y,graphic);
720 if (dx || dy) /* Verschiebung der Grafik? */
722 if (x < BX1) /* Element kommt von links ins Bild */
729 else if (x > BX2) /* Element kommt von rechts ins Bild */
735 else if (x==BX1 && dx<0) /* Element verläßt links das Bild */
741 else if (x==BX2 && dx>0) /* Element verläßt rechts das Bild */
743 else if (dx) /* allg. Bewegung in x-Richtung */
744 MarkTileDirty(x + SIGN(dx), y);
746 if (y < BY1) /* Element kommt von oben ins Bild */
748 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
756 else if (y > BY2) /* Element kommt von unten ins Bild */
762 else if (y==BY1 && dy<0) /* Element verläßt oben das Bild */
768 else if (dy > 0 && cut_mode==CUT_ABOVE)
770 if (y == BY2) /* Element unterhalb des Bildes */
776 MarkTileDirty(x, y + 1);
777 } /* Element verläßt unten das Bild */
778 else if (dy > 0 && (y == BY2 || cut_mode==CUT_BELOW))
780 else if (dy) /* allg. Bewegung in y-Richtung */
781 MarkTileDirty(x, y + SIGN(dy));
784 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
786 src_pixmap = pix[PIX_BACK];
787 drawing_gc = clip_gc[PIX_BACK];
788 graphic -= GFX_START_ROCKSSCREEN;
789 src_x = SX+(graphic % GFX_PER_LINE)*TILEX+cx;
790 src_y = SY+(graphic / GFX_PER_LINE)*TILEY+cy;
792 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
794 src_pixmap = pix[PIX_HEROES];
795 drawing_gc = clip_gc[PIX_HEROES];
796 graphic -= GFX_START_ROCKSHEROES;
797 src_x = (graphic % HEROES_PER_LINE)*TILEX+cx;
798 src_y = (graphic / HEROES_PER_LINE)*TILEY+cy;
801 dest_x = FX + x*TILEX + dx;
802 dest_y = FY + y*TILEY + dy;
805 if (!IN_SCR_FIELD(x,y))
807 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
808 printf("DrawGraphicShifted(): This should never happen!\n");
813 if (mask_mode == USE_MASKING)
815 if (tile_clipmask[tile] != None)
817 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
818 XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y);
819 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
820 src_x,src_y, TILEX,TILEY, dest_x,dest_y);
825 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
828 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
829 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
830 src_x,src_y, width,height, dest_x,dest_y);
834 XCopyArea(display, src_pixmap, drawto_field, gc,
835 src_x,src_y, width,height, dest_x,dest_y);
840 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
843 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
846 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
847 int cut_mode, int mask_mode)
849 int ux = LEVELX(x), uy = LEVELY(y);
850 int graphic = el2gfx(element);
851 int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
852 int phase = phase4 / 2;
853 int dir = MovDir[ux][uy];
855 if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
861 else if (dir == MV_LEFT)
863 else if (dir == MV_DOWN)
866 else if (element==EL_MAULWURF || element==EL_PINGUIN ||
867 element==EL_SCHWEIN || element==EL_DRACHE)
870 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
871 element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
872 element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
873 else if (dir==MV_RIGHT)
874 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
875 element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
876 element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
878 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
879 element==EL_PINGUIN ? GFX_PINGUIN_UP :
880 element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
882 graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
883 element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
884 element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
888 else if (element==EL_SONDE)
890 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
892 else if (element==EL_SALZSAEURE)
894 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
896 else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
900 else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
902 graphic += phase * (element==EL_FELSBROCKEN ? 2 : 1);
904 else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
905 element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
907 graphic += 3-(SiebAktiv%8)/2;
909 else if (IS_AMOEBOID(element))
911 graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
912 graphic += (x+2*y) % 4;
914 else if (element==EL_MAUER_LEBT)
916 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
918 if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
920 if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
921 rechts_massiv = TRUE;
923 if (links_massiv && rechts_massiv)
924 graphic = GFX_MAUERWERK;
925 else if (links_massiv)
926 graphic = GFX_MAUER_R;
927 else if (rechts_massiv)
928 graphic = GFX_MAUER_L;
932 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, mask_mode);
933 else if (mask_mode == USE_MASKING)
934 DrawGraphicThruMask(x,y, graphic);
936 DrawGraphic(x,y, graphic);
939 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
940 int cut_mode, int mask_mode)
942 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
943 DrawScreenElementExt(SCREENX(x),SCREENY(y), dx,dy, element,
944 cut_mode, mask_mode);
947 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
950 DrawScreenElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
953 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
956 DrawLevelElementExt(x,y, dx,dy, element, cut_mode, NO_MASKING);
959 void DrawScreenElementThruMask(int x, int y, int element)
961 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
964 void DrawLevelElementThruMask(int x, int y, int element)
966 DrawLevelElementExt(x,y, 0,0, element, NO_CUTTING, USE_MASKING);
969 void DrawLevelFieldThruMask(int x, int y)
971 DrawLevelElementExt(x,y, 0,0, Feld[x][y], NO_CUTTING, USE_MASKING);
974 void ErdreichAnbroeckeln(int x, int y)
976 int i, width, height, cx,cy;
977 int ux = LEVELX(x), uy = LEVELY(y);
978 int element, graphic;
980 static int xy[4][2] =
988 if (!IN_LEV_FIELD(ux,uy))
991 element = Feld[ux][uy];
993 if (element==EL_ERDREICH)
995 if (!IN_SCR_FIELD(x,y))
998 graphic = GFX_ERDENRAND;
1006 if (!IN_LEV_FIELD(uxx,uyy))
1009 element = Feld[uxx][uyy];
1011 if (element==EL_ERDREICH)
1018 cx = (i==2 ? TILEX-snip : 0);
1026 cy = (i==3 ? TILEY-snip : 0);
1029 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1030 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1031 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1032 width,height, FX+x*TILEX+cx,FY+y*TILEY+cy);
1039 graphic = GFX_ERDENRAND;
1050 if (!IN_LEV_FIELD(uxx,uyy) || Feld[uxx][uyy]!=EL_ERDREICH ||
1051 !IN_SCR_FIELD(xx,yy))
1058 cx = (i==1 ? TILEX-snip : 0);
1066 cy = (i==0 ? TILEY-snip : 0);
1069 XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
1070 SX+(graphic % GFX_PER_LINE)*TILEX+cx,
1071 SY+(graphic / GFX_PER_LINE)*TILEY+cy,
1072 width,height, FX+xx*TILEX+cx,FY+yy*TILEY+cy);
1074 MarkTileDirty(xx,yy);
1079 void DrawScreenElement(int x, int y, int element)
1081 DrawScreenElementExt(x,y, 0,0, element, NO_CUTTING, NO_MASKING);
1082 ErdreichAnbroeckeln(x,y);
1085 void DrawLevelElement(int x, int y, int element)
1087 if (IN_LEV_FIELD(x,y) && IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1088 DrawScreenElement(SCREENX(x),SCREENY(y),element);
1091 void DrawScreenField(int x, int y)
1093 int ux = LEVELX(x), uy = LEVELY(y);
1096 if (!IN_LEV_FIELD(ux,uy))
1098 DrawScreenElement(x,y,EL_BETON);
1102 element = Feld[ux][uy];
1104 if (IS_MOVING(ux,uy))
1106 int horiz_move = (MovDir[ux][uy]==MV_LEFT || MovDir[ux][uy]==MV_RIGHT);
1107 BOOL cut_mode = NO_CUTTING;
1109 if (Store[ux][uy]==EL_MORAST_LEER ||
1110 Store[ux][uy]==EL_SIEB_LEER ||
1111 Store[ux][uy]==EL_SIEB2_LEER ||
1112 Store[ux][uy]==EL_AMOEBE_NASS)
1113 cut_mode = CUT_ABOVE;
1114 else if (Store[ux][uy]==EL_MORAST_VOLL ||
1115 Store[ux][uy]==EL_SIEB_VOLL ||
1116 Store[ux][uy]==EL_SIEB2_VOLL)
1117 cut_mode = CUT_BELOW;
1119 if (cut_mode==CUT_ABOVE)
1120 DrawScreenElementShifted(x,y, 0,0, Store[ux][uy], NO_CUTTING);
1122 DrawScreenElement(x,y,EL_LEERRAUM);
1125 DrawScreenElementShifted(x,y, MovPos[ux][uy],0, element, NO_CUTTING);
1127 DrawScreenElementShifted(x,y, 0,MovPos[ux][uy], element, cut_mode);
1129 if (Store[ux][uy] == EL_SALZSAEURE)
1130 DrawLevelElementThruMask(ux,uy+1, EL_SALZSAEURE);
1132 else if (IS_BLOCKED(ux,uy))
1137 BOOL cut_mode = NO_CUTTING;
1139 Blocked2Moving(ux,uy,&oldx,&oldy);
1142 horiz_move = (MovDir[oldx][oldy]==MV_LEFT || MovDir[oldx][oldy]==MV_RIGHT);
1144 if (Store[oldx][oldy]==EL_MORAST_LEER ||
1145 Store[oldx][oldy]==EL_SIEB_LEER ||
1146 Store[oldx][oldy]==EL_SIEB2_LEER ||
1147 Store[oldx][oldy]==EL_AMOEBE_NASS)
1148 cut_mode = CUT_ABOVE;
1150 DrawScreenElement(x,y,EL_LEERRAUM);
1151 element = Feld[oldx][oldy];
1154 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1156 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1158 else if (IS_DRAWABLE(element))
1159 DrawScreenElement(x,y,element);
1161 DrawScreenElement(x,y,EL_LEERRAUM);
1164 void DrawLevelField(int x, int y)
1166 if (IN_SCR_FIELD(SCREENX(x),SCREENY(y)))
1167 DrawScreenField(SCREENX(x),SCREENY(y));
1168 else if (IS_MOVING(x,y))
1172 Moving2Blocked(x,y,&newx,&newy);
1173 if (IN_SCR_FIELD(SCREENX(newx),SCREENY(newy)))
1174 DrawScreenField(SCREENX(newx),SCREENY(newy));
1176 else if (IS_BLOCKED(x,y))
1180 Blocked2Moving(x,y,&oldx,&oldy);
1181 if (IN_SCR_FIELD(SCREENX(oldx),SCREENY(oldy)))
1182 DrawScreenField(SCREENX(oldx),SCREENY(oldy));
1186 void DrawMiniElement(int x, int y, int element)
1192 DrawMiniGraphic(x,y,-1);
1196 graphic = el2gfx(element);
1197 DrawMiniGraphic(x,y,graphic);
1200 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1202 int x = sx + scroll_x, y = sy + scroll_y;
1204 if (x<-1 || x>lev_fieldx || y<-1 || y>lev_fieldy)
1205 DrawMiniElement(sx,sy,EL_LEERRAUM);
1206 else if (x==-1 || x==lev_fieldx || y==-1 || y==lev_fieldy)
1207 DrawMiniElement(sx,sy,EL_BETON);
1209 DrawMiniElement(sx,sy,Feld[x][y]);
1212 void DrawMicroElement(int xpos, int ypos, int element)
1216 if (element==EL_LEERRAUM)
1219 graphic = el2gfx(element);
1221 XCopyArea(display,pix[PIX_BACK],drawto,gc,
1222 MICRO_GFX_STARTX+(graphic % MICRO_GFX_PER_LINE)*MICRO_TILEX,
1223 MICRO_GFX_STARTY+(graphic / MICRO_GFX_PER_LINE)*MICRO_TILEY,
1224 MICRO_TILEX,MICRO_TILEY, xpos,ypos);
1233 for(x=BX1; x<=BX2; x++)
1234 for(y=BY1; y<=BY2; y++)
1235 DrawScreenField(x,y);
1237 if (soft_scrolling_on)
1238 XCopyArea(display,fieldbuffer,backbuffer,gc,
1239 FX,FY, SXSIZE,SYSIZE,
1242 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1245 void DrawMiniLevel(int scroll_x, int scroll_y)
1251 for(x=0;x<2*SCR_FIELDX;x++)
1252 for(y=0;y<2*SCR_FIELDY;y++)
1253 DrawMiniElementOrWall(x,y,scroll_x,scroll_y);
1255 redraw_mask |= REDRAW_FIELD;
1258 void DrawMicroLevel(int xpos, int ypos)
1262 XFillRectangle(display,drawto,gc,
1263 xpos-MICRO_TILEX,ypos-MICRO_TILEY,
1264 MICRO_TILEX*(STD_LEV_FIELDX+2),
1265 MICRO_TILEY*(STD_LEV_FIELDY+2));
1266 if (lev_fieldx < STD_LEV_FIELDX)
1267 xpos += (STD_LEV_FIELDX - lev_fieldx)/2 * MICRO_TILEX;
1268 if (lev_fieldy < STD_LEV_FIELDY)
1269 ypos += (STD_LEV_FIELDY - lev_fieldy)/2 * MICRO_TILEY;
1271 for(x=-1;x<=STD_LEV_FIELDX;x++)
1272 for(y=-1;y<=STD_LEV_FIELDY;y++)
1273 if (x>=0 && x<lev_fieldx && y>=0 && y<lev_fieldy)
1274 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1275 Feld[x][y]=Ur[x][y]);
1276 else if (x>=-1 && x<lev_fieldx+1 && y>=-1 && y<lev_fieldy+1)
1277 DrawMicroElement(xpos+MICRO_TILEX*x,ypos+MICRO_TILEY*y,
1280 XFillRectangle(display,drawto,gc, SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE);
1284 int len = strlen(level.name);
1285 int lxpos = SX+(SXSIZE-len*FONT4_XSIZE)/2;
1286 int lypos = MICROLABEL_YPOS;
1288 DrawText(lxpos,lypos,level.name,FS_SMALL,FC_SPECIAL2);
1291 redraw_mask |= REDRAW_MICROLEV;
1294 int REQ_in_range(int x, int y)
1296 if (y>DY+249 && y<DY+278)
1298 if (x>DX+1 && x<DX+48)
1300 else if (x>DX+51 && x<DX+98)
1306 BOOL Request(char *text, unsigned int req_state)
1308 int mx,my, ty, result = -1;
1309 unsigned int old_door_state;
1311 /* pause network game while waiting for request to answer */
1312 if (network && game_status == PLAYING && req_state & REQUEST_WAIT_FOR)
1313 SendToServer_PausePlaying();
1315 old_door_state = GetDoorState();
1317 CloseDoor(DOOR_CLOSE_1);
1319 /* Alten Türinhalt sichern */
1320 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1321 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1322 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1);
1324 /* Fragetext schreiben */
1325 XFillRectangle(display,pix[PIX_DB_DOOR],gc,
1326 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1,DXSIZE,DYSIZE);
1328 for(ty=0;ty<13;ty++)
1335 for(tl=0,tx=0;tx<7;tl++,tx++)
1349 DrawTextExt(pix[PIX_DB_DOOR],gc,
1350 DOOR_GFX_PAGEX1+51-(tl*14)/2,SY+ty*16,txt,FS_SMALL,FC_YELLOW);
1351 text+=(tl+(tc==32));
1354 if (req_state & REQ_ASK)
1356 DrawYesNoButton(BUTTON_OK, DB_INIT);
1357 DrawYesNoButton(BUTTON_NO, DB_INIT);
1359 else if (req_state & REQ_CONFIRM)
1361 DrawConfirmButton(BUTTON_CONFIRM, DB_INIT);
1363 else if (req_state & REQ_PLAYER)
1365 DrawPlayerButton(BUTTON_PLAYER_1, DB_INIT);
1366 DrawPlayerButton(BUTTON_PLAYER_2, DB_INIT);
1367 DrawPlayerButton(BUTTON_PLAYER_3, DB_INIT);
1368 DrawPlayerButton(BUTTON_PLAYER_4, DB_INIT);
1371 OpenDoor(DOOR_OPEN_1);
1374 if (!(req_state & REQUEST_WAIT_FOR))
1377 if (game_status != MAINMENU)
1380 button_status = MB_RELEASED;
1387 if (XPending(display))
1391 XNextEvent(display, &event);
1395 HandleExposeEvent((XExposeEvent *) &event);
1398 SleepWhileUnmapped();
1406 if (event.type == MotionNotify)
1408 motion_status = TRUE;
1409 mx = ((XMotionEvent *) &event)->x;
1410 my = ((XMotionEvent *) &event)->y;
1414 motion_status = FALSE;
1415 mx = ((XButtonEvent *) &event)->x;
1416 my = ((XButtonEvent *) &event)->y;
1417 if (event.type==ButtonPress)
1418 button_status = ((XButtonEvent *) &event)->button;
1420 button_status = MB_RELEASED;
1423 if (req_state & REQ_ASK)
1424 choice = CheckYesNoButtons(mx,my,button_status);
1425 else if (req_state & REQ_CONFIRM)
1426 choice = CheckConfirmButton(mx,my,button_status);
1428 choice = CheckPlayerButtons(mx,my,button_status);
1438 case BUTTON_CONFIRM:
1439 result = TRUE | FALSE;
1441 case BUTTON_PLAYER_1:
1444 case BUTTON_PLAYER_2:
1447 case BUTTON_PLAYER_3:
1450 case BUTTON_PLAYER_4:
1459 switch(XLookupKeysym((XKeyEvent *)&event,
1460 ((XKeyEvent *)&event)->state))
1469 if (req_state & REQ_PLAYER)
1473 key_joystick_mapping = 0;
1477 HandleFocusEvent((XFocusChangeEvent *) &event);
1480 HandleClientMessageEvent((XClientMessageEvent *) &event);
1486 else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED)
1490 if (joy & JOY_BUTTON_1)
1492 else if (joy & JOY_BUTTON_2)
1497 if (game_status != MAINMENU)
1500 if (!(req_state & REQ_STAY_OPEN))
1502 CloseDoor(DOOR_CLOSE_1);
1504 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1506 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1507 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1508 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1509 OpenDoor(DOOR_OPEN_1);
1513 /* continue network game after request */
1514 if (network && game_status == PLAYING && req_state & REQUEST_WAIT_FOR)
1515 SendToServer_ContinuePlaying();
1520 unsigned int OpenDoor(unsigned int door_state)
1522 unsigned int new_door_state;
1524 if (door_state & DOOR_COPY_BACK)
1526 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1527 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE+VYSIZE,
1528 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1529 door_state &= ~DOOR_COPY_BACK;
1532 new_door_state = MoveDoor(door_state);
1534 return(new_door_state);
1537 unsigned int CloseDoor(unsigned int door_state)
1539 unsigned int new_door_state;
1541 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1542 DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1543 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,
1544 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1546 new_door_state = MoveDoor(door_state);
1548 return(new_door_state);
1551 unsigned int GetDoorState()
1553 return(MoveDoor(DOOR_GET_STATE));
1556 unsigned int MoveDoor(unsigned int door_state)
1558 static unsigned int door1 = DOOR_OPEN_1;
1559 static unsigned int door2 = DOOR_CLOSE_2;
1560 static long door_delay = 0;
1561 int x, start, stepsize = 2;
1562 long door_delay_value = stepsize * 5;
1564 if (door_state == DOOR_GET_STATE)
1565 return(door1 | door2);
1567 if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1568 door_state &= ~DOOR_OPEN_1;
1569 else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1570 door_state &= ~DOOR_CLOSE_1;
1571 if (door2==DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1572 door_state &= ~DOOR_OPEN_2;
1573 else if (door2==DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1574 door_state &= ~DOOR_CLOSE_2;
1579 door_delay_value = 0;
1580 StopSound(SND_OEFFNEN);
1583 if (door_state & DOOR_ACTION)
1585 if (!(door_state & DOOR_NO_DELAY))
1586 PlaySoundStereo(SND_OEFFNEN,PSND_MAX_RIGHT);
1588 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1590 for(x=start; x<=DXSIZE; x+=stepsize)
1592 WaitUntilDelayReached(&door_delay, door_delay_value);
1594 if (door_state & DOOR_ACTION_1)
1596 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1597 int j = (DXSIZE - i)/3;
1599 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1600 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1+i/2,
1601 DXSIZE,DYSIZE-i/2, DX,DY);
1603 XFillRectangle(display,drawto,gc,DX,DY+DYSIZE-i/2,DXSIZE,i/2);
1605 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1606 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1607 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1608 DXSIZE,DOOR_GFX_PAGEY1, i,77, DX+DXSIZE-i,DY+j);
1609 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1610 DXSIZE,DOOR_GFX_PAGEY1+140, i,63, DX+DXSIZE-i,DY+140+j);
1611 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1612 DX-DXSIZE+i,DY-(DOOR_GFX_PAGEY1+j));
1613 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1614 DXSIZE-i,DOOR_GFX_PAGEY1+j, i,77-j, DX,DY);
1615 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1616 DXSIZE-i,DOOR_GFX_PAGEY1+140, i,63, DX,DY+140-j);
1618 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1619 DXSIZE-i,DOOR_GFX_PAGEY1+77, i,63,
1621 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1622 DXSIZE-i,DOOR_GFX_PAGEY1+203, i,77,
1624 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1625 DX-i,(DY+j)-DOOR_GFX_PAGEY1);
1626 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1627 DXSIZE,DOOR_GFX_PAGEY1+77, i,63,
1628 DX+DXSIZE-i,DY+77+j);
1629 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1630 DXSIZE,DOOR_GFX_PAGEY1+203, i,77-j,
1631 DX+DXSIZE-i,DY+203+j);
1633 redraw_mask |= REDRAW_DOOR_1;
1636 if (door_state & DOOR_ACTION_2)
1638 int i = (door_state & DOOR_OPEN_2 ? VXSIZE-x : x);
1639 int j = (VXSIZE - i)/3;
1641 XCopyArea(display,pix[PIX_DB_DOOR],drawto,gc,
1642 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2+i/2,
1643 VXSIZE,VYSIZE-i/2, VX,VY);
1645 XFillRectangle(display,drawto,gc,VX,VY+VYSIZE-i/2,VXSIZE,i/2);
1647 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1648 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1649 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1650 VXSIZE,DOOR_GFX_PAGEY2, i,VYSIZE/2, VX+VXSIZE-i,VY+j);
1651 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1652 VX-VXSIZE+i,VY-(DOOR_GFX_PAGEY2+j));
1653 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1654 VXSIZE-i,DOOR_GFX_PAGEY2+j, i,VYSIZE/2-j, VX,VY);
1656 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1657 VXSIZE-i,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2,
1659 XSetClipOrigin(display,clip_gc[PIX_DOOR],
1660 VX-i,(VY+j)-DOOR_GFX_PAGEY2);
1661 XCopyArea(display,pix[PIX_DOOR],drawto,clip_gc[PIX_DOOR],
1662 VXSIZE,DOOR_GFX_PAGEY2+VYSIZE/2, i,VYSIZE/2-j,
1663 VX+VXSIZE-i,VY+VYSIZE/2+j);
1665 redraw_mask |= REDRAW_DOOR_2;
1670 if (game_status == MAINMENU)
1675 if (door_state & DOOR_ACTION_1)
1676 door1 = door_state & DOOR_ACTION_1;
1677 if (door_state & DOOR_ACTION_2)
1678 door2 = door_state & DOOR_ACTION_2;
1680 return(door1 | door2);
1683 int ReadPixel(Drawable d, int x, int y)
1685 static XImage *pixelimage;
1687 pixelimage = XGetImage(display, d, x,y, 1,1, AllPlanes, ZPixmap);
1688 return(XGetPixel(pixelimage,0,0));
1691 int el2gfx(int element)
1695 case EL_LEERRAUM: return(-1);
1696 case EL_ERDREICH: return(GFX_ERDREICH);
1697 case EL_MAUERWERK: return(GFX_MAUERWERK);
1698 case EL_FELSBODEN: return(GFX_FELSBODEN);
1699 case EL_FELSBROCKEN: return(GFX_FELSBROCKEN);
1700 case EL_SCHLUESSEL: return(GFX_SCHLUESSEL);
1701 case EL_EDELSTEIN: return(GFX_EDELSTEIN);
1702 case EL_AUSGANG_ZU: return(GFX_AUSGANG_ZU);
1703 case EL_AUSGANG_ACT: return(GFX_AUSGANG_ACT);
1704 case EL_AUSGANG_AUF: return(GFX_AUSGANG_AUF);
1705 case EL_SPIELFIGUR: return(GFX_SPIELFIGUR);
1706 case EL_SPIELER1: return(GFX_SPIELER1);
1707 case EL_SPIELER2: return(GFX_SPIELER2);
1708 case EL_SPIELER3: return(GFX_SPIELER3);
1709 case EL_SPIELER4: return(GFX_SPIELER4);
1710 case EL_KAEFER: return(GFX_KAEFER);
1711 case EL_KAEFER_R: return(GFX_KAEFER_R);
1712 case EL_KAEFER_O: return(GFX_KAEFER_O);
1713 case EL_KAEFER_L: return(GFX_KAEFER_L);
1714 case EL_KAEFER_U: return(GFX_KAEFER_U);
1715 case EL_FLIEGER: return(GFX_FLIEGER);
1716 case EL_FLIEGER_R: return(GFX_FLIEGER_R);
1717 case EL_FLIEGER_O: return(GFX_FLIEGER_O);
1718 case EL_FLIEGER_L: return(GFX_FLIEGER_L);
1719 case EL_FLIEGER_U: return(GFX_FLIEGER_U);
1720 case EL_BUTTERFLY: return(GFX_BUTTERFLY);
1721 case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R);
1722 case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O);
1723 case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L);
1724 case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U);
1725 case EL_FIREFLY: return(GFX_FIREFLY);
1726 case EL_FIREFLY_R: return(GFX_FIREFLY_R);
1727 case EL_FIREFLY_O: return(GFX_FIREFLY_O);
1728 case EL_FIREFLY_L: return(GFX_FIREFLY_L);
1729 case EL_FIREFLY_U: return(GFX_FIREFLY_U);
1730 case EL_MAMPFER: return(GFX_MAMPFER);
1731 case EL_ROBOT: return(GFX_ROBOT);
1732 case EL_BETON: return(GFX_BETON);
1733 case EL_DIAMANT: return(GFX_DIAMANT);
1734 case EL_MORAST_LEER: return(GFX_MORAST_LEER);
1735 case EL_MORAST_VOLL: return(GFX_MORAST_VOLL);
1736 case EL_TROPFEN: return(GFX_TROPFEN);
1737 case EL_BOMBE: return(GFX_BOMBE);
1738 case EL_SIEB_LEER: return(GFX_SIEB_LEER);
1739 case EL_SIEB_VOLL: return(GFX_SIEB_VOLL);
1740 case EL_SIEB_TOT: return(GFX_SIEB_TOT);
1741 case EL_SALZSAEURE: return(GFX_SALZSAEURE);
1742 case EL_AMOEBE_TOT: return(GFX_AMOEBE_TOT);
1743 case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS);
1744 case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM);
1745 case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL);
1746 case EL_AMOEBE_BD: return(GFX_AMOEBE_BD);
1747 case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM);
1748 case EL_KOKOSNUSS: return(GFX_KOKOSNUSS);
1749 case EL_LIFE: return(GFX_LIFE);
1750 case EL_LIFE_ASYNC: return(GFX_LIFE_ASYNC);
1751 case EL_DYNAMIT: return(GFX_DYNAMIT);
1752 case EL_BADEWANNE: return(GFX_BADEWANNE);
1753 case EL_BADEWANNE1: return(GFX_BADEWANNE1);
1754 case EL_BADEWANNE2: return(GFX_BADEWANNE2);
1755 case EL_BADEWANNE3: return(GFX_BADEWANNE3);
1756 case EL_BADEWANNE4: return(GFX_BADEWANNE4);
1757 case EL_BADEWANNE5: return(GFX_BADEWANNE5);
1758 case EL_ABLENK_AUS: return(GFX_ABLENK_AUS);
1759 case EL_ABLENK_EIN: return(GFX_ABLENK_EIN);
1760 case EL_SCHLUESSEL1: return(GFX_SCHLUESSEL1);
1761 case EL_SCHLUESSEL2: return(GFX_SCHLUESSEL2);
1762 case EL_SCHLUESSEL3: return(GFX_SCHLUESSEL3);
1763 case EL_SCHLUESSEL4: return(GFX_SCHLUESSEL4);
1764 case EL_PFORTE1: return(GFX_PFORTE1);
1765 case EL_PFORTE2: return(GFX_PFORTE2);
1766 case EL_PFORTE3: return(GFX_PFORTE3);
1767 case EL_PFORTE4: return(GFX_PFORTE4);
1768 case EL_PFORTE1X: return(GFX_PFORTE1X);
1769 case EL_PFORTE2X: return(GFX_PFORTE2X);
1770 case EL_PFORTE3X: return(GFX_PFORTE3X);
1771 case EL_PFORTE4X: return(GFX_PFORTE4X);
1772 case EL_DYNAMIT_AUS: return(GFX_DYNAMIT_AUS);
1773 case EL_PACMAN: return(GFX_PACMAN);
1774 case EL_PACMAN_R: return(GFX_PACMAN_R);
1775 case EL_PACMAN_O: return(GFX_PACMAN_O);
1776 case EL_PACMAN_L: return(GFX_PACMAN_L);
1777 case EL_PACMAN_U: return(GFX_PACMAN_U);
1778 case EL_UNSICHTBAR: return(GFX_UNSICHTBAR);
1779 case EL_ERZ_EDEL: return(GFX_ERZ_EDEL);
1780 case EL_ERZ_DIAM: return(GFX_ERZ_DIAM);
1781 case EL_BIRNE_AUS: return(GFX_BIRNE_AUS);
1782 case EL_BIRNE_EIN: return(GFX_BIRNE_EIN);
1783 case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL);
1784 case EL_ZEIT_LEER: return(GFX_ZEIT_LEER);
1785 case EL_MAUER_LEBT: return(GFX_MAUER_LEBT);
1786 case EL_MAUER_X: return(GFX_MAUER_X);
1787 case EL_MAUER_Y: return(GFX_MAUER_Y);
1788 case EL_MAUER_XY: return(GFX_MAUER_XY);
1789 case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD);
1790 case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB);
1791 case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT);
1792 case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA);
1793 case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD);
1794 case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB);
1795 case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT);
1796 case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA);
1797 case EL_MAMPFER2: return(GFX_MAMPFER2);
1798 case EL_SIEB2_LEER: return(GFX_SIEB2_LEER);
1799 case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL);
1800 case EL_SIEB2_TOT: return(GFX_SIEB2_TOT);
1801 case EL_DYNABOMB: return(GFX_DYNABOMB);
1802 case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR);
1803 case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ);
1804 case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL);
1805 case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT);
1806 case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER);
1807 case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL);
1808 case EL_MAULWURF: return(GFX_MAULWURF);
1809 case EL_PINGUIN: return(GFX_PINGUIN);
1810 case EL_SCHWEIN: return(GFX_SCHWEIN);
1811 case EL_DRACHE: return(GFX_DRACHE);
1812 case EL_SONDE: return(GFX_SONDE);
1813 case EL_PFEIL_L: return(GFX_PFEIL_L);
1814 case EL_PFEIL_R: return(GFX_PFEIL_R);
1815 case EL_PFEIL_O: return(GFX_PFEIL_O);
1816 case EL_PFEIL_U: return(GFX_PFEIL_U);
1819 if (IS_CHAR(element))
1820 return(GFX_CHAR_START + (element-EL_CHAR_START));