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 ***********************************************************/
17 #include <machine/joystick.h>
31 extern boolean wait_for_vsync;
34 void SetDrawtoField(int mode)
36 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
47 drawto_field = fieldbuffer;
49 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
60 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
67 Drawable buffer = (drawto_field == window ? backbuffer : drawto_field);
69 if (setup.direct_draw && 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)
76 redraw_mask &= ~REDRAW_TILES;
79 if (redraw_mask & REDRAW_FIELD ||
80 (ScreenGfxPos && setup.soft_scrolling && game_status == PLAYING))
81 redraw_mask &= ~REDRAW_TILES;
87 /* synchronize X11 graphics at this point; if we would synchronize the
88 display immediately after the buffer switching (after the XFlush),
89 this could mean that we have to wait for the graphics to complete,
90 although we could go on doing calculations for the next frame */
92 XSync(display, FALSE);
96 wait_for_vsync = TRUE;
100 if (redraw_mask & REDRAW_ALL)
102 XCopyArea(display,backbuffer,window,gc,
103 0,0, WIN_XSIZE,WIN_YSIZE,
108 if (redraw_mask & REDRAW_FIELD)
110 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
111 XCopyArea(display,backbuffer,window,gc,
112 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
116 int fx = FX, fy = FY;
118 if (setup.soft_scrolling)
120 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
121 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
124 if (setup.soft_scrolling ||
125 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
126 ABS(ScreenMovPos) == ScrollStepSize ||
127 redraw_tiles > REDRAWTILES_THRESHOLD)
129 XCopyArea(display, buffer, window, gc, fx, fy, SXSIZE, SYSIZE, SX, SY);
133 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
135 (setup.soft_scrolling ?
136 "setup.soft_scrolling" :
137 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
138 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
139 ABS(ScreenGfxPos) == ScrollStepSize ?
140 "ABS(ScreenGfxPos) == ScrollStepSize" :
141 "redraw_tiles > REDRAWTILES_THRESHOLD"));
146 redraw_mask &= ~REDRAW_MAIN;
149 if (redraw_mask & REDRAW_DOORS)
151 if (redraw_mask & REDRAW_DOOR_1)
152 XCopyArea(display,backbuffer,window,gc,
153 DX,DY, DXSIZE,DYSIZE,
155 if (redraw_mask & REDRAW_DOOR_2)
157 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
158 XCopyArea(display,backbuffer,window,gc,
159 VX,VY, VXSIZE,VYSIZE,
163 if (redraw_mask & REDRAW_VIDEO_1)
164 XCopyArea(display,backbuffer,window,gc,
165 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
166 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
167 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
168 if (redraw_mask & REDRAW_VIDEO_2)
169 XCopyArea(display,backbuffer,window,gc,
170 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
171 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
172 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
173 if (redraw_mask & REDRAW_VIDEO_3)
174 XCopyArea(display,backbuffer,window,gc,
175 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
176 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
177 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
180 if (redraw_mask & REDRAW_DOOR_3)
181 XCopyArea(display, backbuffer, window, gc,
182 EX, EY, EXSIZE, EYSIZE,
184 redraw_mask &= ~REDRAW_DOORS;
187 if (redraw_mask & REDRAW_MICROLEVEL)
189 XCopyArea(display,backbuffer,window,gc,
190 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
191 MICROLEV_XPOS, MICROLEV_YPOS);
192 XCopyArea(display,backbuffer,window,gc,
193 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
194 SX, MICROLABEL_YPOS);
195 redraw_mask &= ~REDRAW_MICROLEVEL;
198 if (redraw_mask & REDRAW_TILES)
200 for(x=0; x<SCR_FIELDX; x++)
201 for(y=0; y<SCR_FIELDY; y++)
202 if (redraw[redraw_x1 + x][redraw_y1 + y])
203 XCopyArea(display,buffer,window,gc,
204 FX+x*TILEX,FX+y*TILEY, TILEX,TILEY,
205 SX+x*TILEX,SY+y*TILEY);
210 for(x=0; x<MAX_BUF_XSIZE; x++)
211 for(y=0; y<MAX_BUF_YSIZE; y++)
220 long fading_delay = 300;
222 if (setup.fading && (redraw_mask & REDRAW_FIELD))
229 XFillRectangle(display,window,gc,
230 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
233 for(i=0;i<2*FULL_SYSIZE;i++)
235 for(y=0;y<FULL_SYSIZE;y++)
237 XCopyArea(display,backbuffer,window,gc,
238 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
246 for(i=1;i<FULL_SYSIZE;i+=2)
247 XCopyArea(display,backbuffer,window,gc,
248 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
254 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
255 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
256 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
260 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
261 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
262 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
266 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
267 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
268 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
272 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
273 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
274 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
278 redraw_mask &= ~REDRAW_MAIN;
287 XFillRectangle(display, backbuffer, gc,
288 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
290 if (setup.soft_scrolling && game_status == PLAYING)
292 XFillRectangle(display, fieldbuffer, gc, 0, 0, FXSIZE, FYSIZE);
293 SetDrawtoField(DRAW_BUFFERED);
296 SetDrawtoField(DRAW_BACKBUFFER);
298 if (setup.direct_draw && game_status == PLAYING)
300 XFillRectangle(display, window, gc,
301 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
302 SetDrawtoField(DRAW_DIRECT);
305 redraw_mask |= REDRAW_FIELD;
308 void DrawTextFCentered(int y, int font_type, char *format, ...)
310 char buffer[FULL_SXSIZE / FONT3_XSIZE + 10];
314 font_xsize = (font_type < FC_SPECIAL1 ? FONT2_XSIZE :
315 font_type < FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
317 va_start(ap, format);
318 vsprintf(buffer, format, ap);
321 DrawText(SX + (SXSIZE - strlen(buffer) * font_xsize) / 2, SY + y,
322 buffer, FS_SMALL, font_type);
325 void DrawTextF(int x, int y, int font_type, char *format, ...)
327 char buffer[FULL_SXSIZE / FONT3_XSIZE + 10];
330 va_start(ap, format);
331 vsprintf(buffer, format, ap);
334 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
337 void DrawText(int x, int y, char *text, int font_size, int font_type)
339 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
342 redraw_mask |= REDRAW_FIELD;
344 redraw_mask |= REDRAW_DOOR_1;
347 void DrawTextExt(Drawable d, GC gc, int x, int y,
348 char *text, int font_size, int font_type)
350 int font_width, font_height, font_start;
352 boolean print_inverse = FALSE;
354 if (font_size != FS_SMALL && font_size != FS_BIG)
355 font_size = FS_SMALL;
356 if (font_type < FC_RED || font_type > FC_SPECIAL2)
359 font_width = (font_size == FS_BIG ? FONT1_XSIZE :
360 font_type < FC_SPECIAL1 ? FONT2_XSIZE :
361 font_type < FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
362 font_height = (font_size == FS_BIG ? FONT1_XSIZE :
363 font_type < FC_SPECIAL2 ? FONT2_XSIZE : FONT4_XSIZE);
364 font_pixmap = (font_size == FS_BIG ? PIX_BIGFONT : PIX_SMALLFONT);
365 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE : FONT2_YSIZE) *
366 FONT_LINES_PER_FONT);
372 if (c == '~' && font_size == FS_SMALL && font_type <= FC_YELLOW)
374 print_inverse = TRUE;
378 if (c >= 'a' && c <= 'z')
380 else if (c == 'ä' || c == 'Ä')
382 else if (c == 'ö' || c == 'Ö')
384 else if (c == 'ü' || c == 'Ü')
387 if (c >= 32 && c <= 95)
389 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
390 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
391 int dest_x = x, dest_y = y;
395 XCopyArea(display, pix[font_pixmap], d, gc,
396 FONT_CHARS_PER_LINE * font_width,
397 3 * font_height + font_start,
398 font_width, font_height, x, y);
400 XSetClipOrigin(display, clip_gc[font_pixmap],
401 dest_x - src_x, dest_y - src_y);
402 XCopyArea(display, pix[font_pixmap], drawto, clip_gc[font_pixmap],
403 0, 0, font_width, font_height, dest_x, dest_y);
406 XCopyArea(display, pix[font_pixmap], d, gc,
407 src_x, src_y, font_width, font_height, dest_x, dest_y);
414 void DrawAllPlayers()
418 for(i=0; i<MAX_PLAYERS; i++)
419 if (stored_player[i].active)
420 DrawPlayer(&stored_player[i]);
423 void DrawPlayerField(int x, int y)
428 DrawPlayer(PLAYERINFO(x,y));
431 void DrawPlayer(struct PlayerInfo *player)
433 int jx = player->jx, jy = player->jy;
434 int last_jx = player->last_jx, last_jy = player->last_jy;
435 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
436 int sx = SCREENX(jx), sy = SCREENY(jy);
437 int sxx = 0, syy = 0;
438 int element = Feld[jx][jy];
441 if (!player->active || player->gone ||
442 !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
446 if (!IN_LEV_FIELD(jx,jy))
448 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
449 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
450 printf("DrawPlayerField(): This should never happen!\n");
455 if (element == EL_EXPLODING)
458 /* draw things in the field the player is leaving, if needed */
460 if (last_jx != jx || last_jy != jy)
462 if (Store[last_jx][last_jy])
464 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
465 DrawLevelFieldThruMask(last_jx, last_jy);
467 else if (Feld[last_jx][last_jy] == EL_DYNAMIT)
468 DrawDynamite(last_jx, last_jy);
470 DrawLevelField(last_jx, last_jy);
472 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
476 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
477 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
479 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
482 DrawLevelField(next_jx, next_jy);
486 if (!IN_SCR_FIELD(sx, sy))
489 if (setup.direct_draw)
490 SetDrawtoField(DRAW_BUFFERED);
492 /* draw things behind the player, if needed */
495 DrawLevelElement(jx, jy, Store[jx][jy]);
496 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
497 DrawLevelField(jx, jy);
499 /* draw player himself */
501 if (player->MovDir == MV_LEFT)
502 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
503 else if (player->MovDir == MV_RIGHT)
504 graphic = (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
505 else if (player->MovDir == MV_UP)
506 graphic = GFX_SPIELER1_UP;
507 else /* MV_DOWN || MV_NO_MOVING */
508 graphic = GFX_SPIELER1_DOWN;
510 graphic += player->index_nr * 3*HEROES_PER_LINE;
511 graphic += player->Frame;
515 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
516 sxx = player->GfxPos;
518 syy = player->GfxPos;
521 if (!setup.soft_scrolling && ScreenMovPos)
524 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
526 if (player->Pushing && player->GfxPos)
528 int px = SCREENX(next_jx), py = SCREENY(next_jy);
530 if (Feld[jx][jy] == EL_SOKOBAN_FELD_LEER ||
531 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
532 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
536 int element = Feld[next_jx][next_jy];
537 int graphic = el2gfx(element);
539 if (element == EL_FELSBROCKEN && sxx)
541 int phase = (player->GfxPos / (TILEX/4));
543 if (player->MovDir == MV_LEFT)
546 graphic += (phase+4)%4;
549 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
553 /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
555 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
557 graphic = el2gfx(element);
559 if (element == EL_DYNAMIT)
561 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
566 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
570 if (game_emulation == EMU_SUPAPLEX)
571 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
573 DrawGraphicThruMask(sx, sy, graphic + phase);
576 if ((last_jx != jx || last_jy != jy) &&
577 Feld[last_jx][last_jy] == EL_EXPLODING)
579 int phase = Frame[last_jx][last_jy];
583 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
584 GFX_EXPLOSION + ((phase - 1) / delay - 1));
587 if (setup.direct_draw)
589 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
590 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
591 int x_size = TILEX * (1 + ABS(jx - last_jx));
592 int y_size = TILEY * (1 + ABS(jy - last_jy));
594 XCopyArea(display, drawto_field, window, gc,
595 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
596 SetDrawtoField(DRAW_DIRECT);
599 MarkTileDirty(sx,sy);
602 static int getGraphicAnimationPhase(int frames, int delay, int mode)
606 if (mode == ANIM_OSCILLATE)
608 int max_anim_frames = 2 * frames - 2;
609 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
610 phase = (phase < frames ? phase : max_anim_frames - phase);
613 phase = (FrameCounter % (delay * frames)) / delay;
615 if (mode == ANIM_REVERSE)
621 void DrawGraphicAnimationExt(int x, int y, int graphic,
622 int frames, int delay, int mode, int mask_mode)
624 int phase = getGraphicAnimationPhase(frames, delay, mode);
626 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
628 if (mask_mode == USE_MASKING)
629 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
631 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
635 void DrawGraphicAnimation(int x, int y, int graphic,
636 int frames, int delay, int mode)
638 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
641 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
642 int frames, int delay, int mode)
644 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
647 void DrawGraphic(int x, int y, int graphic)
650 if (!IN_SCR_FIELD(x,y))
652 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
653 printf("DrawGraphic(): This should never happen!\n");
658 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
662 void DrawGraphicExt(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 SX + (graphic % GFX_PER_LINE) * TILEX,
669 SY + (graphic / GFX_PER_LINE) * TILEY,
672 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
674 graphic -= GFX_START_ROCKSMORE;
675 XCopyArea(display, pix[PIX_MORE], d, gc,
676 (graphic % MORE_PER_LINE) * TILEX,
677 (graphic / MORE_PER_LINE) * TILEY,
680 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
682 graphic -= GFX_START_ROCKSHEROES;
683 XCopyArea(display, pix[PIX_HEROES], d, gc,
684 (graphic % HEROES_PER_LINE) * TILEX,
685 (graphic / HEROES_PER_LINE) * TILEY,
688 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
690 graphic -= GFX_START_ROCKSFONT;
691 XCopyArea(display, pix[PIX_BIGFONT], d, gc,
692 (graphic % FONT_CHARS_PER_LINE) * TILEX,
693 (graphic / FONT_CHARS_PER_LINE) * TILEY +
694 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
698 XFillRectangle(display, d, gc, x, y, TILEX, TILEY);
701 void DrawGraphicThruMask(int x, int y, int graphic)
704 if (!IN_SCR_FIELD(x,y))
706 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
707 printf("DrawGraphicThruMask(): This should never happen!\n");
712 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
716 void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
723 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
725 src_pixmap = pix[PIX_BACK];
726 drawing_gc = clip_gc[PIX_BACK];
727 graphic -= GFX_START_ROCKSSCREEN;
728 src_x = SX + (graphic % GFX_PER_LINE) * TILEX;
729 src_y = SY + (graphic / GFX_PER_LINE) * TILEY;
731 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
733 src_pixmap = pix[PIX_MORE];
734 drawing_gc = clip_gc[PIX_MORE];
735 graphic -= GFX_START_ROCKSMORE;
736 src_x = (graphic % MORE_PER_LINE) * TILEX;
737 src_y = (graphic / MORE_PER_LINE) * TILEY;
739 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
741 src_pixmap = pix[PIX_HEROES];
742 drawing_gc = clip_gc[PIX_HEROES];
743 graphic -= GFX_START_ROCKSHEROES;
744 src_x = (graphic % HEROES_PER_LINE) * TILEX;
745 src_y = (graphic / HEROES_PER_LINE) * TILEY;
749 DrawGraphicExt(d, gc, dest_x,dest_y, graphic);
753 if (tile_clipmask[tile] != None)
755 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
756 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
757 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
758 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
763 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
766 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
767 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
768 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
772 void DrawMiniGraphic(int x, int y, int graphic)
774 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
775 MarkTileDirty(x/2, y/2);
778 void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y)
780 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
782 graphic -= GFX_START_ROCKSSCREEN;
783 *pixmap = pix[PIX_BACK];
784 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
785 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
787 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
789 graphic -= GFX_START_ROCKSMORE;
790 *pixmap = pix[PIX_MORE];
791 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
792 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
794 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
796 graphic -= GFX_START_ROCKSFONT;
797 *pixmap = pix[PIX_SMALLFONT];
798 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
799 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
800 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
804 *pixmap = pix[PIX_MORE];
805 *x = MINI_MORE_STARTX;
806 *y = MINI_MORE_STARTY;
810 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
812 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
814 graphic -= GFX_START_ROCKSSCREEN;
815 XCopyArea(display, pix[PIX_BACK], d, gc,
816 MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX,
817 MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY,
818 MINI_TILEX, MINI_TILEY, x, y);
820 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
822 graphic -= GFX_START_ROCKSMORE;
823 XCopyArea(display, pix[PIX_MORE], d, gc,
824 MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX,
825 MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY,
826 MINI_TILEX, MINI_TILEY, x, y);
828 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
830 graphic -= GFX_START_ROCKSFONT;
831 XCopyArea(display, pix[PIX_SMALLFONT], d, gc,
832 (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE,
833 (graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
834 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT,
835 MINI_TILEX, MINI_TILEY, x, y);
838 XFillRectangle(display, d, gc, x, y, MINI_TILEX, MINI_TILEY);
841 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
842 int cut_mode, int mask_mode)
844 int width = TILEX, height = TILEY;
846 int src_x, src_y, dest_x, dest_y;
853 DrawGraphic(x, y, graphic);
857 if (dx || dy) /* Verschiebung der Grafik? */
859 if (x < BX1) /* Element kommt von links ins Bild */
866 else if (x > BX2) /* Element kommt von rechts ins Bild */
872 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
878 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
880 else if (dx) /* allg. Bewegung in x-Richtung */
881 MarkTileDirty(x + SIGN(dx), y);
883 if (y < BY1) /* Element kommt von oben ins Bild */
885 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
893 else if (y > BY2) /* Element kommt von unten ins Bild */
899 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
905 else if (dy > 0 && cut_mode == CUT_ABOVE)
907 if (y == BY2) /* Element unterhalb des Bildes */
913 MarkTileDirty(x, y + 1);
914 } /* Element verläßt unten das Bild */
915 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
917 else if (dy) /* allg. Bewegung in y-Richtung */
918 MarkTileDirty(x, y + SIGN(dy));
921 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
923 src_pixmap = pix[PIX_BACK];
924 drawing_gc = clip_gc[PIX_BACK];
925 graphic -= GFX_START_ROCKSSCREEN;
926 src_x = SX + (graphic % GFX_PER_LINE) * TILEX + cx;
927 src_y = SY + (graphic / GFX_PER_LINE) * TILEY + cy;
929 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
931 src_pixmap = pix[PIX_MORE];
932 drawing_gc = clip_gc[PIX_MORE];
933 graphic -= GFX_START_ROCKSMORE;
934 src_x = (graphic % MORE_PER_LINE) * TILEX + cx;
935 src_y = (graphic / MORE_PER_LINE) * TILEY + cy;
937 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
939 src_pixmap = pix[PIX_HEROES];
940 drawing_gc = clip_gc[PIX_HEROES];
941 graphic -= GFX_START_ROCKSHEROES;
942 src_x = (graphic % HEROES_PER_LINE) * TILEX + cx;
943 src_y = (graphic / HEROES_PER_LINE) * TILEY + cy;
945 else /* big font graphics currently not allowed (and not needed) */
948 dest_x = FX + x * TILEX + dx;
949 dest_y = FY + y * TILEY + dy;
952 if (!IN_SCR_FIELD(x,y))
954 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
955 printf("DrawGraphicShifted(): This should never happen!\n");
960 if (mask_mode == USE_MASKING)
962 if (tile_clipmask[tile] != None)
964 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
965 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
966 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
967 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
972 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
975 XSetClipOrigin(display, drawing_gc, dest_x - src_x, dest_y - src_y);
976 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
977 src_x, src_y, width, height, dest_x, dest_y);
981 XCopyArea(display, src_pixmap, drawto_field, gc,
982 src_x, src_y, width, height, dest_x, dest_y);
987 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
990 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
993 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
994 int cut_mode, int mask_mode)
996 int ux = LEVELX(x), uy = LEVELY(y);
997 int graphic = el2gfx(element);
998 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
999 int phase4 = phase8 / 2;
1000 int phase2 = phase8 / 4;
1001 int dir = MovDir[ux][uy];
1003 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1005 graphic += 4 * !phase2;
1009 else if (dir == MV_LEFT)
1011 else if (dir == MV_DOWN)
1014 else if (element == EL_SP_SNIKSNAK)
1017 graphic = GFX_SP_SNIKSNAK_LEFT;
1018 else if (dir == MV_RIGHT)
1019 graphic = GFX_SP_SNIKSNAK_RIGHT;
1020 else if (dir == MV_UP)
1021 graphic = GFX_SP_SNIKSNAK_UP;
1023 graphic = GFX_SP_SNIKSNAK_DOWN;
1025 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1027 else if (element == EL_SP_ELECTRON)
1029 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1031 else if (element == EL_MAULWURF || element == EL_PINGUIN ||
1032 element == EL_SCHWEIN || element == EL_DRACHE)
1035 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_LEFT :
1036 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1037 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1038 else if (dir == MV_RIGHT)
1039 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_RIGHT :
1040 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1041 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1042 else if (dir == MV_UP)
1043 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_UP :
1044 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1045 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1047 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_DOWN :
1048 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1049 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1053 else if (element == EL_SONDE)
1055 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1057 else if (element == EL_SALZSAEURE)
1059 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1061 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1065 else if ((element == EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
1067 if (element != EL_SP_INFOTRON)
1068 graphic += phase2 * (element == EL_FELSBROCKEN ? 2 : 1);
1070 else if (element == EL_SIEB_LEER || element == EL_SIEB2_LEER ||
1071 element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL)
1073 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1075 else if (IS_AMOEBOID(element))
1077 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1078 graphic += (x + 2 * y + 4) % 4;
1080 else if (element == EL_MAUER_LEBT)
1082 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1084 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1085 links_massiv = TRUE;
1086 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1087 rechts_massiv = TRUE;
1089 if (links_massiv && rechts_massiv)
1090 graphic = GFX_MAUERWERK;
1091 else if (links_massiv)
1092 graphic = GFX_MAUER_R;
1093 else if (rechts_massiv)
1094 graphic = GFX_MAUER_L;
1098 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1099 else if (mask_mode == USE_MASKING)
1100 DrawGraphicThruMask(x, y, graphic);
1102 DrawGraphic(x, y, graphic);
1105 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1106 int cut_mode, int mask_mode)
1108 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1109 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1110 cut_mode, mask_mode);
1113 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1116 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1119 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1122 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1125 void DrawScreenElementThruMask(int x, int y, int element)
1127 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1130 void DrawLevelElementThruMask(int x, int y, int element)
1132 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1135 void DrawLevelFieldThruMask(int x, int y)
1137 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1140 void ErdreichAnbroeckeln(int x, int y)
1142 int i, width, height, cx,cy;
1143 int ux = LEVELX(x), uy = LEVELY(y);
1144 int element, graphic;
1146 static int xy[4][2] =
1154 if (!IN_LEV_FIELD(ux, uy))
1157 element = Feld[ux][uy];
1159 if (element == EL_ERDREICH)
1161 if (!IN_SCR_FIELD(x, y))
1164 graphic = GFX_ERDENRAND;
1170 uxx = ux + xy[i][0];
1171 uyy = uy + xy[i][1];
1172 if (!IN_LEV_FIELD(uxx, uyy))
1175 element = Feld[uxx][uyy];
1177 if (element == EL_ERDREICH)
1180 if (i == 1 || i == 2)
1184 cx = (i == 2 ? TILEX - snip : 0);
1192 cy = (i == 3 ? TILEY - snip : 0);
1195 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1196 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1197 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1198 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1201 MarkTileDirty(x, y);
1205 graphic = GFX_ERDENRAND;
1209 int xx, yy, uxx, uyy;
1213 uxx = ux + xy[i][0];
1214 uyy = uy + xy[i][1];
1216 if (!IN_LEV_FIELD(uxx, uyy) || Feld[uxx][uyy] != EL_ERDREICH ||
1217 !IN_SCR_FIELD(xx, yy))
1220 if (i == 1 || i == 2)
1224 cx = (i == 1 ? TILEX - snip : 0);
1232 cy = (i==0 ? TILEY-snip : 0);
1235 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1236 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1237 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1238 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1240 MarkTileDirty(xx, yy);
1245 void DrawScreenElement(int x, int y, int element)
1247 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1248 ErdreichAnbroeckeln(x, y);
1251 void DrawLevelElement(int x, int y, int element)
1253 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1254 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1257 void DrawScreenField(int x, int y)
1259 int ux = LEVELX(x), uy = LEVELY(y);
1262 if (!IN_LEV_FIELD(ux, uy))
1264 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1265 element = EL_LEERRAUM;
1267 element = BorderElement;
1269 DrawScreenElement(x, y, element);
1273 element = Feld[ux][uy];
1275 if (IS_MOVING(ux, uy))
1277 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1278 boolean cut_mode = NO_CUTTING;
1280 if (Store[ux][uy] == EL_MORAST_LEER ||
1281 Store[ux][uy] == EL_SIEB_LEER ||
1282 Store[ux][uy] == EL_SIEB2_LEER ||
1283 Store[ux][uy] == EL_AMOEBE_NASS)
1284 cut_mode = CUT_ABOVE;
1285 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1286 Store[ux][uy] == EL_SIEB_VOLL ||
1287 Store[ux][uy] == EL_SIEB2_VOLL)
1288 cut_mode = CUT_BELOW;
1290 if (cut_mode == CUT_ABOVE)
1291 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1293 DrawScreenElement(x, y, EL_LEERRAUM);
1296 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1298 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1300 if (Store[ux][uy] == EL_SALZSAEURE)
1301 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1303 else if (IS_BLOCKED(ux, uy))
1308 boolean cut_mode = NO_CUTTING;
1310 Blocked2Moving(ux, uy, &oldx, &oldy);
1313 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1314 MovDir[oldx][oldy] == MV_RIGHT);
1316 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1317 Store[oldx][oldy] == EL_SIEB_LEER ||
1318 Store[oldx][oldy] == EL_SIEB2_LEER ||
1319 Store[oldx][oldy] == EL_AMOEBE_NASS)
1320 cut_mode = CUT_ABOVE;
1322 DrawScreenElement(x, y, EL_LEERRAUM);
1323 element = Feld[oldx][oldy];
1326 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1328 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1330 else if (IS_DRAWABLE(element))
1331 DrawScreenElement(x, y, element);
1333 DrawScreenElement(x, y, EL_LEERRAUM);
1336 void DrawLevelField(int x, int y)
1338 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1339 DrawScreenField(SCREENX(x), SCREENY(y));
1340 else if (IS_MOVING(x, y))
1344 Moving2Blocked(x, y, &newx, &newy);
1345 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1346 DrawScreenField(SCREENX(newx), SCREENY(newy));
1348 else if (IS_BLOCKED(x, y))
1352 Blocked2Moving(x, y, &oldx, &oldy);
1353 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1354 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1358 void DrawMiniElement(int x, int y, int element)
1364 DrawMiniGraphic(x, y, -1);
1368 graphic = el2gfx(element);
1369 DrawMiniGraphic(x, y, graphic);
1372 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1374 int x = sx + scroll_x, y = sy + scroll_y;
1376 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1377 DrawMiniElement(sx, sy, EL_LEERRAUM);
1378 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1379 DrawMiniElement(sx, sy, Feld[x][y]);
1380 else if (x == -1 && y == -1)
1381 DrawMiniGraphic(sx, sy, GFX_STEEL_UPPER_LEFT);
1382 else if (x == lev_fieldx && y == -1)
1383 DrawMiniGraphic(sx, sy, GFX_STEEL_UPPER_RIGHT);
1384 else if (x == -1 && y == lev_fieldy)
1385 DrawMiniGraphic(sx, sy, GFX_STEEL_LOWER_LEFT);
1386 else if (x == lev_fieldx && y == lev_fieldy)
1387 DrawMiniGraphic(sx, sy, GFX_STEEL_LOWER_RIGHT);
1388 else if (x == -1 || x == lev_fieldx)
1389 DrawMiniGraphic(sx, sy, GFX_STEEL_VERTICAL);
1390 else if (y == -1 || y == lev_fieldy)
1391 DrawMiniGraphic(sx, sy, GFX_STEEL_HORIZONTAL);
1394 void DrawMicroElement(int xpos, int ypos, int element)
1398 if (element == EL_LEERRAUM)
1401 graphic = el2gfx(element);
1403 if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1405 graphic -= GFX_START_ROCKSMORE;
1406 XCopyArea(display, pix[PIX_MORE], drawto, gc,
1407 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX,
1408 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY,
1409 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1412 XCopyArea(display, pix[PIX_BACK], drawto, gc,
1413 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1414 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1415 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1424 for(x=BX1; x<=BX2; x++)
1425 for(y=BY1; y<=BY2; y++)
1426 DrawScreenField(x, y);
1428 if (setup.soft_scrolling)
1429 XCopyArea(display, fieldbuffer, backbuffer, gc,
1430 FX, FY, SXSIZE, SYSIZE, SX, SY);
1432 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1435 void DrawMiniLevel(int scroll_x, int scroll_y)
1439 for(x=0; x<ED_FIELDX; x++)
1440 for(y=0; y<ED_FIELDY; y++)
1441 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1443 redraw_mask |= REDRAW_FIELD;
1446 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1450 /* determine border element for this level */
1453 XFillRectangle(display, drawto, gc,
1454 xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1456 if (lev_fieldx < STD_LEV_FIELDX)
1457 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1458 if (lev_fieldy < STD_LEV_FIELDY)
1459 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1461 xpos += MICRO_TILEX;
1462 ypos += MICRO_TILEY;
1464 for(x=-1; x<=STD_LEV_FIELDX; x++)
1466 for(y=-1; y<=STD_LEV_FIELDY; y++)
1468 int lx = from_x + x, ly = from_y + y;
1470 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1471 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1473 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1474 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1479 redraw_mask |= REDRAW_MICROLEVEL;
1482 static void DrawMicroLevelLabelExt(int mode)
1484 char label_text[100];
1486 XFillRectangle(display, drawto,gc,
1487 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1489 strcpy(label_text, (mode == 1 ? level.name :
1490 mode == 2 ? "created by" :
1491 mode == 3 ? level.author : ""));
1493 if (strlen(label_text) > 0)
1495 int size, lxpos, lypos;
1497 label_text[SXSIZE / FONT4_XSIZE] = '\0';
1499 size = strlen(label_text);
1500 lxpos = SX + (SXSIZE - size * FONT4_XSIZE) / 2;
1501 lypos = MICROLABEL_YPOS;
1503 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1506 redraw_mask |= REDRAW_MICROLEVEL;
1509 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1511 static unsigned long scroll_delay = 0;
1512 static unsigned long label_delay = 0;
1513 static int from_x, from_y, scroll_direction;
1514 static int label_state, label_counter;
1518 from_x = from_y = 0;
1519 scroll_direction = MV_RIGHT;
1523 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1524 DrawMicroLevelLabelExt(label_state);
1526 /* initialize delay counters */
1527 DelayReached(&scroll_delay, 0);
1528 DelayReached(&label_delay, 0);
1533 /* scroll micro level, if needed */
1534 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1535 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1537 switch (scroll_direction)
1543 scroll_direction = MV_UP;
1547 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1550 scroll_direction = MV_DOWN;
1557 scroll_direction = MV_RIGHT;
1561 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1564 scroll_direction = MV_LEFT;
1571 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1574 /* redraw micro level label, if needed */
1575 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1576 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1577 strcmp(level.author, leveldir[leveldir_nr].name) != 0 &&
1578 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1580 label_counter = (label_counter + 1) % 23;
1581 label_state = (label_counter >= 0 && label_counter <= 7 ? 1 :
1582 label_counter >= 9 && label_counter <= 12 ? 2 :
1583 label_counter >= 14 && label_counter <= 21 ? 3 : 0);
1584 DrawMicroLevelLabelExt(label_state);
1588 int REQ_in_range(int x, int y)
1590 if (y > DY+249 && y < DY+278)
1592 if (x > DX+1 && x < DX+48)
1594 else if (x > DX+51 && x < DX+98)
1600 boolean Request(char *text, unsigned int req_state)
1602 int mx, my, ty, result = -1;
1603 unsigned int old_door_state;
1606 /* pause network game while waiting for request to answer */
1607 if (options.network &&
1608 game_status == PLAYING &&
1609 req_state & REQUEST_WAIT_FOR)
1610 SendToServer_PausePlaying();
1613 old_door_state = GetDoorState();
1615 CloseDoor(DOOR_CLOSE_1);
1617 /* Alten Türinhalt sichern */
1618 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
1619 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1620 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1622 /* Fragetext schreiben */
1623 XFillRectangle(display, pix[PIX_DB_DOOR], gc,
1624 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE);
1626 for(ty=0; ty<13; ty++)
1634 for(tl=0,tx=0; tx<7; tl++,tx++)
1637 if (!tc || tc == 32)
1648 DrawTextExt(pix[PIX_DB_DOOR], gc,
1649 DOOR_GFX_PAGEX1 + 51 - (tl * 14)/2, SY + ty * 16,
1650 txt, FS_SMALL, FC_YELLOW);
1651 text += tl + (tc == 32 ? 1 : 0);
1654 if (req_state & REQ_ASK)
1656 DrawYesNoButton(BUTTON_OK, DB_INIT);
1657 DrawYesNoButton(BUTTON_NO, DB_INIT);
1659 else if (req_state & REQ_CONFIRM)
1661 DrawConfirmButton(BUTTON_CONFIRM, DB_INIT);
1663 else if (req_state & REQ_PLAYER)
1665 DrawPlayerButton(BUTTON_PLAYER_1, DB_INIT);
1666 DrawPlayerButton(BUTTON_PLAYER_2, DB_INIT);
1667 DrawPlayerButton(BUTTON_PLAYER_3, DB_INIT);
1668 DrawPlayerButton(BUTTON_PLAYER_4, DB_INIT);
1671 OpenDoor(DOOR_OPEN_1);
1674 if (!(req_state & REQUEST_WAIT_FOR))
1677 if (game_status != MAINMENU)
1680 button_status = MB_RELEASED;
1684 if (XPending(display))
1688 XNextEvent(display, &event);
1698 if (event.type == MotionNotify)
1700 motion_status = TRUE;
1701 mx = ((XMotionEvent *) &event)->x;
1702 my = ((XMotionEvent *) &event)->y;
1706 motion_status = FALSE;
1707 mx = ((XButtonEvent *) &event)->x;
1708 my = ((XButtonEvent *) &event)->y;
1709 if (event.type==ButtonPress)
1710 button_status = ((XButtonEvent *) &event)->button;
1712 button_status = MB_RELEASED;
1715 if (req_state & REQ_ASK)
1716 choice = CheckYesNoButtons(mx,my,button_status);
1717 else if (req_state & REQ_CONFIRM)
1718 choice = CheckConfirmButton(mx,my,button_status);
1720 choice = CheckPlayerButtons(mx,my,button_status);
1730 case BUTTON_CONFIRM:
1731 result = TRUE | FALSE;
1734 case BUTTON_PLAYER_1:
1737 case BUTTON_PLAYER_2:
1740 case BUTTON_PLAYER_3:
1743 case BUTTON_PLAYER_4:
1754 switch(XLookupKeysym((XKeyEvent *)&event,
1755 ((XKeyEvent *)&event)->state))
1768 if (req_state & REQ_PLAYER)
1773 key_joystick_mapping = 0;
1777 HandleOtherEvents(&event);
1781 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
1783 int joy = AnyJoystick();
1785 if (joy & JOY_BUTTON_1)
1787 else if (joy & JOY_BUTTON_2)
1793 /* don't eat all CPU time */
1797 if (game_status != MAINMENU)
1800 if (!(req_state & REQ_STAY_OPEN))
1802 CloseDoor(DOOR_CLOSE_1);
1804 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
1806 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
1807 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
1808 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
1809 OpenDoor(DOOR_OPEN_1);
1814 /* continue network game after request */
1815 if (options.network &&
1816 game_status == PLAYING &&
1817 req_state & REQUEST_WAIT_FOR)
1818 SendToServer_ContinuePlaying();
1824 unsigned int OpenDoor(unsigned int door_state)
1826 unsigned int new_door_state;
1828 if (door_state & DOOR_COPY_BACK)
1830 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
1831 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
1832 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1833 door_state &= ~DOOR_COPY_BACK;
1836 new_door_state = MoveDoor(door_state);
1838 return(new_door_state);
1841 unsigned int CloseDoor(unsigned int door_state)
1843 unsigned int new_door_state;
1845 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
1846 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1847 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
1848 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
1850 new_door_state = MoveDoor(door_state);
1852 return(new_door_state);
1855 unsigned int GetDoorState()
1857 return(MoveDoor(DOOR_GET_STATE));
1860 unsigned int MoveDoor(unsigned int door_state)
1862 static int door1 = DOOR_OPEN_1;
1863 static int door2 = DOOR_CLOSE_2;
1864 static unsigned long door_delay = 0;
1865 int x, start, stepsize = 2;
1866 unsigned long door_delay_value = stepsize * 5;
1868 if (door_state == DOOR_GET_STATE)
1869 return(door1 | door2);
1871 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
1872 door_state &= ~DOOR_OPEN_1;
1873 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
1874 door_state &= ~DOOR_CLOSE_1;
1875 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
1876 door_state &= ~DOOR_OPEN_2;
1877 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
1878 door_state &= ~DOOR_CLOSE_2;
1880 if (setup.quick_doors)
1883 door_delay_value = 0;
1884 StopSound(SND_OEFFNEN);
1887 if (door_state & DOOR_ACTION)
1889 if (!(door_state & DOOR_NO_DELAY))
1890 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
1892 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
1894 for(x=start; x<=DXSIZE; x+=stepsize)
1896 WaitUntilDelayReached(&door_delay, door_delay_value);
1898 if (door_state & DOOR_ACTION_1)
1900 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
1901 int j = (DXSIZE - i) / 3;
1903 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
1904 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
1905 DXSIZE,DYSIZE - i/2, DX, DY);
1907 XFillRectangle(display, drawto, gc, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
1909 XSetClipOrigin(display, clip_gc[PIX_DOOR],
1910 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
1911 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
1912 DXSIZE, DOOR_GFX_PAGEY1, i, 77, DX + DXSIZE - i, DY + j);
1913 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1914 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63, DX + DXSIZE - i,
1916 XSetClipOrigin(display, clip_gc[PIX_DOOR],
1917 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
1918 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1919 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j, DX, DY);
1920 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1921 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63, DX, DY + 140 - j);
1923 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1924 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
1926 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1927 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
1929 XSetClipOrigin(display, clip_gc[PIX_DOOR],
1930 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
1931 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1932 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
1933 DX + DXSIZE - i, DY + 77 + j);
1934 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1935 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
1936 DX + DXSIZE - i, DY + 203 + j);
1938 redraw_mask |= REDRAW_DOOR_1;
1941 if (door_state & DOOR_ACTION_2)
1943 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
1944 int j = (VXSIZE - i) / 3;
1946 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
1947 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
1948 VXSIZE, VYSIZE - i/2, VX, VY);
1950 XFillRectangle(display, drawto, gc, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
1952 XSetClipOrigin(display, clip_gc[PIX_DOOR],
1953 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
1954 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1955 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2, VX + VXSIZE-i, VY+j);
1956 XSetClipOrigin(display, clip_gc[PIX_DOOR],
1957 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
1958 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
1959 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j, VX, VY);
1961 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1962 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2,
1963 VX, VY + VYSIZE / 2 - j);
1964 XSetClipOrigin(display, clip_gc[PIX_DOOR],
1965 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
1966 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
1967 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2 - j,
1968 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
1970 redraw_mask |= REDRAW_DOOR_2;
1975 if (game_status == MAINMENU)
1980 if (setup.quick_doors)
1981 StopSound(SND_OEFFNEN);
1983 if (door_state & DOOR_ACTION_1)
1984 door1 = door_state & DOOR_ACTION_1;
1985 if (door_state & DOOR_ACTION_2)
1986 door2 = door_state & DOOR_ACTION_2;
1988 return(door1 | door2);
1991 int ReadPixel(Drawable d, int x, int y)
1993 XImage *pixel_image;
1994 unsigned long pixel_value;
1996 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
1997 pixel_value = XGetPixel(pixel_image, 0, 0);
1999 XDestroyImage(pixel_image);
2004 int el2gfx(int element)
2008 case EL_LEERRAUM: return -1;
2009 case EL_ERDREICH: return GFX_ERDREICH;
2010 case EL_MAUERWERK: return GFX_MAUERWERK;
2011 case EL_FELSBODEN: return GFX_FELSBODEN;
2012 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2013 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2014 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2015 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2016 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2017 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2018 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2019 case EL_SPIELER1: return GFX_SPIELER1;
2020 case EL_SPIELER2: return GFX_SPIELER2;
2021 case EL_SPIELER3: return GFX_SPIELER3;
2022 case EL_SPIELER4: return GFX_SPIELER4;
2023 case EL_KAEFER: return GFX_KAEFER;
2024 case EL_KAEFER_R: return GFX_KAEFER_R;
2025 case EL_KAEFER_O: return GFX_KAEFER_O;
2026 case EL_KAEFER_L: return GFX_KAEFER_L;
2027 case EL_KAEFER_U: return GFX_KAEFER_U;
2028 case EL_FLIEGER: return GFX_FLIEGER;
2029 case EL_FLIEGER_R: return GFX_FLIEGER_R;
2030 case EL_FLIEGER_O: return GFX_FLIEGER_O;
2031 case EL_FLIEGER_L: return GFX_FLIEGER_L;
2032 case EL_FLIEGER_U: return GFX_FLIEGER_U;
2033 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2034 case EL_BUTTERFLY_R: return GFX_BUTTERFLY_R;
2035 case EL_BUTTERFLY_O: return GFX_BUTTERFLY_O;
2036 case EL_BUTTERFLY_L: return GFX_BUTTERFLY_L;
2037 case EL_BUTTERFLY_U: return GFX_BUTTERFLY_U;
2038 case EL_FIREFLY: return GFX_FIREFLY;
2039 case EL_FIREFLY_R: return GFX_FIREFLY_R;
2040 case EL_FIREFLY_O: return GFX_FIREFLY_O;
2041 case EL_FIREFLY_L: return GFX_FIREFLY_L;
2042 case EL_FIREFLY_U: return GFX_FIREFLY_U;
2043 case EL_MAMPFER: return GFX_MAMPFER;
2044 case EL_ROBOT: return GFX_ROBOT;
2045 case EL_BETON: return GFX_BETON;
2046 case EL_DIAMANT: return GFX_DIAMANT;
2047 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2048 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2049 case EL_TROPFEN: return GFX_TROPFEN;
2050 case EL_BOMBE: return GFX_BOMBE;
2051 case EL_SIEB_INAKTIV: return GFX_SIEB_INAKTIV;
2052 case EL_SIEB_LEER: return GFX_SIEB_LEER;
2053 case EL_SIEB_VOLL: return GFX_SIEB_VOLL;
2054 case EL_SIEB_TOT: return GFX_SIEB_TOT;
2055 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2056 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2057 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2058 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2059 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2060 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2061 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2062 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2063 case EL_LIFE: return GFX_LIFE;
2064 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2065 case EL_DYNAMIT: return GFX_DYNAMIT;
2066 case EL_BADEWANNE: return GFX_BADEWANNE;
2067 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2068 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2069 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2070 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2071 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2072 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2073 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2074 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2075 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2076 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2077 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2078 case EL_PFORTE1: return GFX_PFORTE1;
2079 case EL_PFORTE2: return GFX_PFORTE2;
2080 case EL_PFORTE3: return GFX_PFORTE3;
2081 case EL_PFORTE4: return GFX_PFORTE4;
2082 case EL_PFORTE1X: return GFX_PFORTE1X;
2083 case EL_PFORTE2X: return GFX_PFORTE2X;
2084 case EL_PFORTE3X: return GFX_PFORTE3X;
2085 case EL_PFORTE4X: return GFX_PFORTE4X;
2086 case EL_DYNAMIT_AUS: return GFX_DYNAMIT_AUS;
2087 case EL_PACMAN: return GFX_PACMAN;
2088 case EL_PACMAN_R: return GFX_PACMAN_R;
2089 case EL_PACMAN_O: return GFX_PACMAN_O;
2090 case EL_PACMAN_L: return GFX_PACMAN_L;
2091 case EL_PACMAN_U: return GFX_PACMAN_U;
2092 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2093 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2094 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2095 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2096 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2097 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2098 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2099 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2100 case EL_MAUER_X: return GFX_MAUER_X;
2101 case EL_MAUER_Y: return GFX_MAUER_Y;
2102 case EL_MAUER_XY: return GFX_MAUER_XY;
2103 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2104 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2105 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2106 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2107 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2108 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2109 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2110 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2111 case EL_MAMPFER2: return GFX_MAMPFER2;
2112 case EL_SIEB2_INAKTIV: return GFX_SIEB2_INAKTIV;
2113 case EL_SIEB2_LEER: return GFX_SIEB2_LEER;
2114 case EL_SIEB2_VOLL: return GFX_SIEB2_VOLL;
2115 case EL_SIEB2_TOT: return GFX_SIEB2_TOT;
2116 case EL_DYNABOMB: return GFX_DYNABOMB;
2117 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2118 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2119 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2120 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2121 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2122 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2123 case EL_MAULWURF: return GFX_MAULWURF;
2124 case EL_PINGUIN: return GFX_PINGUIN;
2125 case EL_SCHWEIN: return GFX_SCHWEIN;
2126 case EL_DRACHE: return GFX_DRACHE;
2127 case EL_SONDE: return GFX_SONDE;
2128 case EL_PFEIL_L: return GFX_PFEIL_L;
2129 case EL_PFEIL_R: return GFX_PFEIL_R;
2130 case EL_PFEIL_O: return GFX_PFEIL_O;
2131 case EL_PFEIL_U: return GFX_PFEIL_U;
2132 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2133 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2134 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2135 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2139 if (IS_CHAR(element))
2140 return GFX_CHAR_START + (element - EL_CHAR_START);
2141 else if (element >= EL_SP_START && element <= EL_SP_END)
2143 int nr_element = element - EL_SP_START;
2144 int gfx_per_line = 8;
2146 (nr_element / gfx_per_line) * MORE_PER_LINE +
2147 (nr_element % gfx_per_line);
2149 return GFX_START_ROCKSMORE + nr_graphic;