// values for Explode_MM()
#define EX_PHASE_START 0
-#define EX_NORMAL 0
-#define EX_KETTLE 1
-#define EX_SHORT 2
+#define EX_TYPE_NONE 0
+#define EX_TYPE_NORMAL (1 << 0)
// special positions in the game control window (relative to control window)
#define XX_LEVEL 36
static int pacman_nr = -1;
// various game engine delay counters
-static unsigned int rotate_delay = 0;
-static unsigned int pacman_delay = 0;
-static unsigned int energy_delay = 0;
-static unsigned int overload_delay = 0;
+static DelayCounter rotate_delay = { AUTO_ROTATE_DELAY };
+static DelayCounter pacman_delay = { PACMAN_MOVE_DELAY };
+static DelayCounter energy_delay = { ENERGY_DELAY };
+static DelayCounter overload_delay = { 0 };
+
+// element mask positions for scanning pixels of MM elements
+#define MM_MASK_MCDUFFIN_RIGHT 0
+#define MM_MASK_MCDUFFIN_UP 1
+#define MM_MASK_MCDUFFIN_LEFT 2
+#define MM_MASK_MCDUFFIN_DOWN 3
+#define MM_MASK_GRID_1 4
+#define MM_MASK_GRID_2 5
+#define MM_MASK_GRID_3 6
+#define MM_MASK_GRID_4 7
+#define MM_MASK_RECTANGLE 8
+#define MM_MASK_CIRCLE 9
+
+#define NUM_MM_MASKS 10
// element masks for scanning pixels of MM elements
-static const char mm_masks[10][16][16 + 1] =
+static const char mm_masks[NUM_MM_MASKS][16][16 + 1] =
{
{
" ",
PlayLevelSound_MM(exit_x, exit_y, exit_element, MM_ACTION_OPENING);
}
+static void SetLaserColor(int brightness)
+{
+ int color_min = 0x00;
+ int color_max = brightness; // (0x00 <= brightness <= 0xFF)
+ int color_up = color_max * laser.overload_value / MAX_LASER_OVERLOAD;
+ int color_down = color_max - color_up;
+
+ pen_ray =
+ GetPixelFromRGB(window,
+ (game_mm.laser_red ? color_max : color_up),
+ (game_mm.laser_green ? color_down : color_min),
+ (game_mm.laser_blue ? color_down : color_min));
+}
+
static void InitMovDir_MM(int x, int y)
{
int element = Tile[x][y];
case EL_KETTLE:
case EL_CELL:
- if (native_mm_level.auto_count_kettles)
+ if (init_game && native_mm_level.auto_count_kettles)
game_mm.kettles_still_needed++;
break;
}
else if (IS_MCDUFFIN(element) || IS_LASER(element))
{
- laser.start_edge.x = x;
- laser.start_edge.y = y;
- laser.start_angle = get_element_angle(element);
+ if (init_game)
+ {
+ laser.start_edge.x = x;
+ laser.start_edge.y = y;
+ laser.start_angle = get_element_angle(element);
+ }
+
+ if (IS_MCDUFFIN(element))
+ {
+ game_mm.laser_red = native_mm_level.mm_laser_red;
+ game_mm.laser_green = native_mm_level.mm_laser_green;
+ game_mm.laser_blue = native_mm_level.mm_laser_blue;
+ }
+ else
+ {
+ game_mm.laser_red = native_mm_level.df_laser_red;
+ game_mm.laser_green = native_mm_level.df_laser_green;
+ game_mm.laser_blue = native_mm_level.df_laser_blue;
+ }
}
break;
Tile[x][y] = next_element;
- DrawField_MM(x, y);
game_mm.cycle[i].steps -= step;
}
}
AddLaserEdge(LX, LY); // set laser starting edge
- pen_ray = GetPixelFromRGB(window,
- native_mm_level.laser_red * 0xFF,
- native_mm_level.laser_green * 0xFF,
- native_mm_level.laser_blue * 0xFF);
+ SetLaserColor(0xFF);
}
void InitGameEngine_MM(void)
(native_mm_level.auto_count_kettles ? 0 : native_mm_level.kettles_needed);
game_mm.lights_still_needed = 0;
game_mm.num_keys = 0;
+ game_mm.ball_choice_pos = 0;
+
+ game_mm.laser_red = FALSE;
+ game_mm.laser_green = FALSE;
+ game_mm.laser_blue = TRUE;
game_mm.level_solved = FALSE;
game_mm.game_over = FALSE;
laser.fuse_x = laser.fuse_y = -1;
laser.dest_element = EL_EMPTY;
+ laser.dest_element_last = EL_EMPTY;
+ laser.dest_element_last_x = -1;
+ laser.dest_element_last_y = -1;
laser.wall_mask = 0;
last_LX = 0;
CT = Ct = 0;
- rotate_delay = 0;
- pacman_delay = 0;
- energy_delay = 0;
- overload_delay = 0;
+ rotate_delay.count = 0;
+ pacman_delay.count = 0;
+ energy_delay.count = 0;
+ overload_delay.count = 0;
ClickElement(-1, -1, -1);
Angle[x][y] = 0;
MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
Store[x][y] = Store2[x][y] = 0;
- Frame[x][y] = 0;
Stop[x][y] = FALSE;
InitField(x, y, TRUE);
cycle_steps_done++;
}
- BackToFront();
+ AdvanceFrameCounter();
+ AdvanceGfxFrame();
+
+ DrawLevel_MM();
- ColorCycling();
+ BackToFront();
#ifdef DEBUG
if (setup.quick_doors)
SetTileCursorXY(laser.start_edge.x, laser.start_edge.y);
SetTileCursorActive(TRUE);
+
+ // restart all delay counters after initially cycling game elements
+ ResetFrameCounter(&rotate_delay);
+ ResetFrameCounter(&pacman_delay);
+ ResetFrameCounter(&energy_delay);
+ ResetFrameCounter(&overload_delay);
+}
+
+static void FadeOutLaser(void)
+{
+ int i;
+
+ for (i = 15; i >= 0; i--)
+ {
+ SetLaserColor(0x11 * i);
+
+ DrawLaser(0, DL_LASER_ENABLED);
+
+ BackToFront();
+ Delay_WithScreenUpdates(50);
+ }
+
+ DrawLaser(0, DL_LASER_DISABLED);
+
+ StopSound_MM(SND_MM_GAME_HEALTH_CHARGING);
+}
+
+static void GameOver_MM(int game_over_cause)
+{
+ // do not handle game over if request dialog is already active
+ if (game.request_active)
+ return;
+
+ game_mm.game_over = TRUE;
+ game_mm.game_over_cause = game_over_cause;
+
+ if (setup.ask_on_game_over)
+ game.restart_game_message = (game_over_cause == GAME_OVER_BOMB ?
+ "Bomb killed Mc Duffin! Play it again?" :
+ game_over_cause == GAME_OVER_NO_ENERGY ?
+ "Out of magic energy! Play it again?" :
+ game_over_cause == GAME_OVER_OVERLOADED ?
+ "Magic spell hit Mc Duffin! Play it again?" :
+ NULL);
+
+ SetTileCursorActive(FALSE);
}
void AddLaserEdge(int lx, int ly)
void AddDamagedField(int ex, int ey)
{
+ // prevent adding the same field position again
+ if (laser.num_damages > 0 &&
+ laser.damage[laser.num_damages - 1].x == ex &&
+ laser.damage[laser.num_damages - 1].y == ey &&
+ laser.damage[laser.num_damages - 1].edge == laser.num_edges)
+ return;
+
laser.damage[laser.num_damages].is_mirror = FALSE;
laser.damage[laser.num_damages].angle = laser.current_angle;
laser.damage[laser.num_damages].edge = laser.num_edges;
static int getMaskFromElement(int element)
{
if (IS_GRID(element))
- return IMG_MM_MASK_GRID_1 + get_element_phase(element);
+ return MM_MASK_GRID_1 + get_element_phase(element);
else if (IS_MCDUFFIN(element))
- return IMG_MM_MASK_MCDUFFIN_RIGHT + get_element_phase(element);
+ return MM_MASK_MCDUFFIN_RIGHT + get_element_phase(element);
else if (IS_RECTANGLE(element) || IS_DF_GRID(element))
- return IMG_MM_MASK_RECTANGLE;
+ return MM_MASK_RECTANGLE;
else
- return IMG_MM_MASK_CIRCLE;
+ return MM_MASK_CIRCLE;
}
static int ScanPixel(void)
}
else
{
- int pos = getMaskFromElement(element) - IMG_MM_MASK_MCDUFFIN_RIGHT;
+ int pos = getMaskFromElement(element);
pixel = (mm_masks[pos][dy / 2][dx / 2] == 'X' ? 1 : 0);
}
return hit_mask;
}
+static void DeactivateLaserTargetElement(void)
+{
+ if (laser.dest_element_last == EL_BOMB_ACTIVE ||
+ laser.dest_element_last == EL_MINE_ACTIVE ||
+ laser.dest_element_last == EL_GRAY_BALL_ACTIVE ||
+ laser.dest_element_last == EL_GRAY_BALL_OPENING)
+ {
+ int x = laser.dest_element_last_x;
+ int y = laser.dest_element_last_y;
+ int element = laser.dest_element_last;
+
+ if (Tile[x][y] == element)
+ Tile[x][y] = (element == EL_BOMB_ACTIVE ? EL_BOMB :
+ element == EL_MINE_ACTIVE ? EL_MINE : EL_GRAY_BALL);
+
+ if (Tile[x][y] == EL_GRAY_BALL)
+ MovDelay[x][y] = 0;
+
+ laser.dest_element_last = EL_EMPTY;
+ laser.dest_element_last_x = -1;
+ laser.dest_element_last_y = -1;
+ }
+}
+
void ScanLaser(void)
{
- int element;
+ int element = EL_EMPTY;
+ int last_element = EL_EMPTY;
int end = 0, rf = laser.num_edges;
// do not scan laser again after the game was lost for whatever reason
if (game_mm.game_over)
return;
+ // do not scan laser if fuse is off
+ if (laser.fuse_off)
+ return;
+
+ DeactivateLaserTargetElement();
+
laser.overloaded = FALSE;
laser.stops_inside_element = FALSE;
hit_mask, LX, LY, ELX, ELY);
#endif
+ last_element = element;
+
element = Tile[ELX][ELY];
laser.dest_element = element;
ELX, ELY, element);
#endif
+ // special case: leaving fixed MM steel grid (upwards) with non-90° angle
+ if (element == EL_EMPTY &&
+ IS_GRID_STEEL(last_element) &&
+ laser.current_angle % 4) // angle is not 90°
+ element = last_element;
+
if (element == EL_EMPTY)
{
- if (!HitOnlyAnEdge(element, hit_mask))
+ if (!HitOnlyAnEdge(hit_mask))
break;
}
else if (element == EL_FUSE_ON)
if (rf)
DrawLaser(rf - 1, DL_LASER_ENABLED);
rf = laser.num_edges;
+
+ if (!IS_DF_WALL_STEEL(element))
+ {
+ // only used for scanning DF steel walls; reset for all other elements
+ last_LX = 0;
+ last_LY = 0;
+ last_hit_mask = 0;
+ }
}
#if 0
#endif
}
+static void ScanLaser_FromLastMirror(void)
+{
+ int start_pos = (laser.num_damages > 0 ? laser.num_damages - 1 : 0);
+ int i;
+
+ for (i = start_pos; i >= 0; i--)
+ if (laser.damage[i].is_mirror)
+ break;
+
+ int start_edge = (i > 0 ? laser.damage[i].edge - 1 : 0);
+
+ DrawLaser(start_edge, DL_LASER_DISABLED);
+
+ ScanLaser();
+}
+
static void DrawLaserExt(int start_edge, int num_edges, int mode)
{
int element;
void DrawLaser(int start_edge, int mode)
{
+ // do not draw laser if fuse is off
+ if (laser.fuse_off && mode == DL_LASER_ENABLED)
+ return;
+
+ if (mode == DL_LASER_DISABLED)
+ DeactivateLaserTargetElement();
+
if (laser.num_edges - start_edge < 0)
{
Warn("DrawLaser: laser.num_edges - start_edge < 0");
boolean HitElement(int element, int hit_mask)
{
- if (HitOnlyAnEdge(element, hit_mask))
+ if (HitOnlyAnEdge(hit_mask))
return FALSE;
if (IS_MOVING(ELX, ELY) || IS_BLOCKED(ELX, ELY))
// this is more precise: check if laser would go through the center
if ((ELX * TILEX + 14 - LX) * YS != (ELY * TILEY + 14 - LY) * XS)
{
+ int skip_count = 0;
+
+ // prevent cutting through laser emitter with laser beam
+ if (IS_LASER(element))
+ return TRUE;
+
// skip the whole element before continuing the scan
do
{
LX += XS;
LY += YS;
+
+ skip_count++;
}
while (ELX == LX/TILEX && ELY == LY/TILEY && LX > 0 && LY > 0);
- if (LX/TILEX > ELX || LY/TILEY > ELY)
+ if ((LX/TILEX > ELX || LY/TILEY > ELY) && skip_count > 1)
{
/* skipping scan positions to the right and down skips one scan
position too much, because this is only the top left scan position
of totally four scan positions (plus one to the right, one to the
bottom and one to the bottom right) */
+ /* ... but only roll back scan position if more than one step done */
LX -= XS;
LY -= YS;
LX += step_size * XS;
LY += step_size * YS;
-#if 0
// draw sparkles on mirror
- if ((IS_MIRROR(element) || IS_MIRROR_FIXED(element)) &&
+ if ((IS_MIRROR(element) ||
+ IS_MIRROR_FIXED(element) ||
+ element == EL_PRISM) &&
current_angle != laser.current_angle)
{
- MoveSprite(vp, &Pfeil[2], 4 + 16 * ELX, 5 + 16 * ELY + 1);
+ MovDelay[ELX][ELY] = 11; // start animation
}
-#endif
if ((!IS_POLAR(element) && !IS_POLAR_CROSS(element)) &&
current_angle != laser.current_angle)
return TRUE;
}
- if (element == EL_BOMB || element == EL_MINE)
+ if (element == EL_BOMB || element == EL_MINE || element == EL_GRAY_BALL)
{
PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
+ Tile[ELX][ELY] = (element == EL_BOMB ? EL_BOMB_ACTIVE :
+ element == EL_MINE ? EL_MINE_ACTIVE :
+ EL_GRAY_BALL_ACTIVE);
+
+ laser.dest_element_last = Tile[ELX][ELY];
+ laser.dest_element_last_x = ELX;
+ laser.dest_element_last_y = ELY;
+
if (element == EL_MINE)
laser.overloaded = TRUE;
}
element == EL_KEY ||
element == EL_LIGHTBALL ||
element == EL_PACMAN ||
- IS_PACMAN(element))
+ IS_PACMAN(element) ||
+ IS_ENVELOPE(element))
{
- if (!IS_PACMAN(element))
+ if (!IS_PACMAN(element) &&
+ !IS_ENVELOPE(element))
Bang_MM(ELX, ELY);
if (element == EL_PACMAN)
{
DeletePacMan(ELX, ELY);
}
+ else if (IS_ENVELOPE(element))
+ {
+ Tile[ELX][ELY] = EL_ENVELOPE_1_OPENING + ENVELOPE_NR(Tile[ELX][ELY]);
+ }
RaiseScoreElement_MM(element);
return TRUE;
}
-boolean HitOnlyAnEdge(int element, int hit_mask)
+boolean HitOnlyAnEdge(int hit_mask)
{
// check if the laser hit only the edge of an element and, if so, go on
boolean HitPolarizer(int element, int hit_mask)
{
- if (HitOnlyAnEdge(element, hit_mask))
+ if (HitOnlyAnEdge(hit_mask))
return FALSE;
if (IS_DF_GRID(element))
boolean HitLaserSource(int element, int hit_mask)
{
- if (HitOnlyAnEdge(element, hit_mask))
+ if (HitOnlyAnEdge(hit_mask))
return FALSE;
PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
boolean HitLaserDestination(int element, int hit_mask)
{
- if (HitOnlyAnEdge(element, hit_mask))
+ if (HitOnlyAnEdge(hit_mask))
return FALSE;
if (element != EL_EXIT_OPEN &&
}
}
- if (!HitOnlyAnEdge(element, hit_mask))
+ if (!HitOnlyAnEdge(hit_mask))
{
laser.overloaded = TRUE;
boolean HitAbsorbingWalls(int element, int hit_mask)
{
- if (HitOnlyAnEdge(element, hit_mask))
+ if (HitOnlyAnEdge(hit_mask))
return FALSE;
if (ABS(XS) == 4 &&
}
}
-static void OpenSurpriseBall(int x, int y)
+static void OpenGrayBall(int x, int y)
{
int delay = 2;
if (!MovDelay[x][y]) // next animation frame
+ {
+ if (IS_WALL(Store[x][y]))
+ {
+ DrawWalls_MM(x, y, Store[x][y]);
+
+ // copy wall tile to spare bitmap for "melting" animation
+ BlitBitmap(drawto, bitmap_db_field, cSX + x * TILEX, cSY + y * TILEY,
+ TILEX, TILEY, x * TILEX, y * TILEY);
+
+ DrawElement_MM(x, y, EL_GRAY_BALL);
+ }
+
MovDelay[x][y] = 50 * delay;
+ }
if (MovDelay[x][y]) // wait some time before next frame
{
if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(x, y))
{
Bitmap *bitmap;
- int graphic = el2gfx(Store[x][y]);
int gx, gy;
int dx = RND(26), dy = RND(26);
- getGraphicSource(graphic, 0, &bitmap, &gx, &gy);
+ if (IS_WALL(Store[x][y]))
+ {
+ // copy wall tile from spare bitmap for "melting" animation
+ bitmap = bitmap_db_field;
+ gx = x * TILEX;
+ gy = y * TILEY;
+ }
+ else
+ {
+ int graphic = el2gfx(Store[x][y]);
+
+ getGraphicSource(graphic, 0, &bitmap, &gx, &gy);
+ }
BlitBitmap(bitmap, drawto, gx + dx, gy + dy, 6, 6,
cSX + x * TILEX + dx, cSY + y * TILEY + dy);
+ laser.redraw = TRUE;
+
MarkTileDirty(x, y);
}
if (!MovDelay[x][y])
{
Tile[x][y] = Store[x][y];
- Store[x][y] = 0;
+ Store[x][y] = Store2[x][y] = 0;
+ MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
+
+ InitField(x, y, FALSE);
+ DrawField_MM(x, y);
+
+ ScanLaser_FromLastMirror();
+ }
+ }
+}
+
+static void OpenEnvelope(int x, int y)
+{
+ int num_frames = 8; // seven frames plus final empty space
+
+ if (!MovDelay[x][y]) // next animation frame
+ MovDelay[x][y] = num_frames;
+
+ if (MovDelay[x][y]) // wait some time before next frame
+ {
+ int nr = ENVELOPE_OPENING_NR(Tile[x][y]);
+
+ MovDelay[x][y]--;
+
+ if (MovDelay[x][y] > 0 && IN_SCR_FIELD(x, y))
+ {
+ int graphic = el_act2gfx(EL_ENVELOPE_1 + nr, MM_ACTION_COLLECTING);
+ int frame = num_frames - MovDelay[x][y] - 1;
+
+ DrawGraphicAnimation_MM(x, y, graphic, frame);
+
+ laser.redraw = TRUE;
+ }
+
+ if (MovDelay[x][y] == 0)
+ {
+ Tile[x][y] = EL_EMPTY;
+
DrawField_MM(x, y);
ScanLaser();
+
+ ShowEnvelope_MM(nr);
}
}
}
if (!MovDelay[x][y])
{
- int i;
-
Tile[x][y] = real_element & (wall_mask ^ 0xFF);
Store[x][y] = Store2[x][y] = 0;
if (Tile[x][y] == EL_WALL_ICE)
Tile[x][y] = EL_EMPTY;
- for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i >= 0; i--)
- if (laser.damage[i].is_mirror)
- break;
-
- if (i > 0)
- DrawLaser(laser.damage[i].edge - 1, DL_LASER_DISABLED);
- else
- DrawLaser(0, DL_LASER_DISABLED);
-
- ScanLaser();
+ ScanLaser_FromLastMirror();
}
else if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(x, y))
{
}
}
+static void DrawFieldAnimated_MM(int x, int y)
+{
+ DrawField_MM(x, y);
+
+ laser.redraw = TRUE;
+}
+
+static void DrawFieldAnimatedIfNeeded_MM(int x, int y)
+{
+ int element = Tile[x][y];
+ int graphic = el2gfx(element);
+
+ if (!getGraphicInfo_NewFrame(x, y, graphic))
+ return;
+
+ DrawField_MM(x, y);
+
+ laser.redraw = TRUE;
+}
+
+static void DrawFieldTwinkle(int x, int y)
+{
+ if (MovDelay[x][y] != 0) // wait some time before next frame
+ {
+ MovDelay[x][y]--;
+
+ DrawField_MM(x, y);
+
+ if (MovDelay[x][y] != 0)
+ {
+ int graphic = IMG_TWINKLE_WHITE;
+ int frame = getGraphicAnimationFrame(graphic, 10 - MovDelay[x][y]);
+
+ DrawGraphicThruMask_MM(SCREENX(x), SCREENY(y), graphic, frame);
+ }
+
+ laser.redraw = TRUE;
+ }
+}
+
static void Explode_MM(int x, int y, int phase, int mode)
{
int num_phase = 9, delay = 2;
Tile[x][y] = center_element;
}
- if (center_element == EL_BOMB || IS_MCDUFFIN(center_element))
- Store[x][y] = center_element;
- else
- Store[x][y] = EL_EMPTY;
-
+ Store[x][y] = center_element;
Store2[x][y] = mode;
+
Tile[x][y] = EL_EXPLODING_OPAQUE;
+
+ GfxElement[x][y] = (center_element == EL_BOMB_ACTIVE ? EL_BOMB :
+ IS_MCDUFFIN(center_element) ? EL_MCDUFFIN :
+ center_element);
+
MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
- Frame[x][y] = 1;
+
+ ExplodePhase[x][y] = 1;
return;
}
- Frame[x][y] = (phase < last_phase ? phase + 1 : 0);
+ if (phase == 1)
+ GfxFrame[x][y] = 0; // restart explosion animation
+
+ ExplodePhase[x][y] = (phase < last_phase ? phase + 1 : 0);
if (phase == half_phase)
{
if (phase == last_phase)
{
- if (Store[x][y] == EL_BOMB)
+ if (Store[x][y] == EL_BOMB_ACTIVE)
{
DrawLaser(0, DL_LASER_DISABLED);
InitLaser();
Bang_MM(laser.start_edge.x, laser.start_edge.y);
- Store[x][y] = EL_EMPTY;
-
- game_mm.game_over = TRUE;
- game_mm.game_over_cause = GAME_OVER_BOMB;
- SetTileCursorActive(FALSE);
+ GameOver_MM(GAME_OVER_DELAYED);
laser.overloaded = FALSE;
}
else if (IS_MCDUFFIN(Store[x][y]))
{
- Store[x][y] = EL_EMPTY;
-
- game.restart_game_message = "Bomb killed Mc Duffin! Play it again?";
+ GameOver_MM(GAME_OVER_BOMB);
}
- Tile[x][y] = Store[x][y];
+ Tile[x][y] = EL_EMPTY;
+
Store[x][y] = Store2[x][y] = 0;
MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
}
else if (!(phase % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
{
- int graphic = IMG_MM_DEFAULT_EXPLODING;
- int graphic_phase = (phase / delay - 1);
- Bitmap *bitmap;
- int src_x, src_y;
+ int graphic = el_act2gfx(GfxElement[x][y], MM_ACTION_EXPLODING);
+ int frame = getGraphicAnimationFrameXY(graphic, x, y);
- if (Store2[x][y] == EX_KETTLE)
- {
- if (graphic_phase < 3)
- {
- graphic = IMG_MM_KETTLE_EXPLODING;
- }
- else if (graphic_phase < 5)
- {
- graphic_phase += 3;
- }
- else
- {
- graphic = IMG_EMPTY;
- graphic_phase = 0;
- }
- }
- else if (Store2[x][y] == EX_SHORT)
- {
- if (graphic_phase < 4)
- {
- graphic_phase += 4;
- }
- else
- {
- graphic = IMG_EMPTY;
- graphic_phase = 0;
- }
- }
-
- getGraphicSource(graphic, graphic_phase, &bitmap, &src_x, &src_y);
-
- BlitBitmap(bitmap, drawto_field, src_x, src_y, TILEX, TILEY,
- cFX + x * TILEX, cFY + y * TILEY);
+ DrawGraphicAnimation_MM(x, y, graphic, frame);
MarkTileDirty(x, y);
}
static void Bang_MM(int x, int y)
{
int element = Tile[x][y];
- int mode = EX_NORMAL;
-
-#if 0
- DrawLaser(0, DL_LASER_ENABLED);
-#endif
-
- switch (element)
- {
- case EL_KETTLE:
- mode = EX_KETTLE;
- break;
-
- case EL_GATE_STONE:
- case EL_GATE_WOOD:
- mode = EX_SHORT;
- break;
-
- default:
- mode = EX_NORMAL;
- break;
- }
if (IS_PACMAN(element))
PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
- else if (element == EL_BOMB || IS_MCDUFFIN(element))
+ else if (element == EL_BOMB_ACTIVE || IS_MCDUFFIN(element))
PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
else if (element == EL_KEY)
PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
else
PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
- Explode_MM(x, y, EX_PHASE_START, mode);
+ Explode_MM(x, y, EX_PHASE_START, EX_TYPE_NORMAL);
}
void TurnRound(int x, int y)
boolean ClickElement(int x, int y, int button)
{
- static unsigned int click_delay = 0;
- static int click_delay_value = CLICK_DELAY;
+ static DelayCounter click_delay = { CLICK_DELAY };
static boolean new_button = TRUE;
boolean element_clicked = FALSE;
int element;
if (button == -1)
{
// initialize static variables
- click_delay = 0;
- click_delay_value = CLICK_DELAY;
+ click_delay.count = 0;
+ click_delay.value = CLICK_DELAY;
new_button = TRUE;
return FALSE;
if (button == MB_RELEASED)
{
new_button = TRUE;
- click_delay_value = CLICK_DELAY;
+ click_delay.value = CLICK_DELAY;
// release eventually hold auto-rotating mirror
RotateMirror(x, y, MB_RELEASED);
return FALSE;
}
- if (!FrameReached(&click_delay, click_delay_value) && !new_button)
+ if (!FrameReached(&click_delay) && !new_button)
return FALSE;
if (button == MB_MIDDLEBUTTON) // middle button has no function
element_clicked = TRUE;
}
+ else if (IS_ENVELOPE(element))
+ {
+ Tile[x][y] = EL_ENVELOPE_1_OPENING + ENVELOPE_NR(element);
+
+ element_clicked = TRUE;
+ }
- click_delay_value = (new_button ? CLICK_DELAY_FIRST : CLICK_DELAY);
+ click_delay.value = (new_button ? CLICK_DELAY_FIRST : CLICK_DELAY);
new_button = FALSE;
return element_clicked;
IS_POLAR(Tile[x][y]) ||
IS_POLAR_CROSS(Tile[x][y])) && x == ELX && y == ELY)
{
- check = 0;
-
if (IS_BEAMER(Tile[x][y]))
{
#if 0
LX, LY, laser.beamer_edge, laser.beamer[1].num);
#endif
- laser.num_edges--;
+ if (check == 1)
+ laser.num_edges--;
}
ScanLaser();
+
+ check = 0;
}
if (check == 2)
{
int x, y;
- if (!FrameReached(&rotate_delay, AUTO_ROTATE_DELAY))
+ if (!FrameReached(&rotate_delay))
return;
for (x = 0; x < lev_fieldx; x++)
}
}
-void ColorCycling(void)
-{
- static int CC, Cc = 0;
-
- static int color, old = 0xF00, new = 0x010, mult = 1;
- static unsigned short red, green, blue;
-
- if (color_status == STATIC_COLORS)
- return;
-
- CC = FrameCounter;
-
- if (CC < Cc || CC > Cc + 2)
- {
- Cc = CC;
-
- color = old + new * mult;
- if (mult > 0)
- mult++;
- else
- mult--;
-
- if (ABS(mult) == 16)
- {
- mult =- mult / 16;
- old = color;
- new = new << 4;
-
- if (new > 0x100)
- new = 0x001;
- }
-
- red = 0x0e00 * ((color & 0xF00) >> 8);
- green = 0x0e00 * ((color & 0x0F0) >> 4);
- blue = 0x0e00 * ((color & 0x00F));
- SetRGB(pen_magicolor[0], red, green, blue);
-
- red = 0x1111 * ((color & 0xF00) >> 8);
- green = 0x1111 * ((color & 0x0F0) >> 4);
- blue = 0x1111 * ((color & 0x00F));
- SetRGB(pen_magicolor[1], red, green, blue);
- }
-}
-
-static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
+static void GameActions_MM_Ext(void)
{
int element;
int x, y, i;
else if (IS_MOVING(x, y))
ContinueMoving_MM(x, y);
else if (IS_EXPLODING(element))
- Explode_MM(x, y, Frame[x][y], EX_NORMAL);
+ Explode_MM(x, y, ExplodePhase[x][y], EX_TYPE_NORMAL);
else if (element == EL_EXIT_OPENING)
OpenExit(x, y);
else if (element == EL_GRAY_BALL_OPENING)
- OpenSurpriseBall(x, y);
+ OpenGrayBall(x, y);
+ else if (IS_ENVELOPE_OPENING(element))
+ OpenEnvelope(x, y);
else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_ICE)
MeltIce(x, y);
else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_AMOEBA)
GrowAmoeba(x, y);
+ else if (IS_MIRROR(element) ||
+ IS_MIRROR_FIXED(element) ||
+ element == EL_PRISM)
+ DrawFieldTwinkle(x, y);
+ else if (element == EL_GRAY_BALL_ACTIVE ||
+ element == EL_BOMB_ACTIVE ||
+ element == EL_MINE_ACTIVE)
+ DrawFieldAnimated_MM(x, y);
+ else if (!IS_BLOCKED(x, y))
+ DrawFieldAnimatedIfNeeded_MM(x, y);
}
AutoRotateMirrors();
CT = FrameCounter;
- if (game_mm.num_pacman && FrameReached(&pacman_delay, PACMAN_MOVE_DELAY))
+ if (game_mm.num_pacman && FrameReached(&pacman_delay))
{
MovePacMen();
}
}
- if (FrameReached(&energy_delay, ENERGY_DELAY))
- {
- if (game_mm.energy_left > 0)
- {
- game_mm.energy_left--;
-
- redraw_mask |= REDRAW_DOOR_1;
- }
- else if (game.time_limit && !game_mm.game_over)
- {
- int i;
-
- for (i = 15; i >= 0; i--)
- {
-#if 0
- SetRGB(pen_ray, 0x0000, 0x0000, i * color_scale);
-#endif
- pen_ray = GetPixelFromRGB(window,
- native_mm_level.laser_red * 0x11 * i,
- native_mm_level.laser_green * 0x11 * i,
- native_mm_level.laser_blue * 0x11 * i);
-
- DrawLaser(0, DL_LASER_ENABLED);
- BackToFront();
- Delay_WithScreenUpdates(50);
- }
+ // skip all following game actions if game is over
+ if (game_mm.game_over)
+ return;
- StopSound_MM(SND_MM_GAME_HEALTH_CHARGING);
-#if 0
- FadeMusic();
-#endif
+ if (game_mm.energy_left == 0 && !game.no_level_time_limit && game.time_limit)
+ {
+ FadeOutLaser();
- DrawLaser(0, DL_LASER_DISABLED);
- game_mm.game_over = TRUE;
- game_mm.game_over_cause = GAME_OVER_NO_ENERGY;
+ GameOver_MM(GAME_OVER_NO_ENERGY);
- SetTileCursorActive(FALSE);
+ return;
+ }
- game.restart_game_message = "Out of magic energy! Play it again?";
+ if (FrameReached(&energy_delay))
+ {
+ if (game_mm.energy_left > 0)
+ game_mm.energy_left--;
- return;
- }
+ // when out of energy, wait another frame to play "out of time" sound
}
element = laser.dest_element;
if (!laser.overloaded && laser.overload_value == 0 &&
element != EL_BOMB &&
+ element != EL_BOMB_ACTIVE &&
element != EL_MINE &&
- element != EL_BALL_GRAY &&
+ element != EL_MINE_ACTIVE &&
+ element != EL_GRAY_BALL &&
+ element != EL_GRAY_BALL_ACTIVE &&
element != EL_BLOCK_STONE &&
element != EL_BLOCK_WOOD &&
element != EL_FUSE_ON &&
!IS_WALL_AMOEBA(element))
return;
+ overload_delay.value = HEALTH_DELAY(laser.overloaded);
+
if (((laser.overloaded && laser.overload_value < MAX_LASER_OVERLOAD) ||
(!laser.overloaded && laser.overload_value > 0)) &&
- FrameReached(&overload_delay, HEALTH_DELAY(laser.overloaded)))
+ FrameReached(&overload_delay))
{
if (laser.overloaded)
laser.overload_value++;
if (laser.overload_value < MAX_LASER_OVERLOAD - 8)
{
- int color_up = 0xFF * laser.overload_value / MAX_LASER_OVERLOAD;
- int color_down = 0xFF - color_up;
-
-#if 0
- SetRGB(pen_ray, (laser.overload_value / 6) * color_scale, 0x0000,
- (15 - (laser.overload_value / 6)) * color_scale);
-#endif
- pen_ray =
- GetPixelFromRGB(window,
- (native_mm_level.laser_red ? 0xFF : color_up),
- (native_mm_level.laser_green ? color_down : 0x00),
- (native_mm_level.laser_blue ? color_down : 0x00));
+ SetLaserColor(0xFF);
DrawLaser(0, DL_LASER_ENABLED);
}
else
PlaySound_MM(SND_MM_GAME_HEALTH_CHARGING);
- if (laser.overloaded)
- {
-#if 0
- BlitBitmap(pix[PIX_DOOR], drawto,
- DOOR_GFX_PAGEX4 + XX_OVERLOAD,
- DOOR_GFX_PAGEY1 + YY_OVERLOAD + OVERLOAD_YSIZE
- - laser.overload_value,
- 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;
- }
-
if (laser.overload_value == MAX_LASER_OVERLOAD)
{
- int i;
-
UpdateAndDisplayGameControlValues();
- for (i = 15; i >= 0; i--)
- {
-#if 0
- SetRGB(pen_ray, i * color_scale, 0x0000, 0x0000);
-#endif
-
- pen_ray = GetPixelFromRGB(window, 0x11 * i, 0x00, 0x00);
-
- DrawLaser(0, DL_LASER_ENABLED);
- BackToFront();
- Delay_WithScreenUpdates(50);
- }
-
- DrawLaser(0, DL_LASER_DISABLED);
+ FadeOutLaser();
- game_mm.game_over = TRUE;
- game_mm.game_over_cause = GAME_OVER_OVERLOADED;
-
- SetTileCursorActive(FALSE);
-
- game.restart_game_message = "Magic spell hit Mc Duffin! Play it again?";
+ GameOver_MM(GAME_OVER_OVERLOADED);
return;
}
DrawGraphic_MM(ELX, ELY, IMG_MM_FUSE);
}
- if (element == EL_BALL_GRAY && CT > native_mm_level.time_ball)
+ if (element == EL_GRAY_BALL && CT > native_mm_level.time_ball)
{
- static int new_elements[] =
+ if (!Store2[ELX][ELY]) // check if content element not yet determined
{
- EL_MIRROR_START,
- EL_MIRROR_FIXED_START,
- EL_POLAR_START,
- EL_POLAR_CROSS_START,
- EL_PACMAN_START,
- EL_KETTLE,
- EL_BOMB,
- EL_PRISM
- };
- int num_new_elements = sizeof(new_elements) / sizeof(int);
- int new_element = new_elements[RND(num_new_elements)];
-
- Store[ELX][ELY] = new_element + RND(get_num_elements(new_element));
- Tile[ELX][ELY] = EL_GRAY_BALL_OPENING;
+ int last_anim_random_frame = gfx.anim_random_frame;
+ int element_pos;
- // !!! CHECK AGAIN: Laser on Polarizer !!!
- ScanLaser();
+ if (native_mm_level.ball_choice_mode == ANIM_RANDOM)
+ gfx.anim_random_frame = RND(native_mm_level.num_ball_contents);
- return;
+ element_pos = getAnimationFrame(native_mm_level.num_ball_contents, 1,
+ native_mm_level.ball_choice_mode, 0,
+ game_mm.ball_choice_pos);
-#if 0
- int graphic;
+ if (native_mm_level.ball_choice_mode == ANIM_RANDOM)
+ gfx.anim_random_frame = last_anim_random_frame;
- switch (RND(5))
- {
- case 0:
- element = EL_MIRROR_START + RND(16);
- break;
- case 1:
- {
- int rnd = RND(3);
+ game_mm.ball_choice_pos++;
- element = (rnd == 0 ? EL_KETTLE : rnd == 1 ? EL_BOMB : EL_PRISM);
- }
- break;
- default:
- {
- int rnd = RND(3);
-
- element = (rnd == 0 ? EL_FUSE_ON :
- rnd >= 1 && rnd <= 4 ? EL_PACMAN_RIGHT + rnd - 1 :
- rnd >= 5 && rnd <= 20 ? EL_POLAR_START + rnd - 5 :
- rnd >= 21 && rnd <= 24 ? EL_POLAR_CROSS_START + rnd - 21 :
- EL_MIRROR_FIXED_START + rnd - 25);
- }
- break;
- }
-
- graphic = el2gfx(element);
-
- for (i = 0; i < 50; i++)
- {
- int x = RND(26);
- int y = RND(26);
+ int new_element = native_mm_level.ball_content[element_pos];
+ int new_element_unmapped = unmap_element(new_element);
-#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();
-
- DrawLaser(0, DL_LASER_ENABLED);
+ if (IS_WALL(new_element_unmapped))
+ {
+ // always use completely filled wall element
+ new_element = new_element_unmapped | 0x000f;
+ }
+ else if (native_mm_level.rotate_ball_content &&
+ get_num_elements(new_element) > 1)
+ {
+ // randomly rotate newly created game element
+ new_element = get_rotated_element(new_element, RND(16));
+ }
- Delay_WithScreenUpdates(50);
+ Store[ELX][ELY] = new_element;
+ Store2[ELX][ELY] = TRUE;
}
- Tile[ELX][ELY] = element;
- DrawField_MM(ELX, ELY);
-
-#if 0
- Debug("game:mm:GameActions_MM_Ext", "NEW ELEMENT: (%d, %d)", ELX, ELY);
-#endif
-
- // above stuff: GRAY BALL -> PRISM !!!
-/*
- LX = ELX * TILEX + 14;
- LY = ELY * TILEY + 14;
- if (laser.current_angle == (laser.current_angle >> 1) << 1)
- OK = 8;
- else
- OK = 4;
- LX -= OK * XS;
- LY -= OK * YS;
-
- laser.num_edges -= 2;
- laser.num_damages--;
-*/
-
-#if 0
- for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i>=0; i--)
- if (laser.damage[i].is_mirror)
- break;
-
- if (i > 0)
- DrawLaser(laser.damage[i].edge - 1, DL_LASER_DISABLED);
- else
- DrawLaser(0, DL_LASER_DISABLED);
-#else
- DrawLaser(0, DL_LASER_DISABLED);
-#endif
+ Tile[ELX][ELY] = EL_GRAY_BALL_OPENING;
- ScanLaser();
-#endif
+ laser.dest_element_last = Tile[ELX][ELY];
return;
}
{
PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_SHRINKING);
- {
- Tile[ELX][ELY] = Tile[ELX][ELY] - EL_WALL_ICE + EL_WALL_CHANGING;
- Store[ELX][ELY] = EL_WALL_ICE;
- Store2[ELX][ELY] = laser.wall_mask;
-
- laser.dest_element = Tile[ELX][ELY];
+ Tile[ELX][ELY] = Tile[ELX][ELY] - EL_WALL_ICE + EL_WALL_CHANGING;
+ Store[ELX][ELY] = EL_WALL_ICE;
+ Store2[ELX][ELY] = laser.wall_mask;
- return;
- }
-
- for (i = 0; i < 5; i++)
- {
- int phase = i + 1;
-
- if (i == 4)
- {
- Tile[ELX][ELY] &= (laser.wall_mask ^ 0xFF);
- phase = 0;
- }
-
- DrawWallsAnimation_MM(ELX, ELY, Tile[ELX][ELY], phase, laser.wall_mask);
- BackToFront();
- Delay_WithScreenUpdates(100);
- }
-
- if (Tile[ELX][ELY] == EL_WALL_ICE)
- Tile[ELX][ELY] = EL_EMPTY;
-
-/*
- laser.num_edges--;
- LX = laser.edge[laser.num_edges].x - cSX2;
- LY = laser.edge[laser.num_edges].y - cSY2;
-*/
-
- for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i >= 0; i--)
- if (laser.damage[i].is_mirror)
- break;
-
- if (i > 0)
- DrawLaser(laser.damage[i].edge - 1, DL_LASER_DISABLED);
- else
- DrawLaser(0, DL_LASER_DISABLED);
-
- ScanLaser();
+ laser.dest_element = Tile[ELX][ELY];
return;
}
if (IS_WALL_AMOEBA(element) && CT > 60)
{
- int k1, k2, k3, dx, dy, de, dm;
+ int k1, k2, k3;
int element2 = Tile[ELX][ELY];
if (element2 != EL_EMPTY && !IS_WALL_AMOEBA(element))
Tile[ELX][ELY] = element | laser.wall_mask;
- dx = ELX;
- dy = ELY;
- de = Tile[ELX][ELY];
- dm = laser.wall_mask;
-
-#if 1
- {
- int x = ELX, y = ELY;
- int wall_mask = laser.wall_mask;
-
- ScanLaser();
- DrawLaser(0, DL_LASER_ENABLED);
-
- PlayLevelSound_MM(dx, dy, element, MM_ACTION_GROWING);
-
- Tile[x][y] = Tile[x][y] - EL_WALL_AMOEBA + EL_WALL_CHANGING;
- Store[x][y] = EL_WALL_AMOEBA;
- Store2[x][y] = wall_mask;
-
- return;
- }
-#endif
+ int x = ELX, y = ELY;
+ int wall_mask = laser.wall_mask;
- DrawWallsAnimation_MM(dx, dy, de, 4, dm);
ScanLaser();
DrawLaser(0, DL_LASER_ENABLED);
- PlayLevelSound_MM(dx, dy, element, MM_ACTION_GROWING);
+ PlayLevelSound_MM(x, y, element, MM_ACTION_GROWING);
- for (i = 4; i >= 0; i--)
- {
- DrawWallsAnimation_MM(dx, dy, de, i, dm);
-
- BackToFront();
- Delay_WithScreenUpdates(20);
- }
-
- DrawLaser(0, DL_LASER_ENABLED);
+ Tile[x][y] = Tile[x][y] - EL_WALL_AMOEBA + EL_WALL_CHANGING;
+ Store[x][y] = EL_WALL_AMOEBA;
+ Store2[x][y] = wall_mask;
return;
}
if (element == EL_FUEL_FULL && CT > 10)
{
- for (i = game_mm.energy_left; i <= MAX_LASER_ENERGY; i+=2)
+ int num_init_game_frames = INIT_GAME_ACTIONS_DELAY;
+ int start = num_init_game_frames * game_mm.energy_left / native_mm_level.time;
+
+ for (i = start; i <= num_init_game_frames; i++)
{
-#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
+ if (i == num_init_game_frames)
+ StopSound_MM(SND_MM_GAME_LEVELTIME_CHARGING);
+ else if (setup.sound_loops)
+ PlaySoundLoop_MM(SND_MM_GAME_LEVELTIME_CHARGING);
+ else
+ PlaySound_MM(SND_MM_GAME_LEVELTIME_CHARGING);
- redraw_mask |= REDRAW_DOOR_1;
- BackToFront();
+ game_mm.energy_left = native_mm_level.time * i / num_init_game_frames;
- Delay_WithScreenUpdates(20);
+ UpdateAndDisplayGameControlValues();
+
+ BackToFront();
}
- game_mm.energy_left = MAX_LASER_ENERGY;
- Tile[ELX][ELY] = EL_FUEL_EMPTY;
+ Tile[ELX][ELY] = laser.dest_element = EL_FUEL_EMPTY;
+
DrawField_MM(ELX, ELY);
DrawLaser(0, DL_LASER_ENABLED);
return;
}
-
- return;
}
-void GameActions_MM(struct MouseActionInfo action, boolean warp_mode)
+void GameActions_MM(struct MouseActionInfo action)
{
boolean element_clicked = ClickElement(action.lx, action.ly, action.button);
boolean button_released = (action.button == MB_RELEASED);
- GameActions_MM_Ext(action, warp_mode);
+ GameActions_MM_Ext();
CheckSingleStepMode_MM(element_clicked, button_released);
}
return element;
}
-#if 0
-static void RemoveField(int x, int y)
-{
- Tile[x][y] = EL_EMPTY;
- MovPos[x][y] = 0;
- MovDir[x][y] = 0;
- MovDelay[x][y] = 0;
-}
-#endif
-
static void RemoveMovingField_MM(int x, int y)
{
int oldx = x, oldy = y, newx = x, newy = y;
DrawLevelField_MM(newx, newy);
}
-void PlaySoundLevel(int x, int y, int sound_nr)
-{
- int sx = SCREENX(x), sy = SCREENY(y);
- int volume, stereo;
- int silence_distance = 8;
-
- if ((!setup.sound_simple && !IS_LOOP_SOUND(sound_nr)) ||
- (!setup.sound_loops && IS_LOOP_SOUND(sound_nr)))
- return;
-
- if (!IN_LEV_FIELD(x, y) ||
- sx < -silence_distance || sx >= SCR_FIELDX+silence_distance ||
- sy < -silence_distance || sy >= SCR_FIELDY+silence_distance)
- return;
-
- volume = SOUND_MAX_VOLUME;
-
-#ifndef MSDOS
- stereo = (sx - SCR_FIELDX/2) * 12;
-#else
- stereo = SOUND_MIDDLE + (2 * sx - (SCR_FIELDX - 1)) * 5;
- if (stereo > SOUND_MAX_RIGHT)
- stereo = SOUND_MAX_RIGHT;
- if (stereo < SOUND_MAX_LEFT)
- stereo = SOUND_MAX_LEFT;
-#endif
-
- if (!IN_SCR_FIELD(sx, sy))
- {
- int dx = ABS(sx - SCR_FIELDX/2) - SCR_FIELDX/2;
- int dy = ABS(sy - SCR_FIELDY/2) - SCR_FIELDY/2;
-
- volume -= volume * (dx > dy ? dx : dy) / silence_distance;
- }
-
- PlaySoundExt(sound_nr, volume, stereo, SND_CTRL_PLAY_SOUND);
-}
-
static void RaiseScore_MM(int value)
{
game_mm.score += value;
// Mirror Magic game engine snapshot handling functions
// ----------------------------------------------------------------------------
-void SaveEngineSnapshotValues_MM(ListNode **buffers)
+void SaveEngineSnapshotValues_MM(void)
{
int x, y;
engine_snapshot_mm.Hit[x][y] = Hit[x][y];
engine_snapshot_mm.Box[x][y] = Box[x][y];
engine_snapshot_mm.Angle[x][y] = Angle[x][y];
- engine_snapshot_mm.Frame[x][y] = Frame[x][y];
}
}
Hit[x][y] = engine_snapshot_mm.Hit[x][y];
Box[x][y] = engine_snapshot_mm.Box[x][y];
Angle[x][y] = engine_snapshot_mm.Angle[x][y];
- Frame[x][y] = engine_snapshot_mm.Frame[x][y];
}
}