#define DL_LASER_ENABLED 1
/* values for 'click_delay_value' in ClickElement() */
-#define CLICK_DELAY_SHORT 125
-#define CLICK_DELAY_LONG 250
-#define AUTO_ROTATE_DELAY CLICK_DELAY_SHORT
+#define CLICK_DELAY_FIRST 12 /* delay (frames) after first click */
+#define CLICK_DELAY 6 /* delay (frames) for pressed butten */
+
+#define AUTO_ROTATE_DELAY CLICK_DELAY
+#define INIT_GAME_ACTIONS_DELAY (ONE_SECOND_DELAY / GAME_FRAME_DELAY)
+#define NUM_INIT_CYCLE_STEPS 16
+#define PACMAN_MOVE_DELAY 12
+#define ENERGY_DELAY (4 * ONE_SECOND_DELAY / GAME_FRAME_DELAY)
+#define HEALTH_DEC_DELAY 3
+#define HEALTH_INC_DELAY 9
+#define HEALTH_DELAY(x) ((x) ? HEALTH_DEC_DELAY : HEALTH_INC_DELAY)
/* forward declaration for internal use */
static int MovingOrBlocked2Element_MM(int, int);
}
}
-static void InitCycleElements()
+static void InitCycleElements_RotateSingleStep()
{
- int i, j;
+ int i;
if (game_mm.num_cycle == 0) /* no elements to cycle */
return;
- for (i = 0; i < 16; i++)
+ for (i = 0; i < game_mm.num_cycle; i++)
{
- for (j = 0; j < game_mm.num_cycle; j++)
- {
- int x = game_mm.cycle[j].x;
- int y = game_mm.cycle[j].y;
- int step = SIGN(game_mm.cycle[j].steps);
- int last_element = Feld[x][y];
- int next_element = get_rotated_element(last_element, step);
-
- if (!game_mm.cycle[j].steps)
- continue;
-
- Feld[x][y] = next_element;
-
- DrawField_MM(x, y);
- game_mm.cycle[j].steps -= step;
- }
-
- BackToFront();
- ColorCycling();
+ int x = game_mm.cycle[i].x;
+ int y = game_mm.cycle[i].y;
+ int step = SIGN(game_mm.cycle[i].steps);
+ int last_element = Feld[x][y];
+ int next_element = get_rotated_element(last_element, step);
-#ifdef DEBUG
- if (setup.quick_doors)
+ if (!game_mm.cycle[i].steps)
continue;
-#endif
- Delay(AUTO_ROTATE_DELAY);
+ Feld[x][y] = next_element;
+
+ DrawField_MM(x, y);
+ game_mm.cycle[i].steps -= step;
}
}
void InitGameActions_MM()
{
+ int num_init_game_frames = INIT_GAME_ACTIONS_DELAY;
+ int cycle_steps_done = 0;
int i;
- InitCycleElements();
InitLaser();
#if 0
OpenDoor(DOOR_OPEN_ALL);
#endif
- if (setup.sound_loops)
- PlaySoundExt(SND_FUEL, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT, SND_CTRL_PLAY_LOOP);
-
- for (i = 0; i <= native_mm_level.time; i += 2)
+ for (i = 0; i <= num_init_game_frames; i++)
{
- if (!setup.sound_loops)
- PlaySoundStereo(SND_FUEL, SOUND_MAX_RIGHT);
+ 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);
- game_mm.energy_left = i;
+ game_mm.energy_left = native_mm_level.time * i / num_init_game_frames;
UpdateAndDisplayGameControlValues();
+ while (cycle_steps_done < NUM_INIT_CYCLE_STEPS * i / num_init_game_frames)
+ {
+ InitCycleElements_RotateSingleStep();
+
+ cycle_steps_done++;
+ }
+
BackToFront();
ColorCycling();
#endif
}
- game_mm.energy_left = native_mm_level.time;
-
- if (setup.sound_loops)
- StopSound(SND_FUEL);
-
#if 0
if (setup.sound_music && num_bg_loops)
PlayMusic(level_nr % num_bg_loops);
((element - EL_POLAR_START) % 2 ||
(element - EL_POLAR_START) / 2 != laser.current_angle % 8))
{
- PlaySoundStereo(SND_KINK, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
laser.num_damages--;
if (IS_POLAR_CROSS(element) &&
(element - EL_POLAR_CROSS_START) != laser.current_angle % 4)
{
- PlaySoundStereo(SND_KINK, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
laser.num_damages--;
if ((!IS_POLAR(element) && !IS_POLAR_CROSS(element)) &&
current_angle != laser.current_angle)
- PlaySoundStereo(SND_LASER, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
laser.overloaded =
(get_opposite_angle(laser.current_angle) ==
if (element == EL_BOMB || element == EL_MINE)
{
- PlaySoundStereo(SND_KINK, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
if (element == EL_MINE)
laser.overloaded = TRUE;
if (game_mm.kettles_still_needed == 0)
{
+ int exit_element = (element == EL_KETTLE ? EL_EXIT_OPEN : EL_RECEIVER);
int x, y;
static int xy[4][2] =
{
{ 0, +1 }
};
- PlaySoundStereo(SND_KLING, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, exit_element, MM_ACTION_OPENING);
for (y = 0; y < lev_fieldy; y++)
{
if (element == EL_LIGHTBULB_OFF || element == EL_LIGHTBULB_ON)
{
- PlaySoundStereo(SND_KINK, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
DrawLaser(0, DL_LASER_ENABLED);
boolean HitLaserSource(int element, int hit_mask)
{
- if (HitOnlyAnEdge(element, hit_mask))
- return FALSE;
+ if (HitOnlyAnEdge(element, hit_mask))
+ return FALSE;
+
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
- PlaySoundStereo(SND_AUTSCH, ST(ELX));
- laser.overloaded = TRUE;
+ laser.overloaded = TRUE;
- return TRUE;
+ return TRUE;
}
boolean HitLaserDestination(int element, int hit_mask)
game_mm.kettles_still_needed == 0 &&
laser.current_angle == get_opposite_angle(get_element_angle(element))))
{
- PlaySoundStereo(SND_HOLZ, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
+
return TRUE;
}
hit_mask == HIT_MASK_RIGHT ||
hit_mask == HIT_MASK_BOTTOM))
{
- PlaySoundStereo(SND_HUI, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
LX -= XS;
LY -= YS;
(hit_mask == HIT_MASK_TOPRIGHT || hit_mask == HIT_MASK_BOTTOMLEFT ?
ANG_MIRROR_135 : ANG_MIRROR_45);
- PlaySoundStereo(SND_HUI, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
AddDamagedField(ELX, ELY);
AddLaserEdge(LX, LY);
hit_mask == (HIT_MASK_ALL ^ HIT_MASK_TOPRIGHT) ?
ANG_MIRROR_135 : ANG_MIRROR_45);
- PlaySoundStereo(SND_HUI, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
/*
AddDamagedField(ELX, ELY);
element == EL_BLOCK_WOOD ||
element == EL_GATE_WOOD)
{
- PlaySoundStereo(SND_HOLZ, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
return TRUE;
}
}
if (IS_PACMAN(element))
- PlaySoundStereo(SND_QUIEK, ST(x));
+ PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
else if (element == EL_BOMB || IS_MCDUFFIN(element))
- PlaySoundStereo(SND_ROAAAR, ST(x));
+ PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
else if (element == EL_KEY)
- PlaySoundStereo(SND_KLING, ST(x));
+ PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
else
- PlaySoundStereo((mode == EX_SHORT ? SND_WHOOSH : SND_KABUMM), ST(x));
+ PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
Explode_MM(x, y, EX_PHASE_START, mode);
}
laser.redraw = TRUE;
}
-void ClickElement(int mx, int my, int button)
+void ClickElement(int x, int y, int button)
{
static unsigned int click_delay = 0;
- static int click_delay_value = CLICK_DELAY_SHORT;
+ static int click_delay_value = CLICK_DELAY;
static boolean new_button = TRUE;
int element;
- int x = (mx - SX) / TILEX, y = (my - SY) / TILEY;
/* do not rotate objects hit by the laser after the game was solved */
if (game_mm.level_solved && Hit[x][y])
if (button == MB_RELEASED)
{
new_button = TRUE;
- click_delay_value = CLICK_DELAY_SHORT;
+ click_delay_value = CLICK_DELAY;
/* release eventually hold auto-rotating mirror */
RotateMirror(x, y, MB_RELEASED);
return;
}
- if (!DelayReached(&click_delay, click_delay_value) && !new_button)
+ if (!FrameReached(&click_delay, click_delay_value) && !new_button)
return;
if (button == MB_MIDDLEBUTTON) /* middle button has no function */
return;
- if (!IN_PIX_FIELD(mx - SX, my - SY))
+ if (!IN_LEV_FIELD(x, y))
return;
if (Feld[x][y] == EL_EMPTY)
DrawLaser(0, DL_LASER_ENABLED);
}
- click_delay_value = (new_button ? CLICK_DELAY_LONG : CLICK_DELAY_SHORT);
+ click_delay_value = (new_button ? CLICK_DELAY_FIRST : CLICK_DELAY);
new_button = FALSE;
}
static unsigned int rotate_delay = 0;
int x, y;
- if (!DelayReached(&rotate_delay, AUTO_ROTATE_DELAY))
+ if (!FrameReached(&rotate_delay, AUTO_ROTATE_DELAY))
return;
for (x = 0; x < lev_fieldx; x++)
}
}
-static void GameActions_MM_Ext(byte action[MAX_PLAYERS], boolean warp_mode)
+static void GameActions_MM_Ext(struct MouseActionInfo action, 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;
int r, d;
- WaitUntilDelayReached(&action_delay, GameFrameDelay);
-
for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
Stop[x][y] = FALSE;
CT = Counter();
- if (game_mm.num_pacman && DelayReached(&pacman_delay, 250))
+ if (game_mm.num_pacman && FrameReached(&pacman_delay, PACMAN_MOVE_DELAY))
{
MovePacMen();
}
}
- if (DelayReached(&energy_delay, 4000))
+ if (FrameReached(&energy_delay, ENERGY_DELAY))
{
game_mm.energy_left--;
if (game_mm.energy_left >= 0)
Delay(50);
}
- StopSound(SND_WARNTON);
+ StopSound_MM(SND_MM_GAME_HEALTH_CHARGING);
FadeMusic();
DrawLaser(0, DL_LASER_DISABLED);
if (((laser.overloaded && laser.overload_value < MAX_LASER_OVERLOAD) ||
(!laser.overloaded && laser.overload_value > 0)) &&
- DelayReached(&overload_delay, 60 + !laser.overloaded * 120))
+ FrameReached(&overload_delay, HEALTH_DELAY(laser.overloaded)))
{
if (laser.overloaded)
laser.overload_value++;
(native_mm_level.laser_blue ? color_down : 0x00));
DrawLaser(0, DL_LASER_ENABLED);
+#if 0
BackToFront();
- }
-
- if (laser.overloaded)
- {
- if (setup.sound_loops)
- PlaySoundExt(SND_WARNTON, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
- SND_CTRL_PLAY_LOOP);
- else
- PlaySoundStereo(SND_WARNTON, SOUND_MAX_RIGHT);
+#endif
}
if (!laser.overloaded)
- StopSound(SND_WARNTON);
+ StopSound_MM(SND_MM_GAME_HEALTH_CHARGING);
+ else if (setup.sound_loops)
+ PlaySoundLoop_MM(SND_MM_GAME_HEALTH_CHARGING);
+ else
+ PlaySound_MM(SND_MM_GAME_HEALTH_CHARGING);
if (laser.overloaded)
{
if (IS_WALL_ICE(element) && CT > 1000)
{
- PlaySoundStereo(SND_SLURP, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_SHRINKING);
{
Feld[ELX][ELY] = Feld[ELX][ELY] - EL_WALL_ICE + EL_WALL_CHANGING;
ScanLaser();
DrawLaser(0, DL_LASER_ENABLED);
- PlaySoundStereo(SND_AMOEBE, ST(dx));
+ PlayLevelSound_MM(dx, dy, element, MM_ACTION_GROWING);
Feld[x][y] = Feld[x][y] - EL_WALL_AMOEBA + EL_WALL_CHANGING;
Store[x][y] = EL_WALL_AMOEBA;
ScanLaser();
DrawLaser(0, DL_LASER_ENABLED);
- PlaySoundStereo(SND_AMOEBE, ST(dx));
+ PlayLevelSound_MM(dx, dy, element, MM_ACTION_GROWING);
for (i = 4; i >= 0; i--)
{
return;
}
- PlaySoundStereo(SND_BONG, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_PUSHING);
Feld[ELX][ELY] = 0;
Feld[x][y] = element;
return;
}
-void GameActions_MM(byte action[MAX_PLAYERS], boolean warp_mode)
+void GameActions_MM(struct MouseActionInfo action, boolean warp_mode)
{
- if (!button_status)
- ClickElement(0, 0, MB_NOT_PRESSED);
+ ClickElement(action.lx, action.ly, action.button);
GameActions_MM_Ext(action, warp_mode);
}