added in-game mouse actions for Mirror Magic game engine
[rocksndiamonds.git] / src / game_mm / mm_game.c
index 5e42ceaaa4160697e4fe06a64c54022ada904f36..ca8c49c534e17f98fe83309edc890f3eb80ed27e 100644 (file)
@@ -21,7 +21,7 @@
 #define OVERLOAD_XSIZE         ENERGY_XSIZE
 #define OVERLOAD_YSIZE         MAX_LASER_OVERLOAD
 
-/* values for Explode() */
+/* values for Explode_MM() */
 #define EX_PHASE_START         0
 #define EX_NORMAL              0
 #define EX_KETTLE              1
 #define AUTO_ROTATE_DELAY      CLICK_DELAY_SHORT
 
 /* forward declaration for internal use */
+static int MovingOrBlocked2Element_MM(int, int);
+static void Bang_MM(int, int);
+static void RaiseScore_MM(int);
+static void RemoveMovingField_MM(int, int);
+static void InitMovingField_MM(int, int, int);
+static void ContinueMoving_MM(int, int);
+static void Moving2Blocked_MM(int, int, int *, int *);
 
 
-void GetPlayerConfig()
-{
-  if (!audio.sound_available)
-    setup.sound = FALSE;
-
-  if (!audio.loops_available)
-  {
-    setup.sound_loops = FALSE;
-    setup.sound_music = FALSE;
-  }
-
-  if (!video.fullscreen_available)
-    setup.fullscreen = FALSE;
-
-  setup.sound_simple = setup.sound;
-
-  SetAudioMode(setup.sound);
-}
-
 static int get_element_angle(int element)
 {
   int element_phase = get_element_phase(element);
@@ -121,7 +109,7 @@ static int get_mirrored_angle(int laser_angle, int mirror_angle)
   return (reflected_angle + 16) % 16;
 }
 
-void InitMovDir(int x, int y)
+static void InitMovDir_MM(int x, int y)
 {
   int element = Feld[x][y];
   static int direction[3][4] =
@@ -214,16 +202,7 @@ static void InitField(int x, int y, boolean init_game)
       }
       else if (IS_PACMAN(element))
       {
-#if 0
-       int phase = element - EL_PACMAN_RIGHT;
-
-       game_mm.pacman[game_mm.num_pacman].x = x;
-       game_mm.pacman[game_mm.num_pacman].y = y;
-       game_mm.pacman[game_mm.num_pacman].dir = phase + ((phase + 1) % 2) * 2;
-       game_mm.num_pacman++;
-#else
-       InitMovDir(x, y);
-#endif
+       InitMovDir_MM(x, y);
       }
       else if (IS_MCDUFFIN(element) || IS_LASER(element))
       {
@@ -309,7 +288,7 @@ static void InitLaser()
                            native_mm_level.laser_blue  * 0xFF);
 }
 
-void InitGame()
+void InitGameEngine_MM()
 {
   int i, x, y;
 
@@ -365,15 +344,19 @@ void InitGame()
     }
   }
 
+#if 0
   CloseDoor(DOOR_CLOSE_1);
+#endif
 
   DrawLevel_MM();
   InitCycleElements();
   InitLaser();
 
+#if 0
   /* copy default game door content to main double buffer */
   BlitBitmap(pix[PIX_DOOR], drawto,
             DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+#endif
 
 #if 0
   DrawText(DX_LEVEL, DY_LEVEL,
@@ -384,33 +367,37 @@ void InitGame()
           int2str(game_mm.score, 4), FONT_TEXT_2);
 #endif
 
+#if 0
   UnmapGameButtons();
-  /*
-  game_gadget[SOUND_CTRL_ID_MUSIC]->checked = setup.sound_music;
-  game_gadget[SOUND_CTRL_ID_LOOPS]->checked = setup.sound_loops;
-  game_gadget[SOUND_CTRL_ID_SIMPLE]->checked = setup.sound_simple;
-  */
   MapGameButtons();
+#endif
 
+#if 0
   /* copy actual game door content to door double buffer for OpenDoor() */
   BlitBitmap(drawto, pix[PIX_DB_DOOR],
             DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+#endif
 
+#if 0
   OpenDoor(DOOR_OPEN_ALL);
+#endif
 
   if (setup.sound_loops)
     PlaySoundExt(SND_FUEL, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT, SND_CTRL_PLAY_LOOP);
 
+#if 0 // !!! TEMPORARILY DISABLED !!!
   for(i=0; i<=game_mm.energy_left; i+=2)
   {
     if (!setup.sound_loops)
       PlaySoundStereo(SND_FUEL, SOUND_MAX_RIGHT);
 
+#if 0
     BlitBitmap(pix[PIX_DOOR], drawto,
               DOOR_GFX_PAGEX4 + XX_ENERGY,
               DOOR_GFX_PAGEY1 + YY_ENERGY + ENERGY_YSIZE - i,
               ENERGY_XSIZE, i,
               DX_ENERGY, DY_ENERGY + ENERGY_YSIZE - i);
+#endif
 
     redraw_mask |= REDRAW_DOOR_1;
     BackToFront();
@@ -427,9 +414,12 @@ void InitGame()
 
   if (setup.sound_loops)
     StopSound(SND_FUEL);
+#endif
 
+#if 0
   if (setup.sound_music && num_bg_loops)
     PlayMusic(level_nr % num_bg_loops);
+#endif
 
   ScanLaser();
 }
@@ -477,13 +467,13 @@ boolean StepBehind()
 static int getMaskFromElement(int element)
 {
   if (IS_GRID(element))
-    return GFX_MASK_GRID_00 + get_element_phase(element);
+    return IMG_MM_MASK_GRID_1 + get_element_phase(element);
   else if (IS_MCDUFFIN(element))
-    return GFX_MASK_MCDUFFIN_00 + get_element_phase(element);
+    return IMG_MM_MASK_MCDUFFIN_RIGHT + get_element_phase(element);
   else if (IS_RECTANGLE(element) || IS_DF_GRID(element))
-    return GFX_MASK_RECTANGLE;
+    return IMG_MM_MASK_RECTANGLE;
   else
-    return GFX_MASK_CIRCLE;
+    return IMG_MM_MASK_CIRCLE;
 }
 
 int ScanPixel()
@@ -501,7 +491,7 @@ int ScanPixel()
     int i;
 
 #if 0
-    /* for security */
+    /* for safety */
     if (SX + LX < REAL_SX || SX + LX >= REAL_SX + FULL_SXSIZE ||
        SY + LY < REAL_SY || SY + LY >= REAL_SY + FULL_SYSIZE)
     {
@@ -541,11 +531,15 @@ int ScanPixel()
          int mask_x, mask_y;
          int dx = px - lx * TILEX;
          int dy = py - ly * TILEY;
+         Bitmap *bitmap;
+         int src_x, src_y;
+
+         getGraphicSource(graphic_mask, 0, &bitmap, &src_x, &src_y);
 
-         mask_x = (graphic_mask % GFX_PER_LINE) * TILEX + dx;
-         mask_y = (graphic_mask / GFX_PER_LINE) * TILEY + dy;
+         mask_x = src_x + dx;
+         mask_y = src_y + dy;
 
-         pixel = (ReadPixel(pix[PIX_BACK], mask_x, mask_y) ? 1 : 0);
+         pixel = (ReadPixel(bitmap, mask_x, mask_y) ? 1 : 0);
        }
       }
       else
@@ -576,23 +570,10 @@ void ScanLaser()
 {
   int element;
   int end = 0, rf = laser.num_edges;
-#if 0
-  unsigned short color_scale = 0xFFFF / 15;
-#endif
-#if 0
-  int testx, testy;
-#endif
 
   laser.overloaded = FALSE;
   laser.stops_inside_element = FALSE;
 
-#if 0
-  if (laser.overload_value < MAX_LASER_OVERLOAD - 8)
-    SetRGB(pen_ray,
-          (laser.overload_value / 6) * color_scale, 0x0000,
-          (15 - (laser.overload_value / 6)) * color_scale);
-#endif
-
   DrawLaser(0, DL_LASER_ENABLED);
 
 #if 0
@@ -655,7 +636,6 @@ void ScanLaser()
       ELY = (LY - 2) / TILEY;
     }
 
-
 #if 0
     printf("hit_mask (2) == '%x' (%d, %d) (%d, %d)\n",
           hit_mask, LX, LY, ELX, ELY);
@@ -677,11 +657,6 @@ void ScanLaser()
       printf("WARNING! (1) %d, %d (%d)\n", ELX, ELY, element);
 #endif
 
-#if 0
-    testx = ELX;
-    testy = ELY;
-#endif
-
     if (element == EL_EMPTY)
     {
       if (!HitOnlyAnEdge(element, hit_mask))
@@ -741,14 +716,6 @@ void ScanLaser()
     rf = laser.num_edges;
   }
 
-  /*
-    element = Feld[ELX][ELY];
-    laser.dest_element = element;
-  */
-
-
-
-
 #if 0
   if (laser.dest_element != Feld[ELX][ELY])
   {
@@ -757,7 +724,6 @@ void ScanLaser()
   }
 #endif
 
-
   if (!end && !laser.stops_inside_element && !StepBehind())
   {
 #if 0
@@ -774,19 +740,10 @@ void ScanLaser()
 
   Ct = CT = Counter();
 
-
 #if 0
     if (!IN_LEV_FIELD(ELX, ELY))
       printf("WARNING! (2) %d, %d\n", ELX, ELY);
 #endif
-
-
-#if 0
-  printf("(%d, %d) == %d  [(%d, %d) == %d]\n",
-        testx, testy, laser.dest_element,
-        ELX, ELY, (IN_SCR_FIELD(ELX,ELY) ? Feld[ELX][ELY] : -1));
-#endif
-
 }
 
 void DrawLaserExt(int start_edge, int num_edges, int mode)
@@ -868,7 +825,6 @@ void DrawLaserExt(int start_edge, int num_edges, int mode)
     ely = laser.damage[damage_start].y;
     element = Feld[elx][ely];
 
-
 #if 0
     if (IS_BEAMER(element))
     {
@@ -1053,7 +1009,7 @@ boolean HitElement(int element, int hit_mask)
     return FALSE;
 
   if (IS_MOVING(ELX, ELY) || IS_BLOCKED(ELX, ELY))
-    element = MovingOrBlocked2Element(ELX, ELY);
+    element = MovingOrBlocked2Element_MM(ELX, ELY);
 
 #if 0
   printf("HitElement (1): element == %d\n", element);
@@ -1068,18 +1024,6 @@ boolean HitElement(int element, int hit_mask)
 
   AddDamagedField(ELX, ELY);
 
-#if 0
-  if (ELX != (LX + 5 * XS) / TILEX ||
-      ELY != (LY + 5 * YS) / TILEY)
-  {
-    LX += 2 * XS;
-    LY += 2 * YS;
-
-    return FALSE;
-  }
-
-#else
-
   /* this is more precise: check if laser would go through the center */
   if ((ELX * TILEX + 14 - LX) * YS != (ELY * TILEY + 14 - LY) * XS)
   {
@@ -1104,7 +1048,6 @@ boolean HitElement(int element, int hit_mask)
 
     return FALSE;
   }
-#endif
 
 #if 0
   printf("HitElement (2): element == %d\n", element);
@@ -1242,19 +1185,14 @@ boolean HitElement(int element, int hit_mask)
       IS_PACMAN(element))
   {
     if (!IS_PACMAN(element))
-      Bang(ELX, ELY);
+      Bang_MM(ELX, ELY);
 
     if (element == EL_PACMAN)
-      Bang(ELX, ELY);
+      Bang_MM(ELX, ELY);
 
     if (element == EL_KETTLE || element == EL_CELL)
     {
-#if 0
-      if (game_mm.kettles_still_needed)
-       DrawText(DX_KETTLES, DY_KETTLES,
-                int2str(--game_mm.kettles_still_needed, 3), FONT_TEXT_2);
-#endif
-      RaiseScore(10);
+      RaiseScore_MM(10);
 
       if (game_mm.kettles_still_needed == 0)
       {
@@ -1301,11 +1239,11 @@ boolean HitElement(int element, int hit_mask)
     else if (element == EL_KEY)
       game_mm.num_keys++;
     else if (element == EL_LIGHTBALL)
-      RaiseScore(10);
+      RaiseScore_MM(10);
     else if (IS_PACMAN(element))
     {
       DeletePacMan(ELX, ELY);
-      RaiseScore(50);
+      RaiseScore_MM(50);
     }
 
     return FALSE;
@@ -1488,18 +1426,6 @@ boolean HitPolarizer(int element, int hit_mask)
     if (laser.current_angle == grid_angle ||
        laser.current_angle == get_opposite_angle(grid_angle))
     {
-#if 0
-      int step_size;
-
-      if (!IS_22_5_ANGLE(laser.current_angle)) /* 90° or 45° angle */
-       step_size = 8;
-      else
-       step_size = 4;
-
-      LX += step_size * XS;
-      LY += step_size * YS;
-#else
-
       /* skip the whole element before continuing the scan */
       do
       {
@@ -1518,7 +1444,6 @@ boolean HitPolarizer(int element, int hit_mask)
        LX -= XS;
        LY -= YS;
       }
-#endif
 
       AddLaserEdge(LX, LY);
 
@@ -1611,7 +1536,7 @@ boolean HitBlock(int element, int hit_mask)
                                  hit_mask == HIT_MASK_RIGHT));
     AddLaserEdge(LX, LY);
 
-    Bang(ELX, ELY);
+    Bang_MM(ELX, ELY);
 
     game_mm.num_keys--;
     if (element == EL_GATE_STONE && Box[ELX][ELY])
@@ -2042,14 +1967,7 @@ void OpenSurpriseBall(int x, int y)
 
   if (MovDelay[x][y])          /* wait some time before next frame */
   {
-#if 0
-    int phase;
-#endif
-
     MovDelay[x][y]--;
-#if 0
-    phase = MovDelay[x][y] / delay;
-#endif
     if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(x, y))
     {
       Bitmap *bitmap;
@@ -2153,14 +2071,11 @@ void GrowAmoeba(int x, int y)
   }
 }
 
-void Explode(int x, int y, int phase, int mode)
+static void Explode_MM(int x, int y, int phase, int mode)
 {
   int num_phase = 9, delay = 2;
   int last_phase = num_phase * delay;
   int half_phase = (num_phase / 2) * delay;
-#if 0
-  int first_phase_after_start = EX_PHASE_START + 1;
-#endif
 
   laser.redraw = TRUE;
 
@@ -2171,8 +2086,8 @@ void Explode(int x, int y, int phase, int mode)
     if (IS_MOVING(x, y) || IS_BLOCKED(x, y))
     {
       /* put moving element to center field (and let it explode there) */
-      center_element = MovingOrBlocked2Element(x, y);
-      RemoveMovingField(x, y);
+      center_element = MovingOrBlocked2Element_MM(x, y);
+      RemoveMovingField_MM(x, y);
       Feld[x][y] = center_element;
     }
 
@@ -2200,17 +2115,13 @@ void Explode(int x, int y, int phase, int mode)
 
   if (phase == last_phase)
   {
-#if 0
-    int element;
-#endif
-
     if (Store[x][y] == EL_BOMB)
     {
       laser.num_damages--;
       DrawLaser(0, DL_LASER_DISABLED);
       laser.num_edges = 0;
 
-      Bang(laser.start_edge.x, laser.start_edge.y);
+      Bang_MM(laser.start_edge.x, laser.start_edge.y);
       Store[x][y] = EL_EMPTY;
     }
     else if (IS_MCDUFFIN(Store[x][y]))
@@ -2220,9 +2131,6 @@ void Explode(int x, int y, int phase, int mode)
       Store[x][y] = EL_EMPTY;
     }
 
-#if 0
-    element = Feld[x][y] = Store[x][y];
-#endif
     Store[x][y] = Store2[x][y] = 0;
     MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
     InitField(x, y, FALSE);
@@ -2230,28 +2138,29 @@ void Explode(int x, int y, int phase, int mode)
   }
   else if (!(phase % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
   {
-    int graphic = GFX_EXPLOSION_START;
+    int graphic = IMG_MM_DEFAULT_EXPLODING;
     int graphic_phase = (phase / delay - 1);
+    Bitmap *bitmap;
+    int src_x, src_y;
 
     if (Store2[x][y] == EX_KETTLE)
     {
       if (graphic_phase < 3)
-       graphic = GFX_EXPLOSION_KETTLE;
+       graphic = IMG_MM_KETTLE_EXPLODING;
       else if (graphic_phase < 5)
       {
-       graphic = GFX_EXPLOSION_LAST;
-       graphic_phase -= graphic_phase;
+       graphic_phase += 3;
       }
       else
       {
-       graphic = GFX_EMPTY;
+       graphic = IMG_EMPTY;
        graphic_phase = 0;
       }
     }
     else if (Store2[x][y] == EX_SHORT)
     {
       if (graphic_phase < 4)
-       graphic = GFX_EXPLOSION_SHORT;
+       graphic_phase += 4;
       else
       {
        graphic = GFX_EMPTY;
@@ -2259,11 +2168,15 @@ void Explode(int x, int y, int phase, int mode)
       }
     }
 
-    DrawGraphic_MM(x, y, graphic + graphic_phase);
+    getGraphicSource(graphic, graphic_phase, &bitmap, &src_x, &src_y);
+
+    BlitBitmap(bitmap, drawto_field, src_x, src_y, TILEX, TILEY,
+              FX + x * TILEX, FY + y * TILEY);
+    MarkTileDirty(x, y);
   }
 }
 
-void Bang(int x, int y)
+static void Bang_MM(int x, int y)
 {
   int element = Feld[x][y];
   int mode = EX_NORMAL;
@@ -2297,7 +2210,7 @@ void Bang(int x, int y)
   else
     PlaySoundStereo((mode == EX_SHORT ? SND_WHOOSH : SND_KABUMM), ST(x));
 
-  Explode(x, y, EX_PHASE_START, mode);
+  Explode_MM(x, y, EX_PHASE_START, mode);
 }
 
 void TurnRound(int x, int y)
@@ -2331,34 +2244,15 @@ void TurnRound(int x, int y)
 
   int element = Feld[x][y];
   int old_move_dir = MovDir[x][y];
-#if 0
-  int left_dir = turn[old_move_dir].left;
-#endif
   int right_dir = turn[old_move_dir].right;
   int back_dir = turn[old_move_dir].back;
-
-#if 0
-  int left_dx = move_xy[left_dir].x, left_dy = move_xy[left_dir].y;
-#endif
   int right_dx = move_xy[right_dir].x, right_dy = move_xy[right_dir].y;
-
-#if 0
-  int left_x = x+left_dx, left_y = y+left_dy;
-#endif
   int right_x = x+right_dx, right_y = y+right_dy;
 
   if (element == EL_PACMAN)
   {
-#if 0
-    boolean can_turn_left = FALSE;
-#endif
     boolean can_turn_right = FALSE;
 
-#if 0
-    if (IN_LEV_FIELD(left_x, left_y) &&
-       IS_EATABLE4PACMAN(Feld[left_x][left_y]))
-      can_turn_left = TRUE;
-#endif
     if (IN_LEV_FIELD(right_x, right_y) &&
        IS_EATABLE4PACMAN(Feld[right_x][right_y]))
       can_turn_right = TRUE;
@@ -2372,7 +2266,7 @@ void TurnRound(int x, int y)
   }
 }
 
-void StartMoving(int x, int y)
+static void StartMoving_MM(int x, int y)
 {
   int element = Feld[x][y];
 
@@ -2393,7 +2287,7 @@ void StartMoving(int x, int y)
 
     /* now make next step */
 
-    Moving2Blocked(x, y, &newx, &newy);        /* get next screen position */
+    Moving2Blocked_MM(x, y, &newx, &newy);     /* get next screen position */
 
     if (element == EL_PACMAN &&
        IN_LEV_FIELD(newx, newy) && IS_EATABLE4PACMAN(Feld[newx][newy]) &&
@@ -2413,14 +2307,14 @@ void StartMoving(int x, int y)
       return;
     }
 
-    InitMovingField(x, y, MovDir[x][y]);
+    InitMovingField_MM(x, y, MovDir[x][y]);
   }
 
   if (MovDir[x][y])
-    ContinueMoving(x, y);
+    ContinueMoving_MM(x, y);
 }
 
-void ContinueMoving(int x, int y)
+static void ContinueMoving_MM(int x, int y)
 {
   int element = Feld[x][y];
   int direction = MovDir[x][y];
@@ -2451,7 +2345,7 @@ void ContinueMoving(int x, int y)
     if (element == EL_PACMAN)
     {
       if (Store[newx][newy] == EL_BOMB)
-       Bang(newx, newy);
+       Bang_MM(newx, newy);
 
       if (IS_WALL_AMOEBA(Store[newx][newy]) &&
          (LX + 2 * XS) / TILEX == newx &&
@@ -2541,7 +2435,7 @@ void ClickElement(int mx, int my, int button)
     laser.fuse_off = FALSE;
     laser.fuse_x = laser.fuse_y = -1;
 
-    DrawGraphic_MM(x, y, GFX_FUSE_ON);
+    DrawGraphic_MM(x, y, IMG_MM_FUSE_ACTIVE);
     ScanLaser();
   }
   else if (element == EL_FUSE_ON && !laser.fuse_off && new_button)
@@ -2552,12 +2446,12 @@ void ClickElement(int mx, int my, int button)
     laser.overloaded = FALSE;
 
     DrawLaser(0, DL_LASER_DISABLED);
-    DrawGraphic_MM(x, y, GFX_FUSE_OFF);
+    DrawGraphic_MM(x, y, IMG_MM_FUSE);
   }
   else if (element == EL_LIGHTBALL)
   {
-    Bang(x, y);
-    RaiseScore(10);
+    Bang_MM(x, y);
+    RaiseScore_MM(10);
     DrawLaser(0, DL_LASER_ENABLED);
   }
 
@@ -2721,7 +2615,7 @@ void DeletePacMan(int px, int py)
 {
   int i, j;
 
-  Bang(px, py);
+  Bang_MM(px, py);
 
   if (game_mm.num_pacman <= 1)
   {
@@ -2786,30 +2680,18 @@ void ColorCycling(void)
   }
 }
 
-void GameActions()
+static void GameActions_MM_Ext(byte action[MAX_PLAYERS], boolean warp_mode)
 {
   static unsigned int action_delay = 0;
   static unsigned int pacman_delay = 0;
   static unsigned int energy_delay = 0;
   static unsigned int overload_delay = 0;
-#if 0
-  unsigned short color_scale = 0xFFFF / 15;
-#endif
   int element;
   int x, y, i;
 
   int r, d;
 
-#if 1
   WaitUntilDelayReached(&action_delay, GameFrameDelay);
-#else
-  if (!DelayReached(&action_delay, GameFrameDelay))
-  {
-    if (!PendingEvent())       /* delay only if no pending events */
-      Delay(10);
-    return;
-  }
-#endif
 
   for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
     Stop[x][y] = FALSE;
@@ -2819,11 +2701,11 @@ void GameActions()
     element = Feld[x][y];
 
     if (!IS_MOVING(x, y) && CAN_MOVE(element))
-      StartMoving(x, y);
+      StartMoving_MM(x, y);
     else if (IS_MOVING(x, y))
-      ContinueMoving(x, y);
+      ContinueMoving_MM(x, y);
     else if (IS_EXPLODING(element))
-      Explode(x, y, Frame[x][y], EX_NORMAL);
+      Explode_MM(x, y, Frame[x][y], EX_NORMAL);
     else if (element == EL_EXIT_OPENING)
       OpenExit(x, y);
     else if (element == EL_GRAY_BALL_OPENING)
@@ -2839,7 +2721,7 @@ void GameActions()
 #if 1
   /* !!! CHANGE THIS: REDRAW ONLY WHEN NEEDED !!! */
 
-  /* redraw after Explode() ... */
+  /* redraw after Explode_MM() ... */
   if (laser.redraw)
     DrawLaser(0, DL_LASER_ENABLED);
   laser.redraw = FALSE;
@@ -2863,10 +2745,12 @@ void GameActions()
     game_mm.energy_left--;
     if (game_mm.energy_left >= 0)
     {
+#if 0
       BlitBitmap(pix[PIX_DOOR], drawto,
                 DOOR_GFX_PAGEX5 + XX_ENERGY, DOOR_GFX_PAGEY1 + YY_ENERGY,
                 ENERGY_XSIZE, ENERGY_YSIZE - game_mm.energy_left,
                 DX_ENERGY, DY_ENERGY);
+#endif
       redraw_mask |= REDRAW_DOOR_1;
     }
     else if (setup.time_limit)
@@ -2978,6 +2862,7 @@ void GameActions()
 
     if (laser.overloaded)
     {
+#if 0
       BlitBitmap(pix[PIX_DOOR], drawto,
                 DOOR_GFX_PAGEX4 + XX_OVERLOAD,
                 DOOR_GFX_PAGEY1 + YY_OVERLOAD + OVERLOAD_YSIZE
@@ -2985,14 +2870,17 @@ void GameActions()
                 OVERLOAD_XSIZE, laser.overload_value,
                 DX_OVERLOAD, DY_OVERLOAD + OVERLOAD_YSIZE
                 - laser.overload_value);
+#endif
       redraw_mask |= REDRAW_DOOR_1;
     }
     else
     {
+#if 0
       BlitBitmap(pix[PIX_DOOR], drawto,
                 DOOR_GFX_PAGEX5 + XX_OVERLOAD, DOOR_GFX_PAGEY1 + YY_OVERLOAD,
                 OVERLOAD_XSIZE, OVERLOAD_YSIZE - laser.overload_value,
                 DX_OVERLOAD, DY_OVERLOAD);
+#endif
       redraw_mask |= REDRAW_DOOR_1;
     }
 
@@ -3049,17 +2937,17 @@ void GameActions()
     laser.num_edges = 0;
 #endif
 
-    Bang(ELX, ELY);
+    Bang_MM(ELX, ELY);
 
     laser.dest_element = EL_EXPLODING_OPAQUE;
 
 #if 0
-    Bang(ELX, ELY);
+    Bang_MM(ELX, ELY);
     laser.num_damages--;
     DrawLaser(0, DL_LASER_DISABLED);
 
     laser.num_edges = 0;
-    Bang(laser.start_edge.x, laser.start_edge.y);
+    Bang_MM(laser.start_edge.x, laser.start_edge.y);
 
     if (Request("Bomb killed Mc Duffin ! Play it again ?",
                REQ_ASK | REQ_STAY_CLOSED))
@@ -3082,7 +2970,7 @@ void GameActions()
     laser.fuse_x = ELX;
     laser.fuse_y = ELY;
     DrawLaser(0, DL_LASER_DISABLED);
-    DrawGraphic_MM(ELX, ELY, GFX_FUSE_OFF);
+    DrawGraphic_MM(ELX, ELY, IMG_MM_FUSE);
   }
 
   if (element == EL_BALL_GRAY && CT > 1500)
@@ -3144,11 +3032,13 @@ void GameActions()
       int x = RND(26);
       int y = RND(26);
 
+#if 0
       BlitBitmap(pix[PIX_BACK], drawto,
                 SX + (graphic % GFX_PER_LINE) * TILEX + x,
                 SY + (graphic / GFX_PER_LINE) * TILEY + y, 6, 6,
                 SX + ELX * TILEX + x,
                 SY + ELY * TILEY + y);
+#endif
       MarkTileDirty(ELX, ELY);
       BackToFront();
 
@@ -3440,11 +3330,13 @@ void GameActions()
   {
     for(i=game_mm.energy_left; i<=MAX_LASER_ENERGY; i+=2)
     {
+#if 0
       BlitBitmap(pix[PIX_DOOR], drawto,
                 DOOR_GFX_PAGEX4 + XX_ENERGY,
                 DOOR_GFX_PAGEY1 + YY_ENERGY + ENERGY_YSIZE - i,
                 ENERGY_XSIZE, i, DX_ENERGY,
                 DY_ENERGY + ENERGY_YSIZE - i);
+#endif
 
       redraw_mask |= REDRAW_DOOR_1;
       BackToFront();
@@ -3464,6 +3356,14 @@ void GameActions()
   return;
 }
 
+void GameActions_MM(byte action[MAX_PLAYERS], boolean warp_mode)
+{
+  if (!button_status)
+    ClickElement(0, 0, MB_NOT_PRESSED);
+
+  GameActions_MM_Ext(action, warp_mode);
+}
+
 void MovePacMen()
 {
   static int p = -1;
@@ -3516,7 +3416,7 @@ void MovePacMen()
     game_mm.pacman[p].x = nx;
     game_mm.pacman[p].y = ny;
     g = Feld[nx][ny] - EL_PACMAN_RIGHT;
-    DrawGraphic_MM(ox, oy, GFX_EMPTY);
+    DrawGraphic_MM(ox, oy, IMG_EMPTY);
 
     if (element != EL_EMPTY)
     {
@@ -3528,12 +3428,15 @@ void MovePacMen()
 
       for(i=1; i<33; i+=2)
       {
+#if 1
+       // !!! temporary fix to compile -- change to game graphics !!!
+       BlitBitmap(drawto, window,
+                  SX + g * TILEX, SY + 4 * TILEY, TILEX, TILEY,
+                  ox + i * mx, oy + i * my);
+#else
        BlitBitmap(pix[PIX_BACK], window,
                   SX + g * TILEX, SY + 4 * TILEY, TILEX, TILEY,
                   ox + i * mx, oy + i * my);
-#if 0
-       FlushDisplay();
-       Delay(1);
 #endif
       }
       Ct = Ct + Counter() - CT;
@@ -3568,7 +3471,7 @@ void MovePacMen()
   }
 }
 
-void GameWon()
+void GameWon_MM()
 {
   int hi_pos;
   boolean raise_level = FALSE;
@@ -3592,18 +3495,20 @@ void GameWon()
 
       /*
       if (game_mm.energy_left > 0 && !(game_mm.energy_left % 10))
-       RaiseScore(native_mm_level.score[SC_ZEITBONUS]);
+       RaiseScore_MM(native_mm_level.score[SC_ZEITBONUS]);
       */
 
-      RaiseScore(5);
+      RaiseScore_MM(5);
 
       game_mm.energy_left--;
       if (game_mm.energy_left >= 0)
       {
+#if 0
        BlitBitmap(pix[PIX_DOOR], drawto,
                   DOOR_GFX_PAGEX5 + XX_ENERGY, DOOR_GFX_PAGEY1 + YY_ENERGY,
                   ENERGY_XSIZE, ENERGY_YSIZE - game_mm.energy_left,
                   DX_ENERGY, DY_ENERGY);
+#endif
        redraw_mask |= REDRAW_DOOR_1;
       }
 
@@ -3624,7 +3529,7 @@ void GameWon()
       if (!setup.sound_loops)
        PlaySoundStereo(SND_SIRR, SOUND_MAX_RIGHT);
       if (TimePlayed < 999 && !(TimePlayed % 10))
-       RaiseScore(native_mm_level.score[SC_ZEITBONUS]);
+       RaiseScore_MM(native_mm_level.score[SC_ZEITBONUS]);
       if (TimePlayed < 900 && !(TimePlayed % 10))
        TimePlayed += 10;
       else
@@ -3661,7 +3566,7 @@ void GameWon()
   else if (level_nr < leveldir_current->last_level)
     raise_level = TRUE;                /* advance to next level */
 
-  if ((hi_pos = NewHiScore()) >= 0)
+  if ((hi_pos = NewHiScore_MM()) >= 0)
   {
     game_status = HALLOFFAME;
     // DrawHallOfFame(hi_pos);
@@ -3679,7 +3584,7 @@ void GameWon()
   BackToFront();
 }
 
-int NewHiScore()
+int NewHiScore_MM()
 {
   int k, l;
   int position = -1;
@@ -3739,7 +3644,7 @@ int NewHiScore()
   return position;
 }
 
-void InitMovingField(int x, int y, int direction)
+static void InitMovingField_MM(int x, int y, int direction)
 {
   int newx = x + (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
   int newy = y + (direction == MV_UP   ? -1 : direction == MV_DOWN  ? +1 : 0);
@@ -3750,7 +3655,7 @@ void InitMovingField(int x, int y, int direction)
     Feld[newx][newy] = EL_BLOCKED;
 }
 
-void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
+static void Moving2Blocked_MM(int x, int y, int *goes_to_x, int *goes_to_y)
 {
   int direction = MovDir[x][y];
   int newx = x + (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
@@ -3760,7 +3665,8 @@ void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
   *goes_to_y = newy;
 }
 
-void Blocked2Moving(int x, int y, int *comes_from_x, int *comes_from_y)
+static void Blocked2Moving_MM(int x, int y,
+                             int *comes_from_x, int *comes_from_y)
 {
   int oldx = x, oldy = y;
   int direction = MovDir[x][y];
@@ -3778,7 +3684,7 @@ void Blocked2Moving(int x, int y, int *comes_from_x, int *comes_from_y)
   *comes_from_y = oldy;
 }
 
-int MovingOrBlocked2Element(int x, int y)
+static int MovingOrBlocked2Element_MM(int x, int y)
 {
   int element = Feld[x][y];
 
@@ -3786,7 +3692,7 @@ int MovingOrBlocked2Element(int x, int y)
   {
     int oldx, oldy;
 
-    Blocked2Moving(x, y, &oldx, &oldy);
+    Blocked2Moving_MM(x, y, &oldx, &oldy);
     return Feld[oldx][oldy];
   }
   else
@@ -3803,7 +3709,7 @@ static void RemoveField(int x, int y)
 }
 #endif
 
-void RemoveMovingField(int x, int y)
+static void RemoveMovingField_MM(int x, int y)
 {
   int oldx = x, oldy = y, newx = x, newy = y;
 
@@ -3812,13 +3718,13 @@ void RemoveMovingField(int x, int y)
 
   if (IS_MOVING(x, y))
   {
-    Moving2Blocked(x, y, &newx, &newy);
+    Moving2Blocked_MM(x, y, &newx, &newy);
     if (Feld[newx][newy] != EL_BLOCKED)
       return;
   }
   else if (Feld[x][y] == EL_BLOCKED)
   {
-    Blocked2Moving(x, y, &oldx, &oldy);
+    Blocked2Moving_MM(x, y, &oldx, &oldy);
     if (!IS_MOVING(oldx, oldy))
       return;
   }
@@ -3870,7 +3776,7 @@ void PlaySoundLevel(int x, int y, int sound_nr)
   PlaySoundExt(sound_nr, volume, stereo, SND_CTRL_PLAY_SOUND);
 }
 
-void RaiseScore(int value)
+static void RaiseScore_MM(int value)
 {
   game_mm.score += value;
 #if 0
@@ -3879,15 +3785,15 @@ void RaiseScore(int value)
 #endif
 }
 
-void RaiseScoreElement(int element)
+void RaiseScoreElement_MM(int element)
 {
   switch(element)
   {
     case EL_PACMAN:
-      RaiseScore(native_mm_level.score[SC_PACMAN]);
+      RaiseScore_MM(native_mm_level.score[SC_PACMAN]);
       break;
     case EL_KEY:
-      RaiseScore(native_mm_level.score[SC_KEY]);
+      RaiseScore_MM(native_mm_level.score[SC_KEY]);
       break;
     default:
       break;