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 /* tool button identifiers */
35 #define TOOL_CTRL_ID_YES 0
36 #define TOOL_CTRL_ID_NO 1
37 #define TOOL_CTRL_ID_CONFIRM 2
38 #define TOOL_CTRL_ID_PLAYER_1 3
39 #define TOOL_CTRL_ID_PLAYER_2 4
40 #define TOOL_CTRL_ID_PLAYER_3 5
41 #define TOOL_CTRL_ID_PLAYER_4 6
43 #define NUM_TOOL_BUTTONS 7
45 /* forward declaration for internal use */
46 static int getGraphicAnimationPhase(int, int, int);
47 static void UnmapToolButtons();
48 static void HandleToolButtons(struct GadgetInfo *);
50 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
51 static int request_gadget_id = -1;
53 void SetDrawtoField(int mode)
55 if (mode == DRAW_BUFFERED && setup.soft_scrolling)
66 drawto_field = fieldbuffer;
68 else /* DRAW_DIRECT, DRAW_BACKBUFFER */
79 drawto_field = (mode == DRAW_DIRECT ? window : backbuffer);
86 Drawable buffer = (drawto_field == window ? backbuffer : drawto_field);
88 if (setup.direct_draw && game_status == PLAYING)
89 redraw_mask &= ~REDRAW_MAIN;
91 if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
92 redraw_mask |= REDRAW_FIELD;
94 if (redraw_mask & REDRAW_FIELD)
95 redraw_mask &= ~REDRAW_TILES;
98 if (redraw_mask & REDRAW_FIELD ||
99 (ScreenGfxPos && setup.soft_scrolling && game_status == PLAYING))
100 redraw_mask &= ~REDRAW_TILES;
106 /* synchronize X11 graphics at this point; if we would synchronize the
107 display immediately after the buffer switching (after the XFlush),
108 this could mean that we have to wait for the graphics to complete,
109 although we could go on doing calculations for the next frame */
111 XSync(display, FALSE);
115 wait_for_vsync = TRUE;
119 if (redraw_mask & REDRAW_ALL)
121 XCopyArea(display, backbuffer, window, gc,
122 0, 0, WIN_XSIZE, WIN_YSIZE,
127 if (redraw_mask & REDRAW_FIELD)
129 if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
131 XCopyArea(display, backbuffer, window, gc,
132 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
137 int fx = FX, fy = FY;
139 if (setup.soft_scrolling)
141 fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
142 fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0);
145 if (setup.soft_scrolling ||
146 ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
147 ABS(ScreenMovPos) == ScrollStepSize ||
148 redraw_tiles > REDRAWTILES_THRESHOLD)
150 XCopyArea(display, buffer, window, gc, fx, fy, SXSIZE, SYSIZE, SX, SY);
154 printf("redrawing all (ScreenGfxPos == %d) because %s\n",
156 (setup.soft_scrolling ?
157 "setup.soft_scrolling" :
158 ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
159 "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
160 ABS(ScreenGfxPos) == ScrollStepSize ?
161 "ABS(ScreenGfxPos) == ScrollStepSize" :
162 "redraw_tiles > REDRAWTILES_THRESHOLD"));
167 redraw_mask &= ~REDRAW_MAIN;
170 if (redraw_mask & REDRAW_DOORS)
172 if (redraw_mask & REDRAW_DOOR_1)
173 XCopyArea(display, backbuffer, window, gc,
174 DX, DY, DXSIZE, DYSIZE,
176 if (redraw_mask & REDRAW_DOOR_2)
178 if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
179 XCopyArea(display,backbuffer,window,gc,
180 VX,VY, VXSIZE,VYSIZE,
184 if (redraw_mask & REDRAW_VIDEO_1)
185 XCopyArea(display,backbuffer,window,gc,
186 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
187 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
188 VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
189 if (redraw_mask & REDRAW_VIDEO_2)
190 XCopyArea(display,backbuffer,window,gc,
191 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
192 VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
193 VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
194 if (redraw_mask & REDRAW_VIDEO_3)
195 XCopyArea(display,backbuffer,window,gc,
196 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
197 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
198 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
201 if (redraw_mask & REDRAW_DOOR_3)
202 XCopyArea(display, backbuffer, window, gc,
203 EX, EY, EXSIZE, EYSIZE,
205 redraw_mask &= ~REDRAW_DOORS;
208 if (redraw_mask & REDRAW_MICROLEVEL)
210 XCopyArea(display,backbuffer,window,gc,
211 MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
212 MICROLEV_XPOS, MICROLEV_YPOS);
213 XCopyArea(display,backbuffer,window,gc,
214 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
215 SX, MICROLABEL_YPOS);
216 redraw_mask &= ~REDRAW_MICROLEVEL;
219 if (redraw_mask & REDRAW_TILES)
221 for(x=0; x<SCR_FIELDX; x++)
222 for(y=0; y<SCR_FIELDY; y++)
223 if (redraw[redraw_x1 + x][redraw_y1 + y])
224 XCopyArea(display, buffer, window, gc,
225 FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
226 SX + x * TILEX, SY + y * TILEY);
231 for(x=0; x<MAX_BUF_XSIZE; x++)
232 for(y=0; y<MAX_BUF_YSIZE; y++)
241 long fading_delay = 300;
243 if (setup.fading && (redraw_mask & REDRAW_FIELD))
250 XFillRectangle(display,window,gc,
251 REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
254 for(i=0;i<2*FULL_SYSIZE;i++)
256 for(y=0;y<FULL_SYSIZE;y++)
258 XCopyArea(display,backbuffer,window,gc,
259 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
267 for(i=1;i<FULL_SYSIZE;i+=2)
268 XCopyArea(display,backbuffer,window,gc,
269 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
275 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
276 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
277 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
281 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
282 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
283 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
287 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
288 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
289 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
293 XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
294 XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
295 REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
299 redraw_mask &= ~REDRAW_MAIN;
308 XFillRectangle(display, backbuffer, gc,
309 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
311 if (setup.soft_scrolling && game_status == PLAYING)
313 XFillRectangle(display, fieldbuffer, gc, 0, 0, FXSIZE, FYSIZE);
314 SetDrawtoField(DRAW_BUFFERED);
317 SetDrawtoField(DRAW_BACKBUFFER);
319 if (setup.direct_draw && game_status == PLAYING)
321 XFillRectangle(display, window, gc,
322 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
323 SetDrawtoField(DRAW_DIRECT);
326 redraw_mask |= REDRAW_FIELD;
329 void DrawTextFCentered(int y, int font_type, char *format, ...)
331 char buffer[FULL_SXSIZE / FONT3_XSIZE + 10];
335 font_xsize = (font_type < FC_SPECIAL1 ? FONT2_XSIZE :
336 font_type < FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
338 va_start(ap, format);
339 vsprintf(buffer, format, ap);
342 DrawText(SX + (SXSIZE - strlen(buffer) * font_xsize) / 2, SY + y,
343 buffer, FS_SMALL, font_type);
346 void DrawTextF(int x, int y, int font_type, char *format, ...)
348 char buffer[FULL_SXSIZE / FONT3_XSIZE + 10];
351 va_start(ap, format);
352 vsprintf(buffer, format, ap);
355 DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
358 void DrawText(int x, int y, char *text, int font_size, int font_type)
360 DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
363 redraw_mask |= REDRAW_FIELD;
365 redraw_mask |= REDRAW_DOOR_1;
368 void DrawTextExt(Drawable d, GC gc, int x, int y,
369 char *text, int font_size, int font_type)
371 int font_width, font_height, font_start;
373 boolean print_inverse = FALSE;
375 if (font_size != FS_SMALL && font_size != FS_BIG)
376 font_size = FS_SMALL;
377 if (font_type < FC_RED || font_type > FC_SPECIAL2)
380 font_width = (font_size == FS_BIG ? FONT1_XSIZE :
381 font_type < FC_SPECIAL1 ? FONT2_XSIZE :
382 font_type < FC_SPECIAL2 ? FONT3_XSIZE : FONT4_XSIZE);
383 font_height = (font_size == FS_BIG ? FONT1_XSIZE :
384 font_type < FC_SPECIAL2 ? FONT2_XSIZE : FONT4_XSIZE);
385 font_pixmap = (font_size == FS_BIG ? PIX_BIGFONT : PIX_SMALLFONT);
386 font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE : FONT2_YSIZE) *
387 FONT_LINES_PER_FONT);
393 if (c == '~' && font_size == FS_SMALL && font_type <= FC_YELLOW)
395 print_inverse = TRUE;
399 if (c >= 'a' && c <= 'z')
401 else if (c == 'ä' || c == 'Ä')
403 else if (c == 'ö' || c == 'Ö')
405 else if (c == 'ü' || c == 'Ü')
408 if (c >= 32 && c <= 95)
410 int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
411 int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
412 int dest_x = x, dest_y = y;
416 XCopyArea(display, pix[font_pixmap], d, gc,
417 FONT_CHARS_PER_LINE * font_width,
418 3 * font_height + font_start,
419 font_width, font_height, x, y);
421 XSetClipOrigin(display, clip_gc[font_pixmap],
422 dest_x - src_x, dest_y - src_y);
423 XCopyArea(display, pix[font_pixmap], d, clip_gc[font_pixmap],
424 0, 0, font_width, font_height, dest_x, dest_y);
427 XCopyArea(display, pix[font_pixmap], d, gc,
428 src_x, src_y, font_width, font_height, dest_x, dest_y);
435 void DrawAllPlayers()
439 for(i=0; i<MAX_PLAYERS; i++)
440 if (stored_player[i].active)
441 DrawPlayer(&stored_player[i]);
444 void DrawPlayerField(int x, int y)
449 DrawPlayer(PLAYERINFO(x,y));
452 void DrawPlayer(struct PlayerInfo *player)
454 int jx = player->jx, jy = player->jy;
455 int last_jx = player->last_jx, last_jy = player->last_jy;
456 int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
457 int sx = SCREENX(jx), sy = SCREENY(jy);
458 int sxx = 0, syy = 0;
459 int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
461 boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
463 if (!player->active || player->gone ||
464 !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
468 if (!IN_LEV_FIELD(jx,jy))
470 printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
471 printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
472 printf("DrawPlayerField(): This should never happen!\n");
477 if (element == EL_EXPLODING)
480 /* draw things in the field the player is leaving, if needed */
483 if (last_jx != jx || last_jy != jy)
486 if (player_is_moving)
488 if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
490 DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
491 DrawLevelFieldThruMask(last_jx, last_jy);
493 else if (last_element == EL_DYNAMIT)
494 DrawDynamite(last_jx, last_jy);
496 DrawLevelField(last_jx, last_jy);
498 if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
502 if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
503 DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
505 DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
508 DrawLevelField(next_jx, next_jy);
512 if (!IN_SCR_FIELD(sx, sy))
515 if (setup.direct_draw)
516 SetDrawtoField(DRAW_BUFFERED);
518 /* draw things behind the player, if needed */
521 DrawLevelElement(jx, jy, Store[jx][jy]);
522 else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
523 DrawLevelField(jx, jy);
525 /* draw player himself */
527 if (game_emulation == EMU_SUPAPLEX)
529 static int last_dir = MV_LEFT;
530 int action = (player->programmed_action ? player->programmed_action :
532 boolean action_moving =
534 ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
535 !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
537 graphic = GFX_SP_MURPHY;
541 if (player->MovDir == MV_LEFT)
542 graphic = GFX_MURPHY_PUSH_LEFT;
543 else if (player->MovDir == MV_RIGHT)
544 graphic = GFX_MURPHY_PUSH_RIGHT;
545 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
546 graphic = GFX_MURPHY_PUSH_LEFT;
547 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
548 graphic = GFX_MURPHY_PUSH_RIGHT;
550 else if (player->snapped)
552 if (player->MovDir == MV_LEFT)
553 graphic = GFX_MURPHY_SNAP_LEFT;
554 else if (player->MovDir == MV_RIGHT)
555 graphic = GFX_MURPHY_SNAP_RIGHT;
556 else if (player->MovDir == MV_UP)
557 graphic = GFX_MURPHY_SNAP_UP;
558 else if (player->MovDir == MV_DOWN)
559 graphic = GFX_MURPHY_SNAP_DOWN;
561 else if (action_moving)
563 if (player->MovDir == MV_LEFT)
564 graphic = GFX_MURPHY_GO_LEFT;
565 else if (player->MovDir == MV_RIGHT)
566 graphic = GFX_MURPHY_GO_RIGHT;
567 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
568 graphic = GFX_MURPHY_GO_LEFT;
569 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
570 graphic = GFX_MURPHY_GO_RIGHT;
572 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
575 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
576 last_dir = player->MovDir;
580 if (player->MovDir == MV_LEFT)
582 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
583 else if (player->MovDir == MV_RIGHT)
585 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
586 else if (player->MovDir == MV_UP)
587 graphic = GFX_SPIELER1_UP;
588 else /* MV_DOWN || MV_NO_MOVING */
589 graphic = GFX_SPIELER1_DOWN;
591 graphic += player->index_nr * 3 * HEROES_PER_LINE;
592 graphic += player->Frame;
597 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
598 sxx = player->GfxPos;
600 syy = player->GfxPos;
603 if (!setup.soft_scrolling && ScreenMovPos)
606 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
608 if (player->Pushing && player->GfxPos)
610 int px = SCREENX(next_jx), py = SCREENY(next_jy);
612 if (element == EL_SOKOBAN_FELD_LEER ||
613 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
614 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
618 int element = Feld[next_jx][next_jy];
619 int graphic = el2gfx(element);
621 if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK) && sxx)
623 int phase = (player->GfxPos / (TILEX / 4));
625 if (player->MovDir == MV_LEFT)
628 graphic += (phase + 4) % 4;
631 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
635 /* draw things in front of player (EL_DYNAMIT or EL_DYNABOMB) */
637 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
639 graphic = el2gfx(element);
641 if (element == EL_DYNAMIT)
643 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
648 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
652 if (game_emulation == EMU_SUPAPLEX)
653 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
655 DrawGraphicThruMask(sx, sy, graphic + phase);
659 if ((last_jx != jx || last_jy != jy) && last_element == EL_EXPLODING)
662 if (player_is_moving && last_element == EL_EXPLODING)
664 int phase = Frame[last_jx][last_jy];
668 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
669 GFX_EXPLOSION + ((phase - 1) / delay - 1));
672 /* draw elements that stay over the player */
673 /* handle the field the player is leaving ... */
674 if (player_is_moving && IS_OVER_PLAYER(last_element))
675 DrawLevelField(last_jx, last_jy);
676 /* ... and the field the player is entering */
677 if (IS_OVER_PLAYER(element))
678 DrawLevelField(jx, jy);
680 if (setup.direct_draw)
682 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
683 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
684 int x_size = TILEX * (1 + ABS(jx - last_jx));
685 int y_size = TILEY * (1 + ABS(jy - last_jy));
687 XCopyArea(display, drawto_field, window, gc,
688 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
689 SetDrawtoField(DRAW_DIRECT);
692 MarkTileDirty(sx,sy);
695 static int getGraphicAnimationPhase(int frames, int delay, int mode)
699 if (mode == ANIM_OSCILLATE)
701 int max_anim_frames = 2 * frames - 2;
702 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
703 phase = (phase < frames ? phase : max_anim_frames - phase);
706 phase = (FrameCounter % (delay * frames)) / delay;
708 if (mode == ANIM_REVERSE)
714 void DrawGraphicAnimationExt(int x, int y, int graphic,
715 int frames, int delay, int mode, int mask_mode)
717 int phase = getGraphicAnimationPhase(frames, delay, mode);
719 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
721 if (mask_mode == USE_MASKING)
722 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
724 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
728 void DrawGraphicAnimation(int x, int y, int graphic,
729 int frames, int delay, int mode)
731 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
734 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
735 int frames, int delay, int mode)
737 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
740 void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y)
742 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
744 graphic -= GFX_START_ROCKSSCREEN;
745 *pixmap_nr = PIX_BACK;
746 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
747 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
749 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
751 graphic -= GFX_START_ROCKSMORE;
752 *pixmap_nr = PIX_MORE;
753 *x = (graphic % MORE_PER_LINE) * TILEX;
754 *y = (graphic / MORE_PER_LINE) * TILEY;
756 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
758 graphic -= GFX_START_ROCKSHEROES;
759 *pixmap_nr = PIX_HEROES;
760 *x = (graphic % HEROES_PER_LINE) * TILEX;
761 *y = (graphic / HEROES_PER_LINE) * TILEY;
763 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
765 graphic -= GFX_START_ROCKSFONT;
766 *pixmap_nr = PIX_BIGFONT;
767 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
768 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
769 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
773 *pixmap_nr = PIX_MORE;
779 void DrawGraphic(int x, int y, int graphic)
782 if (!IN_SCR_FIELD(x,y))
784 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
785 printf("DrawGraphic(): This should never happen!\n");
790 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
794 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
802 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
803 XCopyArea(display, pix[pixmap_nr], d, gc,
804 src_x, src_y, TILEX, TILEY, x, y);
808 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
810 graphic -= GFX_START_ROCKSSCREEN;
811 XCopyArea(display, pix[PIX_BACK], d, gc,
812 SX + (graphic % GFX_PER_LINE) * TILEX,
813 SY + (graphic / GFX_PER_LINE) * TILEY,
816 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
818 graphic -= GFX_START_ROCKSMORE;
819 XCopyArea(display, pix[PIX_MORE], d, gc,
820 (graphic % MORE_PER_LINE) * TILEX,
821 (graphic / MORE_PER_LINE) * TILEY,
824 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
826 graphic -= GFX_START_ROCKSHEROES;
827 XCopyArea(display, pix[PIX_HEROES], d, gc,
828 (graphic % HEROES_PER_LINE) * TILEX,
829 (graphic / HEROES_PER_LINE) * TILEY,
832 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
834 graphic -= GFX_START_ROCKSFONT;
835 XCopyArea(display, pix[PIX_BIGFONT], d, gc,
836 (graphic % FONT_CHARS_PER_LINE) * TILEX,
837 (graphic / FONT_CHARS_PER_LINE) * TILEY +
838 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
842 XFillRectangle(display, d, gc, x, y, TILEX, TILEY);
848 void DrawGraphicThruMask(int x, int y, int graphic)
851 if (!IN_SCR_FIELD(x,y))
853 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
854 printf("DrawGraphicThruMask(): This should never happen!\n");
859 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
863 void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
874 if (graphic == GFX_LEERRAUM)
877 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
878 src_pixmap = pix[pixmap_nr];
879 drawing_gc = clip_gc[pixmap_nr];
888 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
890 src_pixmap = pix[PIX_BACK];
891 drawing_gc = clip_gc[PIX_BACK];
892 graphic -= GFX_START_ROCKSSCREEN;
893 src_x = SX + (graphic % GFX_PER_LINE) * TILEX;
894 src_y = SY + (graphic / GFX_PER_LINE) * TILEY;
896 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
898 src_pixmap = pix[PIX_MORE];
899 drawing_gc = clip_gc[PIX_MORE];
900 graphic -= GFX_START_ROCKSMORE;
901 src_x = (graphic % MORE_PER_LINE) * TILEX;
902 src_y = (graphic / MORE_PER_LINE) * TILEY;
904 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
906 src_pixmap = pix[PIX_HEROES];
907 drawing_gc = clip_gc[PIX_HEROES];
908 graphic -= GFX_START_ROCKSHEROES;
909 src_x = (graphic % HEROES_PER_LINE) * TILEX;
910 src_y = (graphic / HEROES_PER_LINE) * TILEY;
914 DrawGraphicExt(d, gc, dest_x,dest_y, graphic);
921 if (tile_clipmask[tile] != None)
923 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
924 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
925 XCopyArea(display, src_pixmap, d, tile_clip_gc,
926 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
931 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
934 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
935 XCopyArea(display, src_pixmap, d, drawing_gc,
936 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
940 void DrawMiniGraphic(int x, int y, int graphic)
942 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
943 MarkTileDirty(x/2, y/2);
946 void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y)
948 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
950 graphic -= GFX_START_ROCKSSCREEN;
951 *pixmap = pix[PIX_BACK];
952 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
953 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
955 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
957 graphic -= GFX_START_ROCKSMORE;
958 graphic -= ((graphic / MORE_PER_LINE) * MORE_PER_LINE) / 2;
959 *pixmap = pix[PIX_MORE];
960 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
961 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
963 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
965 graphic -= GFX_START_ROCKSFONT;
966 *pixmap = pix[PIX_SMALLFONT];
967 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
968 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
969 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
973 *pixmap = pix[PIX_MORE];
974 *x = MINI_MORE_STARTX;
975 *y = MINI_MORE_STARTY;
979 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
987 getMiniGraphicSource(graphic, &pixmap, &src_x, &src_y);
988 XCopyArea(display, pixmap, d, gc,
989 src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
993 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
995 graphic -= GFX_START_ROCKSSCREEN;
996 XCopyArea(display, pix[PIX_BACK], d, gc,
997 MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX,
998 MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY,
999 MINI_TILEX, MINI_TILEY, x, y);
1001 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1003 graphic -= GFX_START_ROCKSMORE;
1004 XCopyArea(display, pix[PIX_MORE], d, gc,
1005 MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX,
1006 MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY,
1007 MINI_TILEX, MINI_TILEY, x, y);
1009 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
1011 graphic -= GFX_START_ROCKSFONT;
1012 XCopyArea(display, pix[PIX_SMALLFONT], d, gc,
1013 (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE,
1014 (graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
1015 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT,
1016 MINI_TILEX, MINI_TILEY, x, y);
1019 XFillRectangle(display, d, gc, x, y, MINI_TILEX, MINI_TILEY);
1025 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
1026 int cut_mode, int mask_mode)
1028 int width = TILEX, height = TILEY;
1030 int src_x, src_y, dest_x, dest_y;
1037 DrawGraphic(x, y, graphic);
1041 if (dx || dy) /* Verschiebung der Grafik? */
1043 if (x < BX1) /* Element kommt von links ins Bild */
1050 else if (x > BX2) /* Element kommt von rechts ins Bild */
1056 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1062 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1064 else if (dx) /* allg. Bewegung in x-Richtung */
1065 MarkTileDirty(x + SIGN(dx), y);
1067 if (y < BY1) /* Element kommt von oben ins Bild */
1069 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1077 else if (y > BY2) /* Element kommt von unten ins Bild */
1083 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1089 else if (dy > 0 && cut_mode == CUT_ABOVE)
1091 if (y == BY2) /* Element unterhalb des Bildes */
1097 MarkTileDirty(x, y + 1);
1098 } /* Element verläßt unten das Bild */
1099 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1101 else if (dy) /* allg. Bewegung in y-Richtung */
1102 MarkTileDirty(x, y + SIGN(dy));
1105 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
1107 src_pixmap = pix[PIX_BACK];
1108 drawing_gc = clip_gc[PIX_BACK];
1109 graphic -= GFX_START_ROCKSSCREEN;
1110 src_x = SX + (graphic % GFX_PER_LINE) * TILEX + cx;
1111 src_y = SY + (graphic / GFX_PER_LINE) * TILEY + cy;
1113 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1115 src_pixmap = pix[PIX_MORE];
1116 drawing_gc = clip_gc[PIX_MORE];
1117 graphic -= GFX_START_ROCKSMORE;
1118 src_x = (graphic % MORE_PER_LINE) * TILEX + cx;
1119 src_y = (graphic / MORE_PER_LINE) * TILEY + cy;
1121 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
1123 src_pixmap = pix[PIX_HEROES];
1124 drawing_gc = clip_gc[PIX_HEROES];
1125 graphic -= GFX_START_ROCKSHEROES;
1126 src_x = (graphic % HEROES_PER_LINE) * TILEX + cx;
1127 src_y = (graphic / HEROES_PER_LINE) * TILEY + cy;
1129 else /* big font graphics currently not allowed (and not needed) */
1132 dest_x = FX + x * TILEX + dx;
1133 dest_y = FY + y * TILEY + dy;
1136 if (!IN_SCR_FIELD(x,y))
1138 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1139 printf("DrawGraphicShifted(): This should never happen!\n");
1144 if (mask_mode == USE_MASKING)
1146 if (tile_clipmask[tile] != None)
1148 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
1149 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
1150 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
1151 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1156 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1159 XSetClipOrigin(display, drawing_gc, dest_x - src_x, dest_y - src_y);
1160 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
1161 src_x, src_y, width, height, dest_x, dest_y);
1165 XCopyArea(display, src_pixmap, drawto_field, gc,
1166 src_x, src_y, width, height, dest_x, dest_y);
1171 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1174 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1177 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1178 int cut_mode, int mask_mode)
1180 int ux = LEVELX(x), uy = LEVELY(y);
1181 int graphic = el2gfx(element);
1182 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1183 int phase4 = phase8 / 2;
1184 int phase2 = phase8 / 4;
1185 int dir = MovDir[ux][uy];
1187 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1189 graphic += 4 * !phase2;
1193 else if (dir == MV_LEFT)
1195 else if (dir == MV_DOWN)
1198 else if (element == EL_SP_SNIKSNAK)
1201 graphic = GFX_SP_SNIKSNAK_LEFT;
1202 else if (dir == MV_RIGHT)
1203 graphic = GFX_SP_SNIKSNAK_RIGHT;
1204 else if (dir == MV_UP)
1205 graphic = GFX_SP_SNIKSNAK_UP;
1207 graphic = GFX_SP_SNIKSNAK_DOWN;
1209 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1211 else if (element == EL_SP_ELECTRON)
1213 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1215 else if (element == EL_MAULWURF || element == EL_PINGUIN ||
1216 element == EL_SCHWEIN || element == EL_DRACHE)
1219 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_LEFT :
1220 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1221 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1222 else if (dir == MV_RIGHT)
1223 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_RIGHT :
1224 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1225 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1226 else if (dir == MV_UP)
1227 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_UP :
1228 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1229 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1231 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_DOWN :
1232 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1233 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1237 else if (element == EL_SONDE)
1239 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1241 else if (element == EL_SALZSAEURE)
1243 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1245 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1249 else if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK ||
1250 IS_GEM(element)) && !cut_mode)
1252 if (element == EL_FELSBROCKEN || element == EL_SP_ZONK)
1255 graphic += (4 - phase4) % 4;
1256 else if (dir == MV_RIGHT)
1259 graphic += phase2 * 2;
1261 else if (element != EL_SP_INFOTRON)
1265 if (element == EL_SP_ZONK)
1268 graphic += (4 - phase4) % 4;
1269 else if (dir == MV_RIGHT)
1272 graphic += phase2 * 2;
1274 else if (element != EL_SP_INFOTRON)
1275 graphic += phase2 * (element == EL_FELSBROCKEN ? 2 : 1);
1279 else if (element == EL_SIEB_LEER || element == EL_SIEB2_LEER ||
1280 element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL)
1282 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1284 else if (IS_AMOEBOID(element))
1286 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1287 graphic += (x + 2 * y + 4) % 4;
1289 else if (element == EL_MAUER_LEBT)
1291 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1293 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1294 links_massiv = TRUE;
1295 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1296 rechts_massiv = TRUE;
1298 if (links_massiv && rechts_massiv)
1299 graphic = GFX_MAUERWERK;
1300 else if (links_massiv)
1301 graphic = GFX_MAUER_R;
1302 else if (rechts_massiv)
1303 graphic = GFX_MAUER_L;
1307 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1308 else if (mask_mode == USE_MASKING)
1309 DrawGraphicThruMask(x, y, graphic);
1311 DrawGraphic(x, y, graphic);
1314 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1315 int cut_mode, int mask_mode)
1317 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1318 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1319 cut_mode, mask_mode);
1322 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1325 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1328 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1331 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1334 void DrawScreenElementThruMask(int x, int y, int element)
1336 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1339 void DrawLevelElementThruMask(int x, int y, int element)
1341 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1344 void DrawLevelFieldThruMask(int x, int y)
1346 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1349 void ErdreichAnbroeckeln(int x, int y)
1351 int i, width, height, cx,cy;
1352 int ux = LEVELX(x), uy = LEVELY(y);
1353 int element, graphic;
1355 static int xy[4][2] =
1363 if (!IN_LEV_FIELD(ux, uy))
1366 element = Feld[ux][uy];
1368 if (element == EL_ERDREICH)
1370 if (!IN_SCR_FIELD(x, y))
1373 graphic = GFX_ERDENRAND;
1379 uxx = ux + xy[i][0];
1380 uyy = uy + xy[i][1];
1381 if (!IN_LEV_FIELD(uxx, uyy))
1384 element = Feld[uxx][uyy];
1386 if (element == EL_ERDREICH)
1389 if (i == 1 || i == 2)
1393 cx = (i == 2 ? TILEX - snip : 0);
1401 cy = (i == 3 ? TILEY - snip : 0);
1404 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1405 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1406 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1407 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1410 MarkTileDirty(x, y);
1414 graphic = GFX_ERDENRAND;
1418 int xx, yy, uxx, uyy;
1422 uxx = ux + xy[i][0];
1423 uyy = uy + xy[i][1];
1425 if (!IN_LEV_FIELD(uxx, uyy) || Feld[uxx][uyy] != EL_ERDREICH ||
1426 !IN_SCR_FIELD(xx, yy))
1429 if (i == 1 || i == 2)
1433 cx = (i == 1 ? TILEX - snip : 0);
1441 cy = (i==0 ? TILEY-snip : 0);
1444 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1445 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1446 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1447 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1449 MarkTileDirty(xx, yy);
1454 void DrawScreenElement(int x, int y, int element)
1456 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1457 ErdreichAnbroeckeln(x, y);
1460 void DrawLevelElement(int x, int y, int element)
1462 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1463 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1466 void DrawScreenField(int x, int y)
1468 int ux = LEVELX(x), uy = LEVELY(y);
1471 if (!IN_LEV_FIELD(ux, uy))
1473 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1474 element = EL_LEERRAUM;
1476 element = BorderElement;
1478 DrawScreenElement(x, y, element);
1482 element = Feld[ux][uy];
1484 if (IS_MOVING(ux, uy))
1486 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1487 boolean cut_mode = NO_CUTTING;
1489 if (Store[ux][uy] == EL_MORAST_LEER ||
1490 Store[ux][uy] == EL_SIEB_LEER ||
1491 Store[ux][uy] == EL_SIEB2_LEER ||
1492 Store[ux][uy] == EL_AMOEBE_NASS)
1493 cut_mode = CUT_ABOVE;
1494 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1495 Store[ux][uy] == EL_SIEB_VOLL ||
1496 Store[ux][uy] == EL_SIEB2_VOLL)
1497 cut_mode = CUT_BELOW;
1499 if (cut_mode == CUT_ABOVE)
1500 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1502 DrawScreenElement(x, y, EL_LEERRAUM);
1505 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1507 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1509 if (Store[ux][uy] == EL_SALZSAEURE)
1510 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1512 else if (IS_BLOCKED(ux, uy))
1517 boolean cut_mode = NO_CUTTING;
1519 Blocked2Moving(ux, uy, &oldx, &oldy);
1522 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1523 MovDir[oldx][oldy] == MV_RIGHT);
1525 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1526 Store[oldx][oldy] == EL_SIEB_LEER ||
1527 Store[oldx][oldy] == EL_SIEB2_LEER ||
1528 Store[oldx][oldy] == EL_AMOEBE_NASS)
1529 cut_mode = CUT_ABOVE;
1531 DrawScreenElement(x, y, EL_LEERRAUM);
1532 element = Feld[oldx][oldy];
1535 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1537 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1539 else if (IS_DRAWABLE(element))
1540 DrawScreenElement(x, y, element);
1542 DrawScreenElement(x, y, EL_LEERRAUM);
1545 void DrawLevelField(int x, int y)
1547 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1548 DrawScreenField(SCREENX(x), SCREENY(y));
1549 else if (IS_MOVING(x, y))
1553 Moving2Blocked(x, y, &newx, &newy);
1554 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1555 DrawScreenField(SCREENX(newx), SCREENY(newy));
1557 else if (IS_BLOCKED(x, y))
1561 Blocked2Moving(x, y, &oldx, &oldy);
1562 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1563 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1567 void DrawMiniElement(int x, int y, int element)
1573 DrawMiniGraphic(x, y, -1);
1577 graphic = el2gfx(element);
1578 DrawMiniGraphic(x, y, graphic);
1581 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1583 int x = sx + scroll_x, y = sy + scroll_y;
1585 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1586 DrawMiniElement(sx, sy, EL_LEERRAUM);
1587 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1588 DrawMiniElement(sx, sy, Feld[x][y]);
1591 int steel_type, steel_position;
1594 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1595 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1596 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1597 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1598 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1599 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1602 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1603 steel_position = (x == -1 && y == -1 ? 0 :
1604 x == lev_fieldx && y == -1 ? 1 :
1605 x == -1 && y == lev_fieldy ? 2 :
1606 x == lev_fieldx && y == lev_fieldy ? 3 :
1607 x == -1 || x == lev_fieldx ? 4 :
1608 y == -1 || y == lev_fieldy ? 5 : -1);
1610 if (steel_position != -1)
1611 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1615 if (x == -1 && y == -1)
1616 DrawMiniGraphic(sx, sy, GFX_STEEL_UPPER_LEFT);
1617 else if (x == lev_fieldx && y == -1)
1618 DrawMiniGraphic(sx, sy, GFX_STEEL_UPPER_RIGHT);
1619 else if (x == -1 && y == lev_fieldy)
1620 DrawMiniGraphic(sx, sy, GFX_STEEL_LOWER_LEFT);
1621 else if (x == lev_fieldx && y == lev_fieldy)
1622 DrawMiniGraphic(sx, sy, GFX_STEEL_LOWER_RIGHT);
1623 else if (x == -1 || x == lev_fieldx)
1624 DrawMiniGraphic(sx, sy, GFX_STEEL_VERTICAL);
1625 else if (y == -1 || y == lev_fieldy)
1626 DrawMiniGraphic(sx, sy, GFX_STEEL_HORIZONTAL);
1633 void DrawMicroElement(int xpos, int ypos, int element)
1637 if (element == EL_LEERRAUM)
1640 graphic = el2gfx(element);
1642 if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1644 graphic -= GFX_START_ROCKSMORE;
1645 graphic -= ((graphic / MORE_PER_LINE) * MORE_PER_LINE) / 2;
1646 XCopyArea(display, pix[PIX_MORE], drawto, gc,
1647 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX,
1648 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY,
1649 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1652 XCopyArea(display, pix[PIX_BACK], drawto, gc,
1653 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1654 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1655 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1664 for(x=BX1; x<=BX2; x++)
1665 for(y=BY1; y<=BY2; y++)
1666 DrawScreenField(x, y);
1668 if (setup.soft_scrolling)
1669 XCopyArea(display, fieldbuffer, backbuffer, gc,
1670 FX, FY, SXSIZE, SYSIZE, SX, SY);
1672 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1675 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1679 for(x=0; x<size_x; x++)
1680 for(y=0; y<size_y; y++)
1681 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1683 redraw_mask |= REDRAW_FIELD;
1686 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1690 /* determine border element for this level */
1693 XFillRectangle(display, drawto, gc,
1694 xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1696 if (lev_fieldx < STD_LEV_FIELDX)
1697 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1698 if (lev_fieldy < STD_LEV_FIELDY)
1699 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1701 xpos += MICRO_TILEX;
1702 ypos += MICRO_TILEY;
1704 for(x=-1; x<=STD_LEV_FIELDX; x++)
1706 for(y=-1; y<=STD_LEV_FIELDY; y++)
1708 int lx = from_x + x, ly = from_y + y;
1710 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1711 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1713 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1714 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1719 redraw_mask |= REDRAW_MICROLEVEL;
1722 static void DrawMicroLevelLabelExt(int mode)
1724 char label_text[100];
1726 XFillRectangle(display, drawto,gc,
1727 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1729 strcpy(label_text, (mode == 1 ? level.name :
1730 mode == 2 ? "created by" :
1731 mode == 3 ? level.author : ""));
1733 if (strlen(label_text) > 0)
1735 int size, lxpos, lypos;
1737 label_text[SXSIZE / FONT4_XSIZE] = '\0';
1739 size = strlen(label_text);
1740 lxpos = SX + (SXSIZE - size * FONT4_XSIZE) / 2;
1741 lypos = MICROLABEL_YPOS;
1743 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1746 redraw_mask |= REDRAW_MICROLEVEL;
1749 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1751 static unsigned long scroll_delay = 0;
1752 static unsigned long label_delay = 0;
1753 static int from_x, from_y, scroll_direction;
1754 static int label_state, label_counter;
1758 from_x = from_y = 0;
1759 scroll_direction = MV_RIGHT;
1763 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1764 DrawMicroLevelLabelExt(label_state);
1766 /* initialize delay counters */
1767 DelayReached(&scroll_delay, 0);
1768 DelayReached(&label_delay, 0);
1773 /* scroll micro level, if needed */
1774 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1775 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1777 switch (scroll_direction)
1783 scroll_direction = MV_UP;
1787 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1790 scroll_direction = MV_DOWN;
1797 scroll_direction = MV_RIGHT;
1801 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1804 scroll_direction = MV_LEFT;
1811 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1814 /* redraw micro level label, if needed */
1815 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1816 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1817 strcmp(level.author, leveldir[leveldir_nr].name) != 0 &&
1818 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1820 label_counter = (label_counter + 1) % 23;
1821 label_state = (label_counter >= 0 && label_counter <= 7 ? 1 :
1822 label_counter >= 9 && label_counter <= 12 ? 2 :
1823 label_counter >= 14 && label_counter <= 21 ? 3 : 0);
1824 DrawMicroLevelLabelExt(label_state);
1828 int REQ_in_range(int x, int y)
1830 if (y > DY+249 && y < DY+278)
1832 if (x > DX+1 && x < DX+48)
1834 else if (x > DX+51 && x < DX+98)
1840 boolean Request(char *text, unsigned int req_state)
1842 int mx, my, ty, result = -1;
1843 unsigned int old_door_state;
1846 /* pause network game while waiting for request to answer */
1847 if (options.network &&
1848 game_status == PLAYING &&
1849 req_state & REQUEST_WAIT_FOR)
1850 SendToServer_PausePlaying();
1853 old_door_state = GetDoorState();
1857 CloseDoor(DOOR_CLOSE_1);
1859 /* save old door content */
1860 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
1861 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1862 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1864 /* clear door drawing field */
1866 XFillRectangle(display, pix[PIX_DB_DOOR], gc,
1867 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE);
1869 XFillRectangle(display, drawto, gc, DX, DY, DXSIZE, DYSIZE);
1872 /* write text for request */
1873 for(ty=0; ty<13; ty++)
1881 for(tl=0,tx=0; tx<7; tl++,tx++)
1884 if (!tc || tc == 32)
1896 DrawTextExt(pix[PIX_DB_DOOR], gc,
1897 DOOR_GFX_PAGEX1 + 51 - (tl * 14)/2, SY + ty * 16,
1898 txt, FS_SMALL, FC_YELLOW);
1900 DrawTextExt(drawto, gc,
1901 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1902 txt, FS_SMALL, FC_YELLOW);
1904 text += tl + (tc == 32 ? 1 : 0);
1908 if (req_state & REQ_ASK)
1910 DrawYesNoButton(BUTTON_OK, DB_INIT);
1911 DrawYesNoButton(BUTTON_NO, DB_INIT);
1913 else if (req_state & REQ_CONFIRM)
1915 DrawConfirmButton(BUTTON_CONFIRM, DB_INIT);
1917 else if (req_state & REQ_PLAYER)
1919 DrawPlayerButton(BUTTON_PLAYER_1, DB_INIT);
1920 DrawPlayerButton(BUTTON_PLAYER_2, DB_INIT);
1921 DrawPlayerButton(BUTTON_PLAYER_3, DB_INIT);
1922 DrawPlayerButton(BUTTON_PLAYER_4, DB_INIT);
1926 if (req_state & REQ_ASK)
1928 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1929 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1931 else if (req_state & REQ_CONFIRM)
1933 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1935 else if (req_state & REQ_PLAYER)
1937 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1938 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1939 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1940 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1943 /* copy request gadgets to door backbuffer */
1944 XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
1945 DX, DY, DXSIZE, DYSIZE,
1946 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1950 OpenDoor(DOOR_OPEN_1);
1953 if (!(req_state & REQUEST_WAIT_FOR))
1956 if (game_status != MAINMENU)
1959 button_status = MB_RELEASED;
1961 request_gadget_id = -1;
1965 if (XPending(display))
1969 XNextEvent(display, &event);
1982 if (event.type == MotionNotify)
1989 if (!XQueryPointer(display, window, &root, &child,
1990 &root_x, &root_y, &win_x, &win_y, &mask))
1996 motion_status = TRUE;
1997 mx = ((XMotionEvent *) &event)->x;
1998 my = ((XMotionEvent *) &event)->y;
2002 motion_status = FALSE;
2003 mx = ((XButtonEvent *) &event)->x;
2004 my = ((XButtonEvent *) &event)->y;
2005 if (event.type==ButtonPress)
2006 button_status = ((XButtonEvent *) &event)->button;
2008 button_status = MB_RELEASED;
2014 if (req_state & REQ_ASK)
2015 choice = CheckYesNoButtons(mx,my,button_status);
2016 else if (req_state & REQ_CONFIRM)
2017 choice = CheckConfirmButton(mx,my,button_status);
2019 choice = CheckPlayerButtons(mx,my,button_status);
2029 case BUTTON_CONFIRM:
2030 result = TRUE | FALSE;
2033 case BUTTON_PLAYER_1:
2036 case BUTTON_PLAYER_2:
2039 case BUTTON_PLAYER_3:
2042 case BUTTON_PLAYER_4:
2051 /* this sets 'request_gadget_id' */
2052 HandleGadgets(mx, my, button_status);
2054 switch(request_gadget_id)
2056 case TOOL_CTRL_ID_YES:
2059 case TOOL_CTRL_ID_NO:
2062 case TOOL_CTRL_ID_CONFIRM:
2063 result = TRUE | FALSE;
2066 case TOOL_CTRL_ID_PLAYER_1:
2069 case TOOL_CTRL_ID_PLAYER_2:
2072 case TOOL_CTRL_ID_PLAYER_3:
2075 case TOOL_CTRL_ID_PLAYER_4:
2088 switch(XLookupKeysym((XKeyEvent *)&event,
2089 ((XKeyEvent *)&event)->state))
2102 if (req_state & REQ_PLAYER)
2107 key_joystick_mapping = 0;
2111 HandleOtherEvents(&event);
2115 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2117 int joy = AnyJoystick();
2119 if (joy & JOY_BUTTON_1)
2121 else if (joy & JOY_BUTTON_2)
2127 /* don't eat all CPU time */
2131 if (game_status != MAINMENU)
2136 if (!(req_state & REQ_STAY_OPEN))
2138 CloseDoor(DOOR_CLOSE_1);
2140 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2142 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
2143 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2144 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2145 OpenDoor(DOOR_OPEN_1);
2152 /* continue network game after request */
2153 if (options.network &&
2154 game_status == PLAYING &&
2155 req_state & REQUEST_WAIT_FOR)
2156 SendToServer_ContinuePlaying();
2162 unsigned int OpenDoor(unsigned int door_state)
2164 unsigned int new_door_state;
2166 if (door_state & DOOR_COPY_BACK)
2168 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
2169 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2170 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2171 door_state &= ~DOOR_COPY_BACK;
2174 new_door_state = MoveDoor(door_state);
2176 return(new_door_state);
2179 unsigned int CloseDoor(unsigned int door_state)
2181 unsigned int new_door_state;
2183 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
2184 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2185 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
2186 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2188 new_door_state = MoveDoor(door_state);
2190 return(new_door_state);
2193 unsigned int GetDoorState()
2195 return(MoveDoor(DOOR_GET_STATE));
2198 unsigned int MoveDoor(unsigned int door_state)
2200 static int door1 = DOOR_OPEN_1;
2201 static int door2 = DOOR_CLOSE_2;
2202 static unsigned long door_delay = 0;
2203 int x, start, stepsize = 2;
2204 unsigned long door_delay_value = stepsize * 5;
2206 if (door_state == DOOR_GET_STATE)
2207 return(door1 | door2);
2209 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2210 door_state &= ~DOOR_OPEN_1;
2211 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2212 door_state &= ~DOOR_CLOSE_1;
2213 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2214 door_state &= ~DOOR_OPEN_2;
2215 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2216 door_state &= ~DOOR_CLOSE_2;
2218 if (setup.quick_doors)
2221 door_delay_value = 0;
2222 StopSound(SND_OEFFNEN);
2225 if (door_state & DOOR_ACTION)
2227 if (!(door_state & DOOR_NO_DELAY))
2228 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2230 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2232 for(x=start; x<=DXSIZE; x+=stepsize)
2234 WaitUntilDelayReached(&door_delay, door_delay_value);
2236 if (door_state & DOOR_ACTION_1)
2238 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2239 int j = (DXSIZE - i) / 3;
2241 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
2242 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2243 DXSIZE,DYSIZE - i/2, DX, DY);
2245 XFillRectangle(display, drawto, gc, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2247 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2248 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2249 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
2250 DXSIZE, DOOR_GFX_PAGEY1, i, 77, DX + DXSIZE - i, DY + j);
2251 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2252 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63, DX + DXSIZE - i,
2254 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2255 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2256 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2257 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j, DX, DY);
2258 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2259 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63, DX, DY + 140 - j);
2261 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2262 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2264 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2265 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2267 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2268 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2269 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2270 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2271 DX + DXSIZE - i, DY + 77 + j);
2272 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2273 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2274 DX + DXSIZE - i, DY + 203 + j);
2276 redraw_mask |= REDRAW_DOOR_1;
2279 if (door_state & DOOR_ACTION_2)
2281 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2282 int j = (VXSIZE - i) / 3;
2284 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
2285 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2286 VXSIZE, VYSIZE - i/2, VX, VY);
2288 XFillRectangle(display, drawto, gc, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2290 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2291 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2292 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2293 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2, VX + VXSIZE-i, VY+j);
2294 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2295 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2296 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
2297 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j, VX, VY);
2299 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2300 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2,
2301 VX, VY + VYSIZE / 2 - j);
2302 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2303 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2304 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2305 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2 - j,
2306 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2308 redraw_mask |= REDRAW_DOOR_2;
2316 XCopyArea(display, drawto, window, gc, DX, DY, DXSIZE, DYSIZE, DX, DY);
2321 if (game_status == MAINMENU)
2326 if (setup.quick_doors)
2327 StopSound(SND_OEFFNEN);
2329 if (door_state & DOOR_ACTION_1)
2330 door1 = door_state & DOOR_ACTION_1;
2331 if (door_state & DOOR_ACTION_2)
2332 door2 = door_state & DOOR_ACTION_2;
2334 return(door1 | door2);
2337 int ReadPixel(Drawable d, int x, int y)
2339 XImage *pixel_image;
2340 unsigned long pixel_value;
2342 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
2343 pixel_value = XGetPixel(pixel_image, 0, 0);
2345 XDestroyImage(pixel_image);
2350 /* ---------- new tool button stuff ---------------------------------------- */
2352 /* graphic position values for tool buttons */
2353 #define TOOL_BUTTON_YES_XPOS 2
2354 #define TOOL_BUTTON_YES_YPOS 250
2355 #define TOOL_BUTTON_YES_GFX_YPOS 0
2356 #define TOOL_BUTTON_YES_XSIZE 46
2357 #define TOOL_BUTTON_YES_YSIZE 28
2358 #define TOOL_BUTTON_NO_XPOS 52
2359 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2360 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2361 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2362 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2363 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2364 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2365 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2366 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2367 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2368 #define TOOL_BUTTON_PLAYER_XSIZE 30
2369 #define TOOL_BUTTON_PLAYER_YSIZE 30
2370 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2371 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2372 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2373 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2374 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2375 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2376 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2377 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2378 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2379 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2380 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2381 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2382 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2383 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2384 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2385 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2386 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2387 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2388 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2389 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2398 } toolbutton_info[NUM_TOOL_BUTTONS] =
2401 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2402 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2403 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2408 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2409 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2410 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2415 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2416 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2417 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2418 TOOL_CTRL_ID_CONFIRM,
2422 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2423 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2424 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2425 TOOL_CTRL_ID_PLAYER_1,
2429 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2430 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2431 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2432 TOOL_CTRL_ID_PLAYER_2,
2436 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2437 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2438 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2439 TOOL_CTRL_ID_PLAYER_3,
2443 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2444 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2445 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2446 TOOL_CTRL_ID_PLAYER_4,
2451 void CreateToolButtons()
2455 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2457 Pixmap gd_pixmap = pix[PIX_DOOR];
2458 Pixmap deco_pixmap = None;
2459 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2460 struct GadgetInfo *gi;
2461 unsigned long event_mask;
2462 int gd_xoffset, gd_yoffset;
2463 int gd_x1, gd_x2, gd_y;
2466 event_mask = GD_EVENT_RELEASED;
2468 gd_xoffset = toolbutton_info[i].xpos;
2469 gd_yoffset = toolbutton_info[i].ypos;
2470 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2471 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2472 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2474 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2476 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2477 &deco_pixmap, &deco_x, &deco_y);
2478 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2479 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2482 gi = CreateGadget(GDI_CUSTOM_ID, id,
2483 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2484 GDI_X, DX + toolbutton_info[i].x,
2485 GDI_Y, DY + toolbutton_info[i].y,
2486 GDI_WIDTH, toolbutton_info[i].width,
2487 GDI_HEIGHT, toolbutton_info[i].height,
2488 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2489 GDI_STATE, GD_BUTTON_UNPRESSED,
2490 GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
2491 GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
2492 GDI_DECORATION_DESIGN, deco_pixmap, deco_x, deco_y,
2493 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2494 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2495 GDI_DECORATION_SHIFTING, 1, 1,
2496 GDI_EVENT_MASK, event_mask,
2497 GDI_CALLBACK_ACTION, HandleToolButtons,
2501 Error(ERR_EXIT, "cannot create gadget");
2503 tool_gadget[id] = gi;
2507 static void UnmapToolButtons()
2511 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2512 UnmapGadget(tool_gadget[i]);
2515 static void HandleToolButtons(struct GadgetInfo *gi)
2517 request_gadget_id = gi->custom_id;
2521 int id = gi->custom_id;
2523 if (game_status != PLAYING)
2528 case GAME_CTRL_ID_STOP:
2531 CloseDoor(DOOR_CLOSE_1);
2532 game_status = MAINMENU;
2537 if (Request("Do you really want to quit the game ?",
2538 REQ_ASK | REQ_STAY_CLOSED))
2541 if (options.network)
2542 SendToServer_StopPlaying();
2546 game_status = MAINMENU;
2551 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
2554 case GAME_CTRL_ID_PAUSE:
2555 if (options.network)
2559 SendToServer_ContinuePlaying();
2561 SendToServer_PausePlaying();
2568 case GAME_CTRL_ID_PLAY:
2572 if (options.network)
2573 SendToServer_ContinuePlaying();
2577 tape.pausing = FALSE;
2578 DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
2583 case SOUND_CTRL_ID_MUSIC:
2584 if (setup.sound_music)
2586 setup.sound_music = FALSE;
2587 FadeSound(background_loop[level_nr % num_bg_loops]);
2589 else if (sound_loops_allowed)
2591 setup.sound = setup.sound_music = TRUE;
2592 PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
2596 case SOUND_CTRL_ID_LOOPS:
2597 if (setup.sound_loops)
2598 setup.sound_loops = FALSE;
2599 else if (sound_loops_allowed)
2600 setup.sound = setup.sound_loops = TRUE;
2603 case SOUND_CTRL_ID_SIMPLE:
2604 if (setup.sound_simple)
2605 setup.sound_simple = FALSE;
2606 else if (sound_status==SOUND_AVAILABLE)
2607 setup.sound = setup.sound_simple = TRUE;
2619 int el2gfx(int element)
2623 case EL_LEERRAUM: return -1;
2624 case EL_ERDREICH: return GFX_ERDREICH;
2625 case EL_MAUERWERK: return GFX_MAUERWERK;
2626 case EL_FELSBODEN: return GFX_FELSBODEN;
2627 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2628 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2629 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2630 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2631 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2632 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2633 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2634 case EL_SPIELER1: return GFX_SPIELER1;
2635 case EL_SPIELER2: return GFX_SPIELER2;
2636 case EL_SPIELER3: return GFX_SPIELER3;
2637 case EL_SPIELER4: return GFX_SPIELER4;
2638 case EL_KAEFER: return GFX_KAEFER;
2639 case EL_KAEFER_R: return GFX_KAEFER_R;
2640 case EL_KAEFER_O: return GFX_KAEFER_O;
2641 case EL_KAEFER_L: return GFX_KAEFER_L;
2642 case EL_KAEFER_U: return GFX_KAEFER_U;
2643 case EL_FLIEGER: return GFX_FLIEGER;
2644 case EL_FLIEGER_R: return GFX_FLIEGER_R;
2645 case EL_FLIEGER_O: return GFX_FLIEGER_O;
2646 case EL_FLIEGER_L: return GFX_FLIEGER_L;
2647 case EL_FLIEGER_U: return GFX_FLIEGER_U;
2648 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2649 case EL_BUTTERFLY_R: return GFX_BUTTERFLY_R;
2650 case EL_BUTTERFLY_O: return GFX_BUTTERFLY_O;
2651 case EL_BUTTERFLY_L: return GFX_BUTTERFLY_L;
2652 case EL_BUTTERFLY_U: return GFX_BUTTERFLY_U;
2653 case EL_FIREFLY: return GFX_FIREFLY;
2654 case EL_FIREFLY_R: return GFX_FIREFLY_R;
2655 case EL_FIREFLY_O: return GFX_FIREFLY_O;
2656 case EL_FIREFLY_L: return GFX_FIREFLY_L;
2657 case EL_FIREFLY_U: return GFX_FIREFLY_U;
2658 case EL_MAMPFER: return GFX_MAMPFER;
2659 case EL_ROBOT: return GFX_ROBOT;
2660 case EL_BETON: return GFX_BETON;
2661 case EL_DIAMANT: return GFX_DIAMANT;
2662 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2663 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2664 case EL_TROPFEN: return GFX_TROPFEN;
2665 case EL_BOMBE: return GFX_BOMBE;
2666 case EL_SIEB_INAKTIV: return GFX_SIEB_INAKTIV;
2667 case EL_SIEB_LEER: return GFX_SIEB_LEER;
2668 case EL_SIEB_VOLL: return GFX_SIEB_VOLL;
2669 case EL_SIEB_TOT: return GFX_SIEB_TOT;
2670 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2671 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2672 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2673 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2674 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2675 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2676 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2677 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2678 case EL_LIFE: return GFX_LIFE;
2679 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2680 case EL_DYNAMIT: return GFX_DYNAMIT;
2681 case EL_BADEWANNE: return GFX_BADEWANNE;
2682 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2683 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2684 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2685 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2686 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2687 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2688 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2689 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2690 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2691 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2692 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2693 case EL_PFORTE1: return GFX_PFORTE1;
2694 case EL_PFORTE2: return GFX_PFORTE2;
2695 case EL_PFORTE3: return GFX_PFORTE3;
2696 case EL_PFORTE4: return GFX_PFORTE4;
2697 case EL_PFORTE1X: return GFX_PFORTE1X;
2698 case EL_PFORTE2X: return GFX_PFORTE2X;
2699 case EL_PFORTE3X: return GFX_PFORTE3X;
2700 case EL_PFORTE4X: return GFX_PFORTE4X;
2701 case EL_DYNAMIT_AUS: return GFX_DYNAMIT_AUS;
2702 case EL_PACMAN: return GFX_PACMAN;
2703 case EL_PACMAN_R: return GFX_PACMAN_R;
2704 case EL_PACMAN_O: return GFX_PACMAN_O;
2705 case EL_PACMAN_L: return GFX_PACMAN_L;
2706 case EL_PACMAN_U: return GFX_PACMAN_U;
2707 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2708 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2709 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2710 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2711 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2712 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2713 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2714 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2715 case EL_MAUER_X: return GFX_MAUER_X;
2716 case EL_MAUER_Y: return GFX_MAUER_Y;
2717 case EL_MAUER_XY: return GFX_MAUER_XY;
2718 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2719 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2720 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2721 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2722 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2723 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2724 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2725 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2726 case EL_MAMPFER2: return GFX_MAMPFER2;
2727 case EL_SIEB2_INAKTIV: return GFX_SIEB2_INAKTIV;
2728 case EL_SIEB2_LEER: return GFX_SIEB2_LEER;
2729 case EL_SIEB2_VOLL: return GFX_SIEB2_VOLL;
2730 case EL_SIEB2_TOT: return GFX_SIEB2_TOT;
2731 case EL_DYNABOMB: return GFX_DYNABOMB;
2732 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2733 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2734 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2735 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2736 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2737 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2738 case EL_MAULWURF: return GFX_MAULWURF;
2739 case EL_PINGUIN: return GFX_PINGUIN;
2740 case EL_SCHWEIN: return GFX_SCHWEIN;
2741 case EL_DRACHE: return GFX_DRACHE;
2742 case EL_SONDE: return GFX_SONDE;
2743 case EL_PFEIL_L: return GFX_PFEIL_L;
2744 case EL_PFEIL_R: return GFX_PFEIL_R;
2745 case EL_PFEIL_O: return GFX_PFEIL_O;
2746 case EL_PFEIL_U: return GFX_PFEIL_U;
2747 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2748 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2749 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2750 case EL_SP_ZONK: return GFX_SP_ZONK;
2751 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2752 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2753 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2754 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2755 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2756 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2757 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2758 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2759 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2760 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2761 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2762 case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
2763 case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
2764 case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
2765 case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
2766 case EL_EM_KEY_1: return GFX_EM_KEY_1;
2767 case EL_EM_KEY_2: return GFX_EM_KEY_2;
2768 case EL_EM_KEY_3: return GFX_EM_KEY_3;
2769 case EL_EM_KEY_4: return GFX_EM_KEY_4;
2773 if (IS_CHAR(element))
2774 return GFX_CHAR_START + (element - EL_CHAR_START);
2775 else if (element >= EL_SP_START && element <= EL_SP_END)
2777 int nr_element = element - EL_SP_START;
2778 int gfx_per_line = 8;
2780 (nr_element / gfx_per_line) * MORE_PER_LINE +
2781 (nr_element % gfx_per_line);
2783 return GFX_START_ROCKSMORE + nr_graphic;