1 /***********************************************************
2 * Mirror Magic -- McDuffin's Revenge *
3 *----------------------------------------------------------*
4 * (c) 1994-2001 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
20 /* forward declaration for internal use */
21 static int getGraphicAnimationPhase_MM(int, int, int);
25 ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
27 SetDrawtoField(DRAW_BACKBUFFER);
29 redraw_mask |= REDRAW_FIELD;
32 static int getGraphicAnimationPhase_MM(int frames, int delay, int mode)
36 if (mode == ANIM_PINGPONG)
38 int max_anim_frames = 2 * frames - 2;
39 phase = (FrameCounter % (delay * max_anim_frames)) / delay;
40 phase = (phase < frames ? phase : max_anim_frames - phase);
43 phase = (FrameCounter % (delay * frames)) / delay;
45 if (mode == ANIM_REVERSE)
51 void DrawGraphicAnimationExt_MM(int x, int y, int graphic,
52 int frames, int delay, int mode, int mask_mode)
54 int phase = getGraphicAnimationPhase_MM(frames, delay, mode);
56 if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
58 if (mask_mode == USE_MASKING)
59 DrawGraphicThruMask_MM(SCREENX(x), SCREENY(y), graphic + phase);
61 DrawGraphic_MM(SCREENX(x), SCREENY(y), graphic + phase);
65 void DrawGraphicAnimation_MM(int x, int y, int graphic,
66 int frames, int delay, int mode)
68 DrawGraphicAnimationExt_MM(x, y, graphic, frames, delay, mode, NO_MASKING);
71 void DrawGraphicAnimationThruMask_MM(int x, int y, int graphic,
72 int frames, int delay, int mode)
74 DrawGraphicAnimationExt_MM(x, y, graphic, frames, delay, mode, USE_MASKING);
77 void DrawGraphic_MM(int x, int y, int graphic)
80 if (!IN_SCR_FIELD(x,y))
82 printf("DrawGraphic_MM(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
83 printf("DrawGraphic_MM(): This should never happen!\n");
96 DrawGraphicExt_MM(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
100 void DrawGraphicExt_MM(DrawBuffer *d, int x, int y, int graphic)
105 getGraphicSource(graphic, 0, &bitmap, &src_x, &src_y);
106 BlitBitmap(bitmap, d, src_x, src_y, TILEX, TILEY, x, y);
109 void DrawGraphicThruMask_MM(int x, int y, int graphic)
112 if (!IN_SCR_FIELD(x,y))
114 printf("DrawGraphicThruMask_MM(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
115 printf("DrawGraphicThruMask_MM(): This should never happen!\n");
120 DrawGraphicThruMaskExt_MM(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
124 void DrawGraphicThruMaskExt_MM(DrawBuffer *d, int dest_x, int dest_y, int graphic)
129 if (graphic == GFX_EMPTY)
132 getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
134 BlitBitmapMasked(src_bitmap, d, src_x, src_y, TILEX, TILEY, dest_x, dest_y);
137 void DrawMiniGraphic_MM(int x, int y, int graphic)
139 DrawMiniGraphicExt_MM(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
140 MarkTileDirty(x/2, y/2);
143 void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
145 getSizedGraphicSource(graphic, 0, TILESIZE / 4, bitmap, x, y);
148 void DrawMiniGraphicExt_MM(DrawBuffer *d, int x, int y, int graphic)
153 getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
154 BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
157 void DrawGraphicShifted_MM(int x,int y, int dx,int dy, int graphic,
158 int cut_mode, int mask_mode)
160 int width = TILEX, height = TILEY;
162 int src_x, src_y, dest_x, dest_y;
167 DrawGraphic_MM(x, y, graphic);
171 if (dx || dy) /* Verschiebung der Grafik? */
173 if (x < BX1) /* Element kommt von links ins Bild */
180 else if (x > BX2) /* Element kommt von rechts ins Bild */
186 else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
192 else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
194 else if (dx) /* allg. Bewegung in x-Richtung */
195 MarkTileDirty(x + SIGN(dx), y);
197 if (y < BY1) /* Element kommt von oben ins Bild */
199 if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
207 else if (y > BY2) /* Element kommt von unten ins Bild */
213 else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
219 else if (dy > 0 && cut_mode == CUT_ABOVE)
221 if (y == BY2) /* Element unterhalb des Bildes */
227 MarkTileDirty(x, y + 1);
228 } /* Element verläßt unten das Bild */
229 else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
231 else if (dy) /* allg. Bewegung in y-Richtung */
232 MarkTileDirty(x, y + SIGN(dy));
235 getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
240 dest_x = FX + x * TILEX + dx;
241 dest_y = FY + y * TILEY + dy;
244 if (!IN_SCR_FIELD(x,y))
246 printf("DrawGraphicShifted_MM(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
247 printf("DrawGraphicShifted_MM(): This should never happen!\n");
252 if (mask_mode == USE_MASKING)
254 BlitBitmapMasked(src_bitmap, drawto_field,
255 src_x, src_y, TILEX, TILEY, dest_x, dest_y);
258 BlitBitmap(src_bitmap, drawto_field,
259 src_x, src_y, width, height, dest_x, dest_y);
264 void DrawGraphicShiftedThruMask_MM(int x,int y, int dx,int dy, int graphic,
267 DrawGraphicShifted_MM(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
270 void DrawScreenElementExt_MM(int x, int y, int dx, int dy, int element,
271 int cut_mode, int mask_mode)
273 int ux = LEVELX(x), uy = LEVELY(y);
274 int graphic = el2gfx(element);
275 int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
276 int phase2 = phase8 / 4;
277 int dir = MovDir[ux][uy];
279 if (element == EL_PACMAN)
281 graphic += 4 * !phase2;
285 else if (dir == MV_LEFT)
287 else if (dir == MV_DOWN)
292 DrawGraphicShifted_MM(x, y, dx, dy, graphic, cut_mode, mask_mode);
293 else if (mask_mode == USE_MASKING)
294 DrawGraphicThruMask_MM(x, y, graphic);
296 DrawGraphic_MM(x, y, graphic);
299 void DrawLevelElementExt_MM(int x, int y, int dx, int dy, int element,
300 int cut_mode, int mask_mode)
302 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
303 DrawScreenElementExt_MM(SCREENX(x), SCREENY(y), dx, dy, element,
304 cut_mode, mask_mode);
307 void DrawScreenElementShifted_MM(int x, int y, int dx, int dy, int element,
310 DrawScreenElementExt_MM(x, y, dx, dy, element, cut_mode, NO_MASKING);
313 void DrawLevelElementShifted_MM(int x, int y, int dx, int dy, int element,
316 DrawLevelElementExt_MM(x, y, dx, dy, element, cut_mode, NO_MASKING);
319 void DrawScreenElementThruMask_MM(int x, int y, int element)
321 DrawScreenElementExt_MM(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
324 void DrawLevelElementThruMask_MM(int x, int y, int element)
326 DrawLevelElementExt_MM(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
329 void DrawLevelFieldThruMask_MM(int x, int y)
331 DrawLevelElementExt_MM(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
334 void DrawScreenElement_MM(int x, int y, int element)
336 DrawScreenElementExt_MM(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
339 void DrawLevelElement_MM(int x, int y, int element)
341 if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
342 DrawScreenElement_MM(SCREENX(x), SCREENY(y), element);
345 void DrawScreenField_MM(int x, int y)
347 int element = Feld[x][y];
349 if (!IN_LEV_FIELD(x, y))
354 int horiz_move = (MovDir[x][y] == MV_LEFT || MovDir[x][y] == MV_RIGHT);
356 DrawScreenElement_MM(x, y, EL_EMPTY);
359 DrawScreenElementShifted_MM(x, y, MovPos[x][y], 0, element, NO_CUTTING);
361 DrawScreenElementShifted_MM(x, y, 0, MovPos[x][y], element, NO_CUTTING);
363 else if (IS_BLOCKED(x, y))
369 Blocked2Moving(x, y, &oldx, &oldy);
372 horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
373 MovDir[oldx][oldy] == MV_RIGHT);
375 DrawScreenElement_MM(x, y, EL_EMPTY);
376 element = Feld[oldx][oldy];
379 DrawScreenElementShifted_MM(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
381 DrawScreenElementShifted_MM(sx,sy, 0,MovPos[oldx][oldy],element,NO_CUTTING);
383 else if (IS_DRAWABLE(element))
384 DrawScreenElement_MM(x, y, element);
386 DrawScreenElement_MM(x, y, EL_EMPTY);
389 void DrawLevelField_MM(int x, int y)
391 DrawScreenField_MM(x, y);
394 void DrawMiniElement_MM(int x, int y, int element)
400 DrawMiniGraphic_MM(x, y, GFX_EMPTY);
404 graphic = el2gfx(element);
405 DrawMiniGraphic_MM(x, y, graphic);
408 void DrawMiniElementOrWall_MM(int sx, int sy, int scroll_x, int scroll_y)
410 int x = sx + scroll_x, y = sy + scroll_y;
412 if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
413 DrawMiniElement_MM(sx, sy, EL_EMPTY);
414 else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
415 DrawMiniElement_MM(sx, sy, Feld[x][y]);
418 void DrawField_MM(int x, int y)
420 int element = Feld[x][y];
422 DrawElement_MM(x, y, element);
431 for (x=0; x<lev_fieldx; x++)
432 for (y=0; y<lev_fieldy; y++)
435 redraw_mask |= REDRAW_FIELD;
438 void DrawWallsExt_MM(int x, int y, int element, int draw_mask)
441 int graphic = el2gfx(WALL_BASE(element));
445 getMiniGraphicSource(graphic, &bitmap, &gx, &gy);
447 if (game_status != LEVELED || !editor.draw_walls_masked)
448 DrawGraphic_MM(x, y, GFX_EMPTY);
451 if (IS_WALL_WOOD(element) || IS_WALL_AMOEBA(element) ||
452 IS_DF_WALL_WOOD(element))
454 if (IS_WALL_ICE(element) || IS_WALL_AMOEBA(element))
460 int dest_x = SX + x * TILEX + MINI_TILEX * (i % 2);
461 int dest_y = SY + y * TILEY + MINI_TILEY * (i / 2);
463 if (!((1 << i) & draw_mask))
466 if (element & (1 << i))
467 BlitBitmap(bitmap, drawto, gx, gy, MINI_TILEX, MINI_TILEY,
469 else if (!editor.draw_walls_masked)
470 ClearRectangle(drawto, dest_x, dest_y, MINI_TILEX, MINI_TILEY);
476 void DrawWalls_MM(int x, int y, int element)
478 DrawWallsExt_MM(x, y, element, HIT_MASK_ALL);
481 void DrawWallsAnimation_MM(int x, int y, int element, int phase, int bit_mask)
483 int graphic = GFX_WALL_SEVERAL;
484 int graphic_anim = graphic + (phase + 1) / 2;
485 int dx = (IS_WALL_AMOEBA(element) ? MINI_TILEX : 0);
488 int dy_anim = ((phase + 1) % 2) * MINI_TILEY;
491 Bitmap *bitmap, *bitmap_anim;
493 int src_x_anim, src_y_anim;
495 getGraphicSource(graphic, 0, &bitmap, &src_x, &src_y);
496 getGraphicSource(graphic_anim, 0, &bitmap_anim, &src_x_anim, &src_y_anim);
500 DrawWalls_MM(x, y, element);
506 if (element & (1 << i))
508 int dest_x = SX + x * TILEX + MINI_TILEX * (i % 2);
509 int dest_y = SY + y * TILEY + MINI_TILEY * (i / 2);
512 if (bit_mask & (1 << i))
514 gx = src_x_anim + dx_anim;
515 gy = src_y_anim + dy_anim;
517 BlitBitmap(bitmap_anim, drawto, gx, gy, MINI_TILEX, MINI_TILEY,
525 BlitBitmap(bitmap, drawto, gx, gy, MINI_TILEX, MINI_TILEY,
534 void DrawElement_MM(int x, int y, int element)
536 if (element == EL_EMPTY)
537 DrawGraphic_MM(x, y, GFX_EMPTY);
538 else if (IS_WALL(element))
539 DrawWalls_MM(x, y, element);
541 else if (IS_WALL_CHANGING(element) && IS_WALL_CHANGING(Feld[x][y]))
543 int wall_element = Feld[x][y] - EL_WALL_CHANGING + Store[x][y];
545 DrawWalls_MM(x, y, wall_element);
548 else if (element == EL_PACMAN)
549 DrawLevelField_MM(x, y);
551 DrawGraphic_MM(x, y, el2gfx(element));
554 void DrawMicroWalls_MM(int x, int y, int element)
557 int graphic = el2gfx(WALL_BASE(element));
561 getMicroGraphicSource(graphic, &bitmap, &gx, &gy);
565 int xpos = MICROLEV_XPOS + x * MICRO_TILEX + MICRO_WALLX * (i % 2);
566 int ypos = MICROLEV_YPOS + y * MICRO_TILEY + MICRO_WALLY * (i / 2);
568 if (element & (1 << i))
569 BlitBitmap(bitmap, drawto, gx, gy, MICRO_WALLX, MICRO_WALLY, xpos, ypos);
571 ClearRectangle(drawto, xpos, ypos, MICRO_WALLX, MICRO_WALLY);
575 void DrawMicroElement_MM(int x, int y, int element)
578 int graphic = el2gfx(element);
581 if (element == EL_EMPTY)
584 if (IS_WALL(element))
586 DrawMicroWalls_MM(x, y, element);
590 getMicroGraphicSource(graphic, &bitmap, &gx, &gy);
592 BlitBitmap(bitmap, drawto, gx, gy, MICRO_TILEX, MICRO_TILEY,
593 MICROLEV_XPOS + x * MICRO_TILEX, MICROLEV_YPOS + y * MICRO_TILEY);
596 void DrawMicroLevelExt_MM(int xpos, int ypos)
600 ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
602 for (x=0; x<STD_LEV_FIELDX; x++)
603 for (y=0; y<STD_LEV_FIELDY; y++)
604 DrawMicroElement_MM(x, y, Ur[x][y]);
606 redraw_mask |= REDRAW_FIELD;
609 void DrawMiniLevel_MM(int size_x, int size_y, int scroll_x, int scroll_y)
613 for(x=0; x<size_x; x++)
614 for(y=0; y<size_y; y++)
615 DrawMiniElementOrWall_MM(x, y, scroll_x, scroll_y);
617 redraw_mask |= REDRAW_FIELD;
620 int REQ_in_range(int x, int y)
622 if (y > DY+249 && y < DY+278)
624 if (x > DX+1 && x < DX+48)
626 else if (x > DX+51 && x < DX+98)
632 Pixel ReadPixel(DrawBuffer *bitmap, int x, int y)
634 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
635 return GetPixel(bitmap, x, y);
637 /* GetPixel() does also work for X11, but we use some optimization here */
638 unsigned int pixel_value;
640 if (bitmap == pix[PIX_BACK])
642 /* when reading pixel values from images, it is much faster to use
643 client side images (XImage) than server side images (Pixmap) */
644 static XImage *client_image = NULL;
646 if (client_image == NULL) /* init image cache, if not existing */
647 client_image = XGetImage(display, bitmap->drawable,
648 0,0, WIN_XSIZE,WIN_YSIZE, AllPlanes, ZPixmap);
650 pixel_value = XGetPixel(client_image, x, y);
656 pixel_image = XGetImage(display, bitmap->drawable, x, y, 1, 1,
658 pixel_value = XGetPixel(pixel_image, 0, 0);
660 XDestroyImage(pixel_image);
667 void SetRGB(unsigned int pixel,
668 unsigned short red, unsigned short green, unsigned short blue)
675 if (color_status==STATIC_COLORS)
682 color.flags = DoRed | DoGreen | DoBlue;
683 XStoreColor(display, cmap, &color);
688 int get_base_element(int element)
690 if (IS_MIRROR(element))
691 return EL_MIRROR_START;
692 else if (IS_MIRROR_FIXED(element))
693 return EL_MIRROR_FIXED_START;
694 else if (IS_POLAR(element))
695 return EL_POLAR_START;
696 else if (IS_POLAR_CROSS(element))
697 return EL_POLAR_CROSS_START;
698 else if (IS_BEAMER(element))
699 return EL_BEAMER_RED_START + BEAMER_NR(element) * 16;
700 else if (IS_FIBRE_OPTIC(element))
701 return EL_FIBRE_OPTIC_START + FIBRE_OPTIC_NR(element) * 2;
702 else if (IS_MCDUFFIN(element))
703 return EL_MCDUFFIN_START;
704 else if (IS_LASER(element))
705 return EL_LASER_START;
706 else if (IS_RECEIVER(element))
707 return EL_RECEIVER_START;
708 else if (IS_DF_MIRROR(element))
709 return EL_DF_MIRROR_START;
710 else if (IS_DF_MIRROR_AUTO(element))
711 return EL_DF_MIRROR_AUTO_START;
712 else if (IS_PACMAN(element))
713 return EL_PACMAN_START;
714 else if (IS_GRID_STEEL(element))
715 return EL_GRID_STEEL_START;
716 else if (IS_GRID_WOOD(element))
717 return EL_GRID_WOOD_START;
718 else if (IS_GRID_STEEL_FIXED(element))
719 return EL_GRID_STEEL_FIXED_START;
720 else if (IS_GRID_WOOD_FIXED(element))
721 return EL_GRID_WOOD_FIXED_START;
722 else if (IS_GRID_STEEL_AUTO(element))
723 return EL_GRID_STEEL_AUTO_START;
724 else if (IS_GRID_WOOD_AUTO(element))
725 return EL_GRID_WOOD_AUTO_START;
726 else if (IS_WALL_STEEL(element))
727 return EL_WALL_STEEL_START;
728 else if (IS_WALL_WOOD(element))
729 return EL_WALL_WOOD_START;
730 else if (IS_WALL_ICE(element))
731 return EL_WALL_ICE_START;
732 else if (IS_WALL_AMOEBA(element))
733 return EL_WALL_AMOEBA_START;
734 else if (IS_DF_WALL_STEEL(element))
735 return EL_DF_WALL_STEEL_START;
736 else if (IS_DF_WALL_WOOD(element))
737 return EL_DF_WALL_WOOD_START;
738 else if (IS_CHAR(element))
739 return EL_CHAR_START;
744 int get_element_phase(int element)
746 return element - get_base_element(element);
749 int get_num_elements(int element)
751 if (IS_MIRROR(element) ||
753 IS_BEAMER(element) ||
754 IS_DF_MIRROR(element) ||
755 IS_DF_MIRROR_AUTO(element))
757 else if (IS_GRID_STEEL_FIXED(element) ||
758 IS_GRID_WOOD_FIXED(element) ||
759 IS_GRID_STEEL_AUTO(element) ||
760 IS_GRID_WOOD_AUTO(element))
762 else if (IS_MIRROR_FIXED(element) ||
763 IS_POLAR_CROSS(element) ||
764 IS_MCDUFFIN(element) ||
766 IS_RECEIVER(element) ||
767 IS_PACMAN(element) ||
768 IS_GRID_STEEL(element) ||
769 IS_GRID_WOOD(element))
775 int get_rotated_element(int element, int step)
777 int base_element = get_base_element(element);
778 int num_elements = get_num_elements(element);
779 int element_phase = element - base_element;
781 return base_element + (element_phase + step + num_elements) % num_elements;
784 int el2gfx(int element)
788 case EL_EMPTY: return -1;
789 case EL_GRID_STEEL_00: return GFX_GRID_STEEL_00;
790 case EL_GRID_STEEL_01: return GFX_GRID_STEEL_01;
791 case EL_GRID_STEEL_02: return GFX_GRID_STEEL_02;
792 case EL_GRID_STEEL_03: return GFX_GRID_STEEL_03;
793 case EL_MCDUFFIN_RIGHT: return GFX_MCDUFFIN_RIGHT;
794 case EL_MCDUFFIN_UP: return GFX_MCDUFFIN_UP;
795 case EL_MCDUFFIN_LEFT: return GFX_MCDUFFIN_LEFT;
796 case EL_MCDUFFIN_DOWN: return GFX_MCDUFFIN_DOWN;
797 case EL_EXIT_CLOSED: return GFX_EXIT_CLOSED;
798 case EL_EXIT_OPENING_1: return GFX_EXIT_OPENING_1;
799 case EL_EXIT_OPENING_2: return GFX_EXIT_OPENING_2;
800 case EL_EXIT_OPEN: return GFX_EXIT_OPEN;
801 case EL_KETTLE: return GFX_KETTLE;
802 case EL_BOMB: return GFX_BOMB;
803 case EL_PRISM: return GFX_PRISM;
804 case EL_BLOCK_WOOD: return GFX_BLOCK_WOOD;
805 case EL_BALL_GRAY: return GFX_BALL_GRAY;
806 case EL_FUSE_ON: return GFX_FUSE_ON;
807 case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
808 case EL_PACMAN_UP: return GFX_PACMAN_UP;
809 case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
810 case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
811 case EL_POLAR_CROSS_00: return GFX_POLAR_CROSS_00;
812 case EL_POLAR_CROSS_01: return GFX_POLAR_CROSS_01;
813 case EL_POLAR_CROSS_02: return GFX_POLAR_CROSS_02;
814 case EL_POLAR_CROSS_03: return GFX_POLAR_CROSS_03;
815 case EL_MIRROR_FIXED_00: return GFX_MIRROR_FIXED_00;
816 case EL_MIRROR_FIXED_01: return GFX_MIRROR_FIXED_01;
817 case EL_MIRROR_FIXED_02: return GFX_MIRROR_FIXED_02;
818 case EL_MIRROR_FIXED_03: return GFX_MIRROR_FIXED_03;
819 case EL_GATE_STONE: return GFX_GATE_STONE;
820 case EL_KEY: return GFX_KEY;
821 case EL_LIGHTBULB_ON: return GFX_LIGHTBULB_ON;
822 case EL_LIGHTBULB_OFF: return GFX_LIGHTBULB_OFF;
823 case EL_LIGHTBALL: return GFX_BALL_RED + RND(3);;
824 case EL_BLOCK_STONE: return GFX_BLOCK_STONE;
825 case EL_GATE_WOOD: return GFX_GATE_WOOD;
826 case EL_FUEL_FULL: return GFX_FUEL_FULL;
827 case EL_GRID_WOOD_00: return GFX_GRID_WOOD_00;
828 case EL_GRID_WOOD_01: return GFX_GRID_WOOD_01;
829 case EL_GRID_WOOD_02: return GFX_GRID_WOOD_02;
830 case EL_GRID_WOOD_03: return GFX_GRID_WOOD_03;
831 case EL_FUEL_EMPTY: return GFX_FUEL_EMPTY;
832 case EL_FUSE_OFF: return GFX_FUSE_OFF;
833 case EL_PACMAN: return GFX_PACMAN;
834 case EL_REFRACTOR: return GFX_REFRACTOR;
835 case EL_CELL: return GFX_CELL;
836 case EL_MINE: return GFX_MINE;
838 /* pseudo-graphics; will be mapped to other graphics */
839 case EL_WALL_STEEL: return GFX_WALL_STEEL;
840 case EL_WALL_WOOD: return GFX_WALL_WOOD;
841 case EL_WALL_ICE: return GFX_WALL_ICE;
842 case EL_WALL_AMOEBA: return GFX_WALL_AMOEBA;
843 case EL_DF_WALL_STEEL: return GFX_DF_WALL_STEEL;
844 case EL_DF_WALL_WOOD: return GFX_DF_WALL_WOOD;
848 boolean ed = (game_status == LEVELED);
849 int base_element = get_base_element(element);
850 int element_phase = element - base_element;
853 if (IS_BEAMER(element))
854 element_phase = element - EL_BEAMER_RED_START;
855 else if (IS_FIBRE_OPTIC(element))
856 element_phase = element - EL_FIBRE_OPTIC_START;
858 if (IS_MIRROR(element))
859 base_graphic = GFX_MIRROR_START;
860 else if (IS_BEAMER_OLD(element))
861 base_graphic = GFX_BEAMER_START;
862 else if (IS_POLAR(element))
863 base_graphic = GFX_POLAR_START;
864 else if (IS_CHAR(element))
865 base_graphic = GFX_CHAR_START;
866 else if (IS_GRID_WOOD_FIXED(element))
867 base_graphic = GFX_GRID_WOOD_FIXED_00;
868 else if (IS_GRID_STEEL_FIXED(element))
869 base_graphic = GFX_GRID_STEEL_FIXED_00;
870 else if (IS_DF_MIRROR(element))
871 base_graphic = GFX_DF_MIRROR_00;
872 else if (IS_LASER(element))
873 base_graphic = GFX_LASER_RIGHT;
874 else if (IS_RECEIVER(element))
875 base_graphic = GFX_RECEIVER_RIGHT;
876 else if (IS_DF_MIRROR(element))
877 base_graphic = GFX_DF_MIRROR_00;
878 else if (IS_FIBRE_OPTIC(element))
879 base_graphic = (ed ? GFX_FIBRE_OPTIC_ED_00 : GFX_FIBRE_OPTIC_00);
880 else if (IS_GRID_WOOD_AUTO(element))
881 base_graphic = (ed ? GFX_GRID_WOOD_AUTO_00 : GFX_GRID_WOOD_FIXED_00);
882 else if (IS_GRID_STEEL_AUTO(element))
883 base_graphic = (ed ? GFX_GRID_STEEL_AUTO_00 : GFX_GRID_STEEL_FIXED_00);
884 else if (IS_DF_MIRROR_AUTO(element))
885 base_graphic = (ed ? GFX_DF_MIRROR_AUTO_00 : GFX_DF_MIRROR_00);
886 else if (IS_BEAMER(element))
887 base_graphic = GFX_BEAMER_RED_START;
891 return base_graphic + element_phase;
896 void RedrawPlayfield_MM()
901 void BlitScreenToBitmap_MM(Bitmap *target_bitmap)
903 BlitBitmap(drawto_field, target_bitmap, 0, 0, SXSIZE, SYSIZE, SX, SY);