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 boolean action_moving =
532 ((player->action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
533 !(player->action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
535 graphic = GFX_SP_MURPHY;
539 if (player->MovDir == MV_LEFT)
540 graphic = GFX_MURPHY_PUSH_LEFT;
541 else if (player->MovDir == MV_RIGHT)
542 graphic = GFX_MURPHY_PUSH_RIGHT;
543 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
544 graphic = GFX_MURPHY_PUSH_LEFT;
545 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
546 graphic = GFX_MURPHY_PUSH_RIGHT;
548 else if (player->snapped)
550 if (player->MovDir == MV_LEFT)
551 graphic = GFX_MURPHY_SNAP_LEFT;
552 else if (player->MovDir == MV_RIGHT)
553 graphic = GFX_MURPHY_SNAP_RIGHT;
554 else if (player->MovDir == MV_UP)
555 graphic = GFX_MURPHY_SNAP_UP;
556 else if (player->MovDir == MV_DOWN)
557 graphic = GFX_MURPHY_SNAP_DOWN;
559 else if (action_moving)
561 if (player->MovDir == MV_LEFT)
562 graphic = GFX_MURPHY_GO_LEFT;
563 else if (player->MovDir == MV_RIGHT)
564 graphic = GFX_MURPHY_GO_RIGHT;
565 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
566 graphic = GFX_MURPHY_GO_LEFT;
567 else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
568 graphic = GFX_MURPHY_GO_RIGHT;
570 graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
573 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
574 last_dir = player->MovDir;
578 if (player->MovDir == MV_LEFT)
580 (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
581 else if (player->MovDir == MV_RIGHT)
583 (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
584 else if (player->MovDir == MV_UP)
585 graphic = GFX_SPIELER1_UP;
586 else /* MV_DOWN || MV_NO_MOVING */
587 graphic = GFX_SPIELER1_DOWN;
589 graphic += player->index_nr * 3 * HEROES_PER_LINE;
590 graphic += player->Frame;
595 if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
596 sxx = player->GfxPos;
598 syy = player->GfxPos;
601 if (!setup.soft_scrolling && ScreenMovPos)
604 DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
606 if (player->Pushing && player->GfxPos)
608 int px = SCREENX(next_jx), py = SCREENY(next_jy);
610 if (element == EL_SOKOBAN_FELD_LEER ||
611 Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
612 DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
616 int element = Feld[next_jx][next_jy];
617 int graphic = el2gfx(element);
619 if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK) && sxx)
621 int phase = (player->GfxPos / (TILEX / 4));
623 if (player->MovDir == MV_LEFT)
626 graphic += (phase + 4) % 4;
629 DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
633 /* draw things in front of player (EL_DYNAMIT or EL_DYNABOMB) */
635 if (element == EL_DYNAMIT || element == EL_DYNABOMB)
637 graphic = el2gfx(element);
639 if (element == EL_DYNAMIT)
641 if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
646 if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
650 if (game_emulation == EMU_SUPAPLEX)
651 DrawGraphic(sx, sy, GFX_SP_DISK_RED);
653 DrawGraphicThruMask(sx, sy, graphic + phase);
657 if ((last_jx != jx || last_jy != jy) && last_element == EL_EXPLODING)
660 if (player_is_moving && last_element == EL_EXPLODING)
662 int phase = Frame[last_jx][last_jy];
666 DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
667 GFX_EXPLOSION + ((phase - 1) / delay - 1));
670 /* draw elements that stay over the player */
671 /* handle the field the player is leaving ... */
672 if (player_is_moving && IS_OVER_PLAYER(last_element))
673 DrawLevelField(last_jx, last_jy);
674 /* ... and the field the player is entering */
675 if (IS_OVER_PLAYER(element))
676 DrawLevelField(jx, jy);
678 if (setup.direct_draw)
680 int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
681 int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
682 int x_size = TILEX * (1 + ABS(jx - last_jx));
683 int y_size = TILEY * (1 + ABS(jy - last_jy));
685 XCopyArea(display, drawto_field, window, gc,
686 dest_x, dest_y, x_size, y_size, dest_x, dest_y);
687 SetDrawtoField(DRAW_DIRECT);
690 MarkTileDirty(sx,sy);
693 static int getGraphicAnimationPhase(int frames, int delay, int mode)
697 if (mode == ANIM_OSCILLATE)
699 int max_anim_frames = 2 * frames - 2;
700 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
701 phase = (phase < frames ? phase : max_anim_frames - phase);
704 phase = (FrameCounter % (delay * frames)) / delay;
706 if (mode == ANIM_REVERSE)
712 void DrawGraphicAnimationExt(int x, int y, int graphic,
713 int frames, int delay, int mode, int mask_mode)
715 int phase = getGraphicAnimationPhase(frames, delay, mode);
717 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
719 if (mask_mode == USE_MASKING)
720 DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
722 DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
726 void DrawGraphicAnimation(int x, int y, int graphic,
727 int frames, int delay, int mode)
729 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
732 void DrawGraphicAnimationThruMask(int x, int y, int graphic,
733 int frames, int delay, int mode)
735 DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
738 void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y)
740 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
742 graphic -= GFX_START_ROCKSSCREEN;
743 *pixmap_nr = PIX_BACK;
744 *x = SX + (graphic % GFX_PER_LINE) * TILEX;
745 *y = SY + (graphic / GFX_PER_LINE) * TILEY;
747 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
749 graphic -= GFX_START_ROCKSMORE;
750 *pixmap_nr = PIX_MORE;
751 *x = (graphic % MORE_PER_LINE) * TILEX;
752 *y = (graphic / MORE_PER_LINE) * TILEY;
754 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
756 graphic -= GFX_START_ROCKSHEROES;
757 *pixmap_nr = PIX_HEROES;
758 *x = (graphic % HEROES_PER_LINE) * TILEX;
759 *y = (graphic / HEROES_PER_LINE) * TILEY;
761 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
763 graphic -= GFX_START_ROCKSFONT;
764 *pixmap_nr = PIX_BIGFONT;
765 *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
766 *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
767 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
771 *pixmap_nr = PIX_MORE;
777 void DrawGraphic(int x, int y, int graphic)
780 if (!IN_SCR_FIELD(x,y))
782 printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
783 printf("DrawGraphic(): This should never happen!\n");
788 DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
792 void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
800 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
801 XCopyArea(display, pix[pixmap_nr], d, gc,
802 src_x, src_y, TILEX, TILEY, x, y);
806 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
808 graphic -= GFX_START_ROCKSSCREEN;
809 XCopyArea(display, pix[PIX_BACK], d, gc,
810 SX + (graphic % GFX_PER_LINE) * TILEX,
811 SY + (graphic / GFX_PER_LINE) * TILEY,
814 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
816 graphic -= GFX_START_ROCKSMORE;
817 XCopyArea(display, pix[PIX_MORE], d, gc,
818 (graphic % MORE_PER_LINE) * TILEX,
819 (graphic / MORE_PER_LINE) * TILEY,
822 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
824 graphic -= GFX_START_ROCKSHEROES;
825 XCopyArea(display, pix[PIX_HEROES], d, gc,
826 (graphic % HEROES_PER_LINE) * TILEX,
827 (graphic / HEROES_PER_LINE) * TILEY,
830 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
832 graphic -= GFX_START_ROCKSFONT;
833 XCopyArea(display, pix[PIX_BIGFONT], d, gc,
834 (graphic % FONT_CHARS_PER_LINE) * TILEX,
835 (graphic / FONT_CHARS_PER_LINE) * TILEY +
836 FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY,
840 XFillRectangle(display, d, gc, x, y, TILEX, TILEY);
846 void DrawGraphicThruMask(int x, int y, int graphic)
849 if (!IN_SCR_FIELD(x,y))
851 printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
852 printf("DrawGraphicThruMask(): This should never happen!\n");
857 DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
861 void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
872 if (graphic == GFX_LEERRAUM)
875 getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
876 src_pixmap = pix[pixmap_nr];
877 drawing_gc = clip_gc[pixmap_nr];
886 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
888 src_pixmap = pix[PIX_BACK];
889 drawing_gc = clip_gc[PIX_BACK];
890 graphic -= GFX_START_ROCKSSCREEN;
891 src_x = SX + (graphic % GFX_PER_LINE) * TILEX;
892 src_y = SY + (graphic / GFX_PER_LINE) * TILEY;
894 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
896 src_pixmap = pix[PIX_MORE];
897 drawing_gc = clip_gc[PIX_MORE];
898 graphic -= GFX_START_ROCKSMORE;
899 src_x = (graphic % MORE_PER_LINE) * TILEX;
900 src_y = (graphic / MORE_PER_LINE) * TILEY;
902 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
904 src_pixmap = pix[PIX_HEROES];
905 drawing_gc = clip_gc[PIX_HEROES];
906 graphic -= GFX_START_ROCKSHEROES;
907 src_x = (graphic % HEROES_PER_LINE) * TILEX;
908 src_y = (graphic / HEROES_PER_LINE) * TILEY;
912 DrawGraphicExt(d, gc, dest_x,dest_y, graphic);
919 if (tile_clipmask[tile] != None)
921 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
922 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
923 XCopyArea(display, src_pixmap, d, tile_clip_gc,
924 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
929 printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
932 XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
933 XCopyArea(display, src_pixmap, d, drawing_gc,
934 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
938 void DrawMiniGraphic(int x, int y, int graphic)
940 DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
941 MarkTileDirty(x/2, y/2);
944 void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y)
946 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
948 graphic -= GFX_START_ROCKSSCREEN;
949 *pixmap = pix[PIX_BACK];
950 *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
951 *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
953 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
955 graphic -= GFX_START_ROCKSMORE;
956 graphic -= ((graphic / MORE_PER_LINE) * MORE_PER_LINE) / 2;
957 *pixmap = pix[PIX_MORE];
958 *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
959 *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
961 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
963 graphic -= GFX_START_ROCKSFONT;
964 *pixmap = pix[PIX_SMALLFONT];
965 *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
966 *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
967 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
971 *pixmap = pix[PIX_MORE];
972 *x = MINI_MORE_STARTX;
973 *y = MINI_MORE_STARTY;
977 void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
985 getMiniGraphicSource(graphic, &pixmap, &src_x, &src_y);
986 XCopyArea(display, pixmap, d, gc,
987 src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
991 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
993 graphic -= GFX_START_ROCKSSCREEN;
994 XCopyArea(display, pix[PIX_BACK], d, gc,
995 MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX,
996 MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY,
997 MINI_TILEX, MINI_TILEY, x, y);
999 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1001 graphic -= GFX_START_ROCKSMORE;
1002 XCopyArea(display, pix[PIX_MORE], d, gc,
1003 MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX,
1004 MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY,
1005 MINI_TILEX, MINI_TILEY, x, y);
1007 else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
1009 graphic -= GFX_START_ROCKSFONT;
1010 XCopyArea(display, pix[PIX_SMALLFONT], d, gc,
1011 (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE,
1012 (graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
1013 FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT,
1014 MINI_TILEX, MINI_TILEY, x, y);
1017 XFillRectangle(display, d, gc, x, y, MINI_TILEX, MINI_TILEY);
1023 void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
1024 int cut_mode, int mask_mode)
1026 int width = TILEX, height = TILEY;
1028 int src_x, src_y, dest_x, dest_y;
1035 DrawGraphic(x, y, graphic);
1039 if (dx || dy) /* Verschiebung der Grafik? */
1041 if (x < BX1) /* Element kommt von links ins Bild */
1048 else if (x > BX2) /* Element kommt von rechts ins Bild */
1054 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
1060 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
1062 else if (dx) /* allg. Bewegung in x-Richtung */
1063 MarkTileDirty(x + SIGN(dx), y);
1065 if (y < BY1) /* Element kommt von oben ins Bild */
1067 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
1075 else if (y > BY2) /* Element kommt von unten ins Bild */
1081 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
1087 else if (dy > 0 && cut_mode == CUT_ABOVE)
1089 if (y == BY2) /* Element unterhalb des Bildes */
1095 MarkTileDirty(x, y + 1);
1096 } /* Element verläßt unten das Bild */
1097 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
1099 else if (dy) /* allg. Bewegung in y-Richtung */
1100 MarkTileDirty(x, y + SIGN(dy));
1103 if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
1105 src_pixmap = pix[PIX_BACK];
1106 drawing_gc = clip_gc[PIX_BACK];
1107 graphic -= GFX_START_ROCKSSCREEN;
1108 src_x = SX + (graphic % GFX_PER_LINE) * TILEX + cx;
1109 src_y = SY + (graphic / GFX_PER_LINE) * TILEY + cy;
1111 else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1113 src_pixmap = pix[PIX_MORE];
1114 drawing_gc = clip_gc[PIX_MORE];
1115 graphic -= GFX_START_ROCKSMORE;
1116 src_x = (graphic % MORE_PER_LINE) * TILEX + cx;
1117 src_y = (graphic / MORE_PER_LINE) * TILEY + cy;
1119 else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
1121 src_pixmap = pix[PIX_HEROES];
1122 drawing_gc = clip_gc[PIX_HEROES];
1123 graphic -= GFX_START_ROCKSHEROES;
1124 src_x = (graphic % HEROES_PER_LINE) * TILEX + cx;
1125 src_y = (graphic / HEROES_PER_LINE) * TILEY + cy;
1127 else /* big font graphics currently not allowed (and not needed) */
1130 dest_x = FX + x * TILEX + dx;
1131 dest_y = FY + y * TILEY + dy;
1134 if (!IN_SCR_FIELD(x,y))
1136 printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
1137 printf("DrawGraphicShifted(): This should never happen!\n");
1142 if (mask_mode == USE_MASKING)
1144 if (tile_clipmask[tile] != None)
1146 XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
1147 XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
1148 XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
1149 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
1154 printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
1157 XSetClipOrigin(display, drawing_gc, dest_x - src_x, dest_y - src_y);
1158 XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
1159 src_x, src_y, width, height, dest_x, dest_y);
1163 XCopyArea(display, src_pixmap, drawto_field, gc,
1164 src_x, src_y, width, height, dest_x, dest_y);
1169 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
1172 DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
1175 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
1176 int cut_mode, int mask_mode)
1178 int ux = LEVELX(x), uy = LEVELY(y);
1179 int graphic = el2gfx(element);
1180 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
1181 int phase4 = phase8 / 2;
1182 int phase2 = phase8 / 4;
1183 int dir = MovDir[ux][uy];
1185 if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
1187 graphic += 4 * !phase2;
1191 else if (dir == MV_LEFT)
1193 else if (dir == MV_DOWN)
1196 else if (element == EL_SP_SNIKSNAK)
1199 graphic = GFX_SP_SNIKSNAK_LEFT;
1200 else if (dir == MV_RIGHT)
1201 graphic = GFX_SP_SNIKSNAK_RIGHT;
1202 else if (dir == MV_UP)
1203 graphic = GFX_SP_SNIKSNAK_UP;
1205 graphic = GFX_SP_SNIKSNAK_DOWN;
1207 graphic += (phase8 < 4 ? phase8 : 7 - phase8);
1209 else if (element == EL_SP_ELECTRON)
1211 graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1213 else if (element == EL_MAULWURF || element == EL_PINGUIN ||
1214 element == EL_SCHWEIN || element == EL_DRACHE)
1217 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_LEFT :
1218 element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
1219 element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
1220 else if (dir == MV_RIGHT)
1221 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_RIGHT :
1222 element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
1223 element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
1224 else if (dir == MV_UP)
1225 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_UP :
1226 element == EL_PINGUIN ? GFX_PINGUIN_UP :
1227 element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
1229 graphic = (element == EL_MAULWURF ? GFX_MAULWURF_DOWN :
1230 element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
1231 element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
1235 else if (element == EL_SONDE)
1237 graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
1239 else if (element == EL_SALZSAEURE)
1241 graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
1243 else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
1247 else if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK ||
1248 IS_GEM(element)) && !cut_mode)
1250 if (element == EL_FELSBROCKEN || element == EL_SP_ZONK)
1253 graphic += (4 - phase4) % 4;
1254 else if (dir == MV_RIGHT)
1257 graphic += phase2 * 2;
1259 else if (element != EL_SP_INFOTRON)
1263 if (element == EL_SP_ZONK)
1266 graphic += (4 - phase4) % 4;
1267 else if (dir == MV_RIGHT)
1270 graphic += phase2 * 2;
1272 else if (element != EL_SP_INFOTRON)
1273 graphic += phase2 * (element == EL_FELSBROCKEN ? 2 : 1);
1277 else if (element == EL_SIEB_LEER || element == EL_SIEB2_LEER ||
1278 element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL)
1280 graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
1282 else if (IS_AMOEBOID(element))
1284 graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
1285 graphic += (x + 2 * y + 4) % 4;
1287 else if (element == EL_MAUER_LEBT)
1289 boolean links_massiv = FALSE, rechts_massiv = FALSE;
1291 if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
1292 links_massiv = TRUE;
1293 if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
1294 rechts_massiv = TRUE;
1296 if (links_massiv && rechts_massiv)
1297 graphic = GFX_MAUERWERK;
1298 else if (links_massiv)
1299 graphic = GFX_MAUER_R;
1300 else if (rechts_massiv)
1301 graphic = GFX_MAUER_L;
1305 DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
1306 else if (mask_mode == USE_MASKING)
1307 DrawGraphicThruMask(x, y, graphic);
1309 DrawGraphic(x, y, graphic);
1312 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
1313 int cut_mode, int mask_mode)
1315 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1316 DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
1317 cut_mode, mask_mode);
1320 void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
1323 DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1326 void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
1329 DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
1332 void DrawScreenElementThruMask(int x, int y, int element)
1334 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1337 void DrawLevelElementThruMask(int x, int y, int element)
1339 DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
1342 void DrawLevelFieldThruMask(int x, int y)
1344 DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
1347 void ErdreichAnbroeckeln(int x, int y)
1349 int i, width, height, cx,cy;
1350 int ux = LEVELX(x), uy = LEVELY(y);
1351 int element, graphic;
1353 static int xy[4][2] =
1361 if (!IN_LEV_FIELD(ux, uy))
1364 element = Feld[ux][uy];
1366 if (element == EL_ERDREICH)
1368 if (!IN_SCR_FIELD(x, y))
1371 graphic = GFX_ERDENRAND;
1377 uxx = ux + xy[i][0];
1378 uyy = uy + xy[i][1];
1379 if (!IN_LEV_FIELD(uxx, uyy))
1382 element = Feld[uxx][uyy];
1384 if (element == EL_ERDREICH)
1387 if (i == 1 || i == 2)
1391 cx = (i == 2 ? TILEX - snip : 0);
1399 cy = (i == 3 ? TILEY - snip : 0);
1402 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1403 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1404 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1405 width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
1408 MarkTileDirty(x, y);
1412 graphic = GFX_ERDENRAND;
1416 int xx, yy, uxx, uyy;
1420 uxx = ux + xy[i][0];
1421 uyy = uy + xy[i][1];
1423 if (!IN_LEV_FIELD(uxx, uyy) || Feld[uxx][uyy] != EL_ERDREICH ||
1424 !IN_SCR_FIELD(xx, yy))
1427 if (i == 1 || i == 2)
1431 cx = (i == 1 ? TILEX - snip : 0);
1439 cy = (i==0 ? TILEY-snip : 0);
1442 XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
1443 SX + (graphic % GFX_PER_LINE) * TILEX + cx,
1444 SY + (graphic / GFX_PER_LINE) * TILEY + cy,
1445 width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
1447 MarkTileDirty(xx, yy);
1452 void DrawScreenElement(int x, int y, int element)
1454 DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
1455 ErdreichAnbroeckeln(x, y);
1458 void DrawLevelElement(int x, int y, int element)
1460 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1461 DrawScreenElement(SCREENX(x), SCREENY(y), element);
1464 void DrawScreenField(int x, int y)
1466 int ux = LEVELX(x), uy = LEVELY(y);
1469 if (!IN_LEV_FIELD(ux, uy))
1471 if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
1472 element = EL_LEERRAUM;
1474 element = BorderElement;
1476 DrawScreenElement(x, y, element);
1480 element = Feld[ux][uy];
1482 if (IS_MOVING(ux, uy))
1484 int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
1485 boolean cut_mode = NO_CUTTING;
1487 if (Store[ux][uy] == EL_MORAST_LEER ||
1488 Store[ux][uy] == EL_SIEB_LEER ||
1489 Store[ux][uy] == EL_SIEB2_LEER ||
1490 Store[ux][uy] == EL_AMOEBE_NASS)
1491 cut_mode = CUT_ABOVE;
1492 else if (Store[ux][uy] == EL_MORAST_VOLL ||
1493 Store[ux][uy] == EL_SIEB_VOLL ||
1494 Store[ux][uy] == EL_SIEB2_VOLL)
1495 cut_mode = CUT_BELOW;
1497 if (cut_mode == CUT_ABOVE)
1498 DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
1500 DrawScreenElement(x, y, EL_LEERRAUM);
1503 DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
1505 DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
1507 if (Store[ux][uy] == EL_SALZSAEURE)
1508 DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
1510 else if (IS_BLOCKED(ux, uy))
1515 boolean cut_mode = NO_CUTTING;
1517 Blocked2Moving(ux, uy, &oldx, &oldy);
1520 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
1521 MovDir[oldx][oldy] == MV_RIGHT);
1523 if (Store[oldx][oldy] == EL_MORAST_LEER ||
1524 Store[oldx][oldy] == EL_SIEB_LEER ||
1525 Store[oldx][oldy] == EL_SIEB2_LEER ||
1526 Store[oldx][oldy] == EL_AMOEBE_NASS)
1527 cut_mode = CUT_ABOVE;
1529 DrawScreenElement(x, y, EL_LEERRAUM);
1530 element = Feld[oldx][oldy];
1533 DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
1535 DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
1537 else if (IS_DRAWABLE(element))
1538 DrawScreenElement(x, y, element);
1540 DrawScreenElement(x, y, EL_LEERRAUM);
1543 void DrawLevelField(int x, int y)
1545 if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
1546 DrawScreenField(SCREENX(x), SCREENY(y));
1547 else if (IS_MOVING(x, y))
1551 Moving2Blocked(x, y, &newx, &newy);
1552 if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
1553 DrawScreenField(SCREENX(newx), SCREENY(newy));
1555 else if (IS_BLOCKED(x, y))
1559 Blocked2Moving(x, y, &oldx, &oldy);
1560 if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
1561 DrawScreenField(SCREENX(oldx), SCREENY(oldy));
1565 void DrawMiniElement(int x, int y, int element)
1571 DrawMiniGraphic(x, y, -1);
1575 graphic = el2gfx(element);
1576 DrawMiniGraphic(x, y, graphic);
1579 void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
1581 int x = sx + scroll_x, y = sy + scroll_y;
1583 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
1584 DrawMiniElement(sx, sy, EL_LEERRAUM);
1585 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
1586 DrawMiniElement(sx, sy, Feld[x][y]);
1589 int steel_type, steel_position;
1592 { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
1593 { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
1594 { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
1595 { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
1596 { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
1597 { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
1600 steel_type = (BorderElement == EL_BETON ? 0 : 1);
1601 steel_position = (x == -1 && y == -1 ? 0 :
1602 x == lev_fieldx && y == -1 ? 1 :
1603 x == -1 && y == lev_fieldy ? 2 :
1604 x == lev_fieldx && y == lev_fieldy ? 3 :
1605 x == -1 || x == lev_fieldx ? 4 :
1606 y == -1 || y == lev_fieldy ? 5 : -1);
1608 if (steel_position != -1)
1609 DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
1613 if (x == -1 && y == -1)
1614 DrawMiniGraphic(sx, sy, GFX_STEEL_UPPER_LEFT);
1615 else if (x == lev_fieldx && y == -1)
1616 DrawMiniGraphic(sx, sy, GFX_STEEL_UPPER_RIGHT);
1617 else if (x == -1 && y == lev_fieldy)
1618 DrawMiniGraphic(sx, sy, GFX_STEEL_LOWER_LEFT);
1619 else if (x == lev_fieldx && y == lev_fieldy)
1620 DrawMiniGraphic(sx, sy, GFX_STEEL_LOWER_RIGHT);
1621 else if (x == -1 || x == lev_fieldx)
1622 DrawMiniGraphic(sx, sy, GFX_STEEL_VERTICAL);
1623 else if (y == -1 || y == lev_fieldy)
1624 DrawMiniGraphic(sx, sy, GFX_STEEL_HORIZONTAL);
1631 void DrawMicroElement(int xpos, int ypos, int element)
1635 if (element == EL_LEERRAUM)
1638 graphic = el2gfx(element);
1640 if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
1642 graphic -= GFX_START_ROCKSMORE;
1643 graphic -= ((graphic / MORE_PER_LINE) * MORE_PER_LINE) / 2;
1644 XCopyArea(display, pix[PIX_MORE], drawto, gc,
1645 MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX,
1646 MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY,
1647 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1650 XCopyArea(display, pix[PIX_BACK], drawto, gc,
1651 MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
1652 MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
1653 MICRO_TILEX, MICRO_TILEY, xpos, ypos);
1662 for(x=BX1; x<=BX2; x++)
1663 for(y=BY1; y<=BY2; y++)
1664 DrawScreenField(x, y);
1666 if (setup.soft_scrolling)
1667 XCopyArea(display, fieldbuffer, backbuffer, gc,
1668 FX, FY, SXSIZE, SYSIZE, SX, SY);
1670 redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
1673 void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
1677 for(x=0; x<size_x; x++)
1678 for(y=0; y<size_y; y++)
1679 DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
1681 redraw_mask |= REDRAW_FIELD;
1684 static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
1688 /* determine border element for this level */
1691 XFillRectangle(display, drawto, gc,
1692 xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
1694 if (lev_fieldx < STD_LEV_FIELDX)
1695 xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
1696 if (lev_fieldy < STD_LEV_FIELDY)
1697 ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
1699 xpos += MICRO_TILEX;
1700 ypos += MICRO_TILEY;
1702 for(x=-1; x<=STD_LEV_FIELDX; x++)
1704 for(y=-1; y<=STD_LEV_FIELDY; y++)
1706 int lx = from_x + x, ly = from_y + y;
1708 if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
1709 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1711 else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
1712 DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
1717 redraw_mask |= REDRAW_MICROLEVEL;
1720 static void DrawMicroLevelLabelExt(int mode)
1722 char label_text[100];
1724 XFillRectangle(display, drawto,gc,
1725 SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
1727 strcpy(label_text, (mode == 1 ? level.name :
1728 mode == 2 ? "created by" :
1729 mode == 3 ? level.author : ""));
1731 if (strlen(label_text) > 0)
1733 int size, lxpos, lypos;
1735 label_text[SXSIZE / FONT4_XSIZE] = '\0';
1737 size = strlen(label_text);
1738 lxpos = SX + (SXSIZE - size * FONT4_XSIZE) / 2;
1739 lypos = MICROLABEL_YPOS;
1741 DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
1744 redraw_mask |= REDRAW_MICROLEVEL;
1747 void DrawMicroLevel(int xpos, int ypos, boolean restart)
1749 static unsigned long scroll_delay = 0;
1750 static unsigned long label_delay = 0;
1751 static int from_x, from_y, scroll_direction;
1752 static int label_state, label_counter;
1756 from_x = from_y = 0;
1757 scroll_direction = MV_RIGHT;
1761 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1762 DrawMicroLevelLabelExt(label_state);
1764 /* initialize delay counters */
1765 DelayReached(&scroll_delay, 0);
1766 DelayReached(&label_delay, 0);
1771 /* scroll micro level, if needed */
1772 if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
1773 DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
1775 switch (scroll_direction)
1781 scroll_direction = MV_UP;
1785 if (from_x < lev_fieldx - STD_LEV_FIELDX)
1788 scroll_direction = MV_DOWN;
1795 scroll_direction = MV_RIGHT;
1799 if (from_y < lev_fieldy - STD_LEV_FIELDY)
1802 scroll_direction = MV_LEFT;
1809 DrawMicroLevelExt(xpos, ypos, from_x, from_y);
1812 /* redraw micro level label, if needed */
1813 if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
1814 strcmp(level.author, ANONYMOUS_NAME) != 0 &&
1815 strcmp(level.author, leveldir[leveldir_nr].name) != 0 &&
1816 DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
1818 label_counter = (label_counter + 1) % 23;
1819 label_state = (label_counter >= 0 && label_counter <= 7 ? 1 :
1820 label_counter >= 9 && label_counter <= 12 ? 2 :
1821 label_counter >= 14 && label_counter <= 21 ? 3 : 0);
1822 DrawMicroLevelLabelExt(label_state);
1826 int REQ_in_range(int x, int y)
1828 if (y > DY+249 && y < DY+278)
1830 if (x > DX+1 && x < DX+48)
1832 else if (x > DX+51 && x < DX+98)
1838 boolean Request(char *text, unsigned int req_state)
1840 int mx, my, ty, result = -1;
1841 unsigned int old_door_state;
1844 /* pause network game while waiting for request to answer */
1845 if (options.network &&
1846 game_status == PLAYING &&
1847 req_state & REQUEST_WAIT_FOR)
1848 SendToServer_PausePlaying();
1851 old_door_state = GetDoorState();
1855 CloseDoor(DOOR_CLOSE_1);
1857 /* save old door content */
1858 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
1859 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
1860 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
1862 /* clear door drawing field */
1864 XFillRectangle(display, pix[PIX_DB_DOOR], gc,
1865 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE);
1867 XFillRectangle(display, drawto, gc, DX, DY, DXSIZE, DYSIZE);
1870 /* write text for request */
1871 for(ty=0; ty<13; ty++)
1879 for(tl=0,tx=0; tx<7; tl++,tx++)
1882 if (!tc || tc == 32)
1894 DrawTextExt(pix[PIX_DB_DOOR], gc,
1895 DOOR_GFX_PAGEX1 + 51 - (tl * 14)/2, SY + ty * 16,
1896 txt, FS_SMALL, FC_YELLOW);
1898 DrawTextExt(drawto, gc,
1899 DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
1900 txt, FS_SMALL, FC_YELLOW);
1902 text += tl + (tc == 32 ? 1 : 0);
1906 if (req_state & REQ_ASK)
1908 DrawYesNoButton(BUTTON_OK, DB_INIT);
1909 DrawYesNoButton(BUTTON_NO, DB_INIT);
1911 else if (req_state & REQ_CONFIRM)
1913 DrawConfirmButton(BUTTON_CONFIRM, DB_INIT);
1915 else if (req_state & REQ_PLAYER)
1917 DrawPlayerButton(BUTTON_PLAYER_1, DB_INIT);
1918 DrawPlayerButton(BUTTON_PLAYER_2, DB_INIT);
1919 DrawPlayerButton(BUTTON_PLAYER_3, DB_INIT);
1920 DrawPlayerButton(BUTTON_PLAYER_4, DB_INIT);
1924 if (req_state & REQ_ASK)
1926 MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
1927 MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
1929 else if (req_state & REQ_CONFIRM)
1931 MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
1933 else if (req_state & REQ_PLAYER)
1935 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
1936 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
1937 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
1938 MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
1941 /* copy request gadgets to door backbuffer */
1942 XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
1943 DX, DY, DXSIZE, DYSIZE,
1944 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
1948 OpenDoor(DOOR_OPEN_1);
1951 if (!(req_state & REQUEST_WAIT_FOR))
1954 if (game_status != MAINMENU)
1957 button_status = MB_RELEASED;
1959 request_gadget_id = -1;
1963 if (XPending(display))
1967 XNextEvent(display, &event);
1980 if (event.type == MotionNotify)
1987 if (!XQueryPointer(display, window, &root, &child,
1988 &root_x, &root_y, &win_x, &win_y, &mask))
1994 motion_status = TRUE;
1995 mx = ((XMotionEvent *) &event)->x;
1996 my = ((XMotionEvent *) &event)->y;
2000 motion_status = FALSE;
2001 mx = ((XButtonEvent *) &event)->x;
2002 my = ((XButtonEvent *) &event)->y;
2003 if (event.type==ButtonPress)
2004 button_status = ((XButtonEvent *) &event)->button;
2006 button_status = MB_RELEASED;
2012 if (req_state & REQ_ASK)
2013 choice = CheckYesNoButtons(mx,my,button_status);
2014 else if (req_state & REQ_CONFIRM)
2015 choice = CheckConfirmButton(mx,my,button_status);
2017 choice = CheckPlayerButtons(mx,my,button_status);
2027 case BUTTON_CONFIRM:
2028 result = TRUE | FALSE;
2031 case BUTTON_PLAYER_1:
2034 case BUTTON_PLAYER_2:
2037 case BUTTON_PLAYER_3:
2040 case BUTTON_PLAYER_4:
2049 /* this sets 'request_gadget_id' */
2050 HandleGadgets(mx, my, button_status);
2052 switch(request_gadget_id)
2054 case TOOL_CTRL_ID_YES:
2057 case TOOL_CTRL_ID_NO:
2060 case TOOL_CTRL_ID_CONFIRM:
2061 result = TRUE | FALSE;
2064 case TOOL_CTRL_ID_PLAYER_1:
2067 case TOOL_CTRL_ID_PLAYER_2:
2070 case TOOL_CTRL_ID_PLAYER_3:
2073 case TOOL_CTRL_ID_PLAYER_4:
2086 switch(XLookupKeysym((XKeyEvent *)&event,
2087 ((XKeyEvent *)&event)->state))
2100 if (req_state & REQ_PLAYER)
2105 key_joystick_mapping = 0;
2109 HandleOtherEvents(&event);
2113 else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED)
2115 int joy = AnyJoystick();
2117 if (joy & JOY_BUTTON_1)
2119 else if (joy & JOY_BUTTON_2)
2125 /* don't eat all CPU time */
2129 if (game_status != MAINMENU)
2134 if (!(req_state & REQ_STAY_OPEN))
2136 CloseDoor(DOOR_CLOSE_1);
2138 if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
2140 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
2141 DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2142 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
2143 OpenDoor(DOOR_OPEN_1);
2150 /* continue network game after request */
2151 if (options.network &&
2152 game_status == PLAYING &&
2153 req_state & REQUEST_WAIT_FOR)
2154 SendToServer_ContinuePlaying();
2160 unsigned int OpenDoor(unsigned int door_state)
2162 unsigned int new_door_state;
2164 if (door_state & DOOR_COPY_BACK)
2166 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
2167 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
2168 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2169 door_state &= ~DOOR_COPY_BACK;
2172 new_door_state = MoveDoor(door_state);
2174 return(new_door_state);
2177 unsigned int CloseDoor(unsigned int door_state)
2179 unsigned int new_door_state;
2181 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
2182 DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2183 XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
2184 VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
2186 new_door_state = MoveDoor(door_state);
2188 return(new_door_state);
2191 unsigned int GetDoorState()
2193 return(MoveDoor(DOOR_GET_STATE));
2196 unsigned int MoveDoor(unsigned int door_state)
2198 static int door1 = DOOR_OPEN_1;
2199 static int door2 = DOOR_CLOSE_2;
2200 static unsigned long door_delay = 0;
2201 int x, start, stepsize = 2;
2202 unsigned long door_delay_value = stepsize * 5;
2204 if (door_state == DOOR_GET_STATE)
2205 return(door1 | door2);
2207 if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
2208 door_state &= ~DOOR_OPEN_1;
2209 else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
2210 door_state &= ~DOOR_CLOSE_1;
2211 if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
2212 door_state &= ~DOOR_OPEN_2;
2213 else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
2214 door_state &= ~DOOR_CLOSE_2;
2216 if (setup.quick_doors)
2219 door_delay_value = 0;
2220 StopSound(SND_OEFFNEN);
2223 if (door_state & DOOR_ACTION)
2225 if (!(door_state & DOOR_NO_DELAY))
2226 PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
2228 start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
2230 for(x=start; x<=DXSIZE; x+=stepsize)
2232 WaitUntilDelayReached(&door_delay, door_delay_value);
2234 if (door_state & DOOR_ACTION_1)
2236 int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
2237 int j = (DXSIZE - i) / 3;
2239 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
2240 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
2241 DXSIZE,DYSIZE - i/2, DX, DY);
2243 XFillRectangle(display, drawto, gc, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
2245 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2246 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2247 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
2248 DXSIZE, DOOR_GFX_PAGEY1, i, 77, DX + DXSIZE - i, DY + j);
2249 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2250 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63, DX + DXSIZE - i,
2252 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2253 DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
2254 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2255 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j, DX, DY);
2256 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2257 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63, DX, DY + 140 - j);
2259 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2260 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
2262 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2263 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
2265 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2266 DX - i, (DY + j) - DOOR_GFX_PAGEY1);
2267 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2268 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
2269 DX + DXSIZE - i, DY + 77 + j);
2270 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2271 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
2272 DX + DXSIZE - i, DY + 203 + j);
2274 redraw_mask |= REDRAW_DOOR_1;
2277 if (door_state & DOOR_ACTION_2)
2279 int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
2280 int j = (VXSIZE - i) / 3;
2282 XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
2283 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
2284 VXSIZE, VYSIZE - i/2, VX, VY);
2286 XFillRectangle(display, drawto, gc, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
2288 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2289 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2290 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2291 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2, VX + VXSIZE-i, VY+j);
2292 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2293 VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
2294 XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
2295 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j, VX, VY);
2297 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2298 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2,
2299 VX, VY + VYSIZE / 2 - j);
2300 XSetClipOrigin(display, clip_gc[PIX_DOOR],
2301 VX - i, (VY + j) - DOOR_GFX_PAGEY2);
2302 XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
2303 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2 - j,
2304 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
2306 redraw_mask |= REDRAW_DOOR_2;
2314 XCopyArea(display, drawto, window, gc, DX, DY, DXSIZE, DYSIZE, DX, DY);
2319 if (game_status == MAINMENU)
2324 if (setup.quick_doors)
2325 StopSound(SND_OEFFNEN);
2327 if (door_state & DOOR_ACTION_1)
2328 door1 = door_state & DOOR_ACTION_1;
2329 if (door_state & DOOR_ACTION_2)
2330 door2 = door_state & DOOR_ACTION_2;
2332 return(door1 | door2);
2335 int ReadPixel(Drawable d, int x, int y)
2337 XImage *pixel_image;
2338 unsigned long pixel_value;
2340 pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
2341 pixel_value = XGetPixel(pixel_image, 0, 0);
2343 XDestroyImage(pixel_image);
2348 /* ---------- new tool button stuff ---------------------------------------- */
2350 /* graphic position values for tool buttons */
2351 #define TOOL_BUTTON_YES_XPOS 2
2352 #define TOOL_BUTTON_YES_YPOS 250
2353 #define TOOL_BUTTON_YES_GFX_YPOS 0
2354 #define TOOL_BUTTON_YES_XSIZE 46
2355 #define TOOL_BUTTON_YES_YSIZE 28
2356 #define TOOL_BUTTON_NO_XPOS 52
2357 #define TOOL_BUTTON_NO_YPOS TOOL_BUTTON_YES_YPOS
2358 #define TOOL_BUTTON_NO_GFX_YPOS TOOL_BUTTON_YES_GFX_YPOS
2359 #define TOOL_BUTTON_NO_XSIZE TOOL_BUTTON_YES_XSIZE
2360 #define TOOL_BUTTON_NO_YSIZE TOOL_BUTTON_YES_YSIZE
2361 #define TOOL_BUTTON_CONFIRM_XPOS TOOL_BUTTON_YES_XPOS
2362 #define TOOL_BUTTON_CONFIRM_YPOS TOOL_BUTTON_YES_YPOS
2363 #define TOOL_BUTTON_CONFIRM_GFX_YPOS 30
2364 #define TOOL_BUTTON_CONFIRM_XSIZE 96
2365 #define TOOL_BUTTON_CONFIRM_YSIZE TOOL_BUTTON_YES_YSIZE
2366 #define TOOL_BUTTON_PLAYER_XSIZE 30
2367 #define TOOL_BUTTON_PLAYER_YSIZE 30
2368 #define TOOL_BUTTON_PLAYER_GFX_XPOS 5
2369 #define TOOL_BUTTON_PLAYER_GFX_YPOS 185
2370 #define TOOL_BUTTON_PLAYER_XPOS (5 + TOOL_BUTTON_PLAYER_XSIZE / 2)
2371 #define TOOL_BUTTON_PLAYER_YPOS (215 - TOOL_BUTTON_PLAYER_YSIZE / 2)
2372 #define TOOL_BUTTON_PLAYER1_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2373 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2374 #define TOOL_BUTTON_PLAYER2_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2375 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2376 #define TOOL_BUTTON_PLAYER3_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2377 + 0 * TOOL_BUTTON_PLAYER_XSIZE)
2378 #define TOOL_BUTTON_PLAYER4_XPOS (TOOL_BUTTON_PLAYER_XPOS \
2379 + 1 * TOOL_BUTTON_PLAYER_XSIZE)
2380 #define TOOL_BUTTON_PLAYER1_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2381 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2382 #define TOOL_BUTTON_PLAYER2_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2383 + 0 * TOOL_BUTTON_PLAYER_YSIZE)
2384 #define TOOL_BUTTON_PLAYER3_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2385 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2386 #define TOOL_BUTTON_PLAYER4_YPOS (TOOL_BUTTON_PLAYER_YPOS \
2387 + 1 * TOOL_BUTTON_PLAYER_YSIZE)
2396 } toolbutton_info[NUM_TOOL_BUTTONS] =
2399 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_GFX_YPOS,
2400 TOOL_BUTTON_YES_XPOS, TOOL_BUTTON_YES_YPOS,
2401 TOOL_BUTTON_YES_XSIZE, TOOL_BUTTON_YES_YSIZE,
2406 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_GFX_YPOS,
2407 TOOL_BUTTON_NO_XPOS, TOOL_BUTTON_NO_YPOS,
2408 TOOL_BUTTON_NO_XSIZE, TOOL_BUTTON_NO_YSIZE,
2413 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_GFX_YPOS,
2414 TOOL_BUTTON_CONFIRM_XPOS, TOOL_BUTTON_CONFIRM_YPOS,
2415 TOOL_BUTTON_CONFIRM_XSIZE, TOOL_BUTTON_CONFIRM_YSIZE,
2416 TOOL_CTRL_ID_CONFIRM,
2420 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2421 TOOL_BUTTON_PLAYER1_XPOS, TOOL_BUTTON_PLAYER1_YPOS,
2422 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2423 TOOL_CTRL_ID_PLAYER_1,
2427 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2428 TOOL_BUTTON_PLAYER2_XPOS, TOOL_BUTTON_PLAYER2_YPOS,
2429 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2430 TOOL_CTRL_ID_PLAYER_2,
2434 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2435 TOOL_BUTTON_PLAYER3_XPOS, TOOL_BUTTON_PLAYER3_YPOS,
2436 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2437 TOOL_CTRL_ID_PLAYER_3,
2441 TOOL_BUTTON_PLAYER_GFX_XPOS,TOOL_BUTTON_PLAYER_GFX_YPOS,
2442 TOOL_BUTTON_PLAYER4_XPOS, TOOL_BUTTON_PLAYER4_YPOS,
2443 TOOL_BUTTON_PLAYER_XSIZE, TOOL_BUTTON_PLAYER_YSIZE,
2444 TOOL_CTRL_ID_PLAYER_4,
2449 void CreateToolButtons()
2453 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2455 Pixmap gd_pixmap = pix[PIX_DOOR];
2456 Pixmap deco_pixmap = None;
2457 int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
2458 struct GadgetInfo *gi;
2459 unsigned long event_mask;
2460 int gd_xoffset, gd_yoffset;
2461 int gd_x1, gd_x2, gd_y;
2464 event_mask = GD_EVENT_RELEASED;
2466 gd_xoffset = toolbutton_info[i].xpos;
2467 gd_yoffset = toolbutton_info[i].ypos;
2468 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
2469 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
2470 gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
2472 if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
2474 getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
2475 &deco_pixmap, &deco_x, &deco_y);
2476 deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
2477 deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
2480 gi = CreateGadget(GDI_CUSTOM_ID, id,
2481 GDI_INFO_TEXT, toolbutton_info[i].infotext,
2482 GDI_X, DX + toolbutton_info[i].x,
2483 GDI_Y, DY + toolbutton_info[i].y,
2484 GDI_WIDTH, toolbutton_info[i].width,
2485 GDI_HEIGHT, toolbutton_info[i].height,
2486 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
2487 GDI_STATE, GD_BUTTON_UNPRESSED,
2488 GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
2489 GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
2490 GDI_DECORATION_DESIGN, deco_pixmap, deco_x, deco_y,
2491 GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
2492 GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
2493 GDI_DECORATION_SHIFTING, 1, 1,
2494 GDI_EVENT_MASK, event_mask,
2495 GDI_CALLBACK_ACTION, HandleToolButtons,
2499 Error(ERR_EXIT, "cannot create gadget");
2501 tool_gadget[id] = gi;
2505 static void UnmapToolButtons()
2509 for (i=0; i<NUM_TOOL_BUTTONS; i++)
2510 UnmapGadget(tool_gadget[i]);
2513 static void HandleToolButtons(struct GadgetInfo *gi)
2515 request_gadget_id = gi->custom_id;
2519 int id = gi->custom_id;
2521 if (game_status != PLAYING)
2526 case GAME_CTRL_ID_STOP:
2529 CloseDoor(DOOR_CLOSE_1);
2530 game_status = MAINMENU;
2535 if (Request("Do you really want to quit the game ?",
2536 REQ_ASK | REQ_STAY_CLOSED))
2539 if (options.network)
2540 SendToServer_StopPlaying();
2544 game_status = MAINMENU;
2549 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
2552 case GAME_CTRL_ID_PAUSE:
2553 if (options.network)
2557 SendToServer_ContinuePlaying();
2559 SendToServer_PausePlaying();
2566 case GAME_CTRL_ID_PLAY:
2570 if (options.network)
2571 SendToServer_ContinuePlaying();
2575 tape.pausing = FALSE;
2576 DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
2581 case SOUND_CTRL_ID_MUSIC:
2582 if (setup.sound_music)
2584 setup.sound_music = FALSE;
2585 FadeSound(background_loop[level_nr % num_bg_loops]);
2587 else if (sound_loops_allowed)
2589 setup.sound = setup.sound_music = TRUE;
2590 PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
2594 case SOUND_CTRL_ID_LOOPS:
2595 if (setup.sound_loops)
2596 setup.sound_loops = FALSE;
2597 else if (sound_loops_allowed)
2598 setup.sound = setup.sound_loops = TRUE;
2601 case SOUND_CTRL_ID_SIMPLE:
2602 if (setup.sound_simple)
2603 setup.sound_simple = FALSE;
2604 else if (sound_status==SOUND_AVAILABLE)
2605 setup.sound = setup.sound_simple = TRUE;
2617 int el2gfx(int element)
2621 case EL_LEERRAUM: return -1;
2622 case EL_ERDREICH: return GFX_ERDREICH;
2623 case EL_MAUERWERK: return GFX_MAUERWERK;
2624 case EL_FELSBODEN: return GFX_FELSBODEN;
2625 case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
2626 case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
2627 case EL_EDELSTEIN: return GFX_EDELSTEIN;
2628 case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
2629 case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
2630 case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
2631 case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
2632 case EL_SPIELER1: return GFX_SPIELER1;
2633 case EL_SPIELER2: return GFX_SPIELER2;
2634 case EL_SPIELER3: return GFX_SPIELER3;
2635 case EL_SPIELER4: return GFX_SPIELER4;
2636 case EL_KAEFER: return GFX_KAEFER;
2637 case EL_KAEFER_R: return GFX_KAEFER_R;
2638 case EL_KAEFER_O: return GFX_KAEFER_O;
2639 case EL_KAEFER_L: return GFX_KAEFER_L;
2640 case EL_KAEFER_U: return GFX_KAEFER_U;
2641 case EL_FLIEGER: return GFX_FLIEGER;
2642 case EL_FLIEGER_R: return GFX_FLIEGER_R;
2643 case EL_FLIEGER_O: return GFX_FLIEGER_O;
2644 case EL_FLIEGER_L: return GFX_FLIEGER_L;
2645 case EL_FLIEGER_U: return GFX_FLIEGER_U;
2646 case EL_BUTTERFLY: return GFX_BUTTERFLY;
2647 case EL_BUTTERFLY_R: return GFX_BUTTERFLY_R;
2648 case EL_BUTTERFLY_O: return GFX_BUTTERFLY_O;
2649 case EL_BUTTERFLY_L: return GFX_BUTTERFLY_L;
2650 case EL_BUTTERFLY_U: return GFX_BUTTERFLY_U;
2651 case EL_FIREFLY: return GFX_FIREFLY;
2652 case EL_FIREFLY_R: return GFX_FIREFLY_R;
2653 case EL_FIREFLY_O: return GFX_FIREFLY_O;
2654 case EL_FIREFLY_L: return GFX_FIREFLY_L;
2655 case EL_FIREFLY_U: return GFX_FIREFLY_U;
2656 case EL_MAMPFER: return GFX_MAMPFER;
2657 case EL_ROBOT: return GFX_ROBOT;
2658 case EL_BETON: return GFX_BETON;
2659 case EL_DIAMANT: return GFX_DIAMANT;
2660 case EL_MORAST_LEER: return GFX_MORAST_LEER;
2661 case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
2662 case EL_TROPFEN: return GFX_TROPFEN;
2663 case EL_BOMBE: return GFX_BOMBE;
2664 case EL_SIEB_INAKTIV: return GFX_SIEB_INAKTIV;
2665 case EL_SIEB_LEER: return GFX_SIEB_LEER;
2666 case EL_SIEB_VOLL: return GFX_SIEB_VOLL;
2667 case EL_SIEB_TOT: return GFX_SIEB_TOT;
2668 case EL_SALZSAEURE: return GFX_SALZSAEURE;
2669 case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
2670 case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
2671 case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
2672 case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
2673 case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
2674 case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
2675 case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
2676 case EL_LIFE: return GFX_LIFE;
2677 case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
2678 case EL_DYNAMIT: return GFX_DYNAMIT;
2679 case EL_BADEWANNE: return GFX_BADEWANNE;
2680 case EL_BADEWANNE1: return GFX_BADEWANNE1;
2681 case EL_BADEWANNE2: return GFX_BADEWANNE2;
2682 case EL_BADEWANNE3: return GFX_BADEWANNE3;
2683 case EL_BADEWANNE4: return GFX_BADEWANNE4;
2684 case EL_BADEWANNE5: return GFX_BADEWANNE5;
2685 case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
2686 case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
2687 case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
2688 case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
2689 case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
2690 case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
2691 case EL_PFORTE1: return GFX_PFORTE1;
2692 case EL_PFORTE2: return GFX_PFORTE2;
2693 case EL_PFORTE3: return GFX_PFORTE3;
2694 case EL_PFORTE4: return GFX_PFORTE4;
2695 case EL_PFORTE1X: return GFX_PFORTE1X;
2696 case EL_PFORTE2X: return GFX_PFORTE2X;
2697 case EL_PFORTE3X: return GFX_PFORTE3X;
2698 case EL_PFORTE4X: return GFX_PFORTE4X;
2699 case EL_DYNAMIT_AUS: return GFX_DYNAMIT_AUS;
2700 case EL_PACMAN: return GFX_PACMAN;
2701 case EL_PACMAN_R: return GFX_PACMAN_R;
2702 case EL_PACMAN_O: return GFX_PACMAN_O;
2703 case EL_PACMAN_L: return GFX_PACMAN_L;
2704 case EL_PACMAN_U: return GFX_PACMAN_U;
2705 case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
2706 case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
2707 case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
2708 case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
2709 case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
2710 case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
2711 case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
2712 case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
2713 case EL_MAUER_X: return GFX_MAUER_X;
2714 case EL_MAUER_Y: return GFX_MAUER_Y;
2715 case EL_MAUER_XY: return GFX_MAUER_XY;
2716 case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
2717 case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
2718 case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
2719 case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
2720 case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
2721 case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
2722 case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
2723 case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
2724 case EL_MAMPFER2: return GFX_MAMPFER2;
2725 case EL_SIEB2_INAKTIV: return GFX_SIEB2_INAKTIV;
2726 case EL_SIEB2_LEER: return GFX_SIEB2_LEER;
2727 case EL_SIEB2_VOLL: return GFX_SIEB2_VOLL;
2728 case EL_SIEB2_TOT: return GFX_SIEB2_TOT;
2729 case EL_DYNABOMB: return GFX_DYNABOMB;
2730 case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
2731 case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
2732 case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
2733 case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
2734 case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
2735 case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
2736 case EL_MAULWURF: return GFX_MAULWURF;
2737 case EL_PINGUIN: return GFX_PINGUIN;
2738 case EL_SCHWEIN: return GFX_SCHWEIN;
2739 case EL_DRACHE: return GFX_DRACHE;
2740 case EL_SONDE: return GFX_SONDE;
2741 case EL_PFEIL_L: return GFX_PFEIL_L;
2742 case EL_PFEIL_R: return GFX_PFEIL_R;
2743 case EL_PFEIL_O: return GFX_PFEIL_O;
2744 case EL_PFEIL_U: return GFX_PFEIL_U;
2745 case EL_SPEED_PILL: return GFX_SPEED_PILL;
2746 case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
2747 case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
2748 case EL_SP_ZONK: return GFX_SP_ZONK;
2749 /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
2750 case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
2751 case EL_BLACK_ORB: return GFX_BLACK_ORB;
2752 case EL_EM_GATE_1: return GFX_EM_GATE_1;
2753 case EL_EM_GATE_2: return GFX_EM_GATE_2;
2754 case EL_EM_GATE_3: return GFX_EM_GATE_3;
2755 case EL_EM_GATE_4: return GFX_EM_GATE_4;
2756 case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
2757 case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
2758 case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
2759 case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
2763 if (IS_CHAR(element))
2764 return GFX_CHAR_START + (element - EL_CHAR_START);
2765 else if (element >= EL_SP_START && element <= EL_SP_END)
2767 int nr_element = element - EL_SP_START;
2768 int gfx_per_line = 8;
2770 (nr_element / gfx_per_line) * MORE_PER_LINE +
2771 (nr_element % gfx_per_line);
2773 return GFX_START_ROCKSMORE + nr_graphic;