#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 IS_MUSIC_SOUND(s) ((s) == SND_TYGER || (s) == SND_VOYAGER)
/* game button identifiers */
-#define GAME_CTRL_ID_LEFT 0
-#define GAME_CTRL_ID_MIDDLE 1
-#define GAME_CTRL_ID_RIGHT 2
+#define GAME_CTRL_ID_LEFT 0
+#define GAME_CTRL_ID_MIDDLE 1
+#define GAME_CTRL_ID_RIGHT 2
-#define NUM_GAME_BUTTONS 3
+#define NUM_GAME_BUTTONS 3
/* values for DrawLaser() */
-#define DL_LASER_DISABLED 0
-#define DL_LASER_ENABLED 1
+#define DL_LASER_DISABLED 0
+#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 INIT_GAME_ACTIONS_DELAY ONE_SECOND_DELAY
+#define NUM_INIT_CYCLE_STEPS 16
/* 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);
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] =
{
- { MV_RIGHT, MV_UP, MV_LEFT, MV_DOWN },
- { MV_LEFT, MV_DOWN, MV_RIGHT, MV_UP },
- { MV_LEFT, MV_RIGHT, MV_UP, MV_DOWN }
+ { MV_RIGHT, MV_UP, MV_LEFT, MV_DOWN },
+ { MV_LEFT, MV_DOWN, MV_RIGHT, MV_UP },
+ { MV_LEFT, MV_RIGHT, MV_UP, MV_DOWN }
};
switch(element)
}
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))
{
}
}
-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;
+ 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);
- DrawField_MM(x, y);
- game_mm.cycle[j].steps -= step;
- }
-
- BackToFront();
- ColorCycling();
-
-#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;
}
}
native_mm_level.laser_blue * 0xFF);
}
-void InitGame()
+void InitGameEngine_MM()
{
int i, x, y;
- /* set global editor control values */
- editor.draw_walls_masked = FALSE;
-
/* set global game control values */
game_mm.num_cycle = 0;
game_mm.num_pacman = 0;
game_mm.score = 0;
- game_mm.energy_left = native_mm_level.time;
+ game_mm.energy_left = 0; // later set to "native_mm_level.time"
game_mm.kettles_still_needed =
(native_mm_level.auto_count_kettles ? 0 : native_mm_level.kettles_needed);
game_mm.lights_still_needed = 0;
game_mm.game_over = FALSE;
game_mm.game_over_cause = 0;
+ game_mm.laser_overload_value = 0;
+
/* set global laser control values (must be set before "InitLaser()") */
laser.start_edge.x = 0;
laser.start_edge.y = 0;
laser.start_angle = 0;
- for (i=0; i<MAX_NUM_BEAMERS; i++)
+ for (i = 0; i < MAX_NUM_BEAMERS; i++)
laser.beamer[i][0].num = laser.beamer[i][1].num = 0;
laser.overloaded = FALSE;
CT = Ct = 0;
- for (x=0; x<lev_fieldx; x++)
+ for (x = 0; x < lev_fieldx; x++)
{
- for (y=0; y<lev_fieldy; y++)
+ for (y = 0; y < lev_fieldy; y++)
{
Feld[x][y] = Ur[x][y];
Hit[x][y] = Box[x][y] = 0;
}
}
+#if 0
CloseDoor(DOOR_CLOSE_1);
+#endif
DrawLevel_MM();
- InitCycleElements();
+}
+
+void InitGameActions_MM()
+{
+ int num_init_game_frames = INIT_GAME_ACTIONS_DELAY / GAME_FRAME_DELAY;
+ int cycle_steps_done = 0;
+ int i;
+
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,
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);
-
- for(i=0; i<=game_mm.energy_left; 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);
- 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);
+ 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++;
+ }
- redraw_mask |= REDRAW_DOOR_1;
BackToFront();
ColorCycling();
if (setup.quick_doors)
continue;
#endif
-
- Delay(20);
}
- if (setup.sound_loops)
- StopSound(SND_FUEL);
-
+#if 0
if (setup.sound_music && num_bg_loops)
PlayMusic(level_nr % num_bg_loops);
+#endif
ScanLaser();
}
if (lx < -2 || ly < -2 || lx >= SXSIZE + 2 || ly >= SYSIZE + 2)
{
Error(ERR_WARN, "AddLaserEdge: out of bounds: %d, %d", lx, ly);
+
return;
}
return ((x - last_x) * XS < 0 || (y - last_y) * YS < 0);
}
- else
- return FALSE;
+
+ return FALSE;
}
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()
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)
{
}
#endif
- for (i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
{
+ int px = LX + (i % 2) * 2;
+ int py = LY + (i / 2) * 2;
+ int dx = px % TILEX;
+ int dy = py % TILEY;
+ int lx = (px + TILEX) / TILEX - 1; /* ...+TILEX...-1 to get correct */
+ int ly = (py + TILEY) / TILEY - 1; /* negative values! */
Pixel pixel;
- int px, py, lx, ly;
-
- px = SX + LX + (i % 2) * 2;
- py = SY + LY + (i / 2) * 2;
- lx = (px - SX + TILEX) / TILEX - 1; /* ...+TILEX...-1 to get correct */
- ly = (py - SY + TILEY) / TILEY - 1; /* negative values! */
if (IN_LEV_FIELD(lx, ly))
{
int element = Feld[lx][ly];
if (element == EL_EMPTY || element == EL_EXPLODING_TRANSP)
+ {
pixel = 0;
+ }
else if (IS_WALL(element) || IS_WALL_CHANGING(element))
{
- int pos =
- ((py - SY - ly * TILEY) / MINI_TILEX) * 2 +
- (px - SX - lx * TILEX) / MINI_TILEY;
+ int pos = dy / MINI_TILEY * 2 + dx / MINI_TILEX;
pixel = ((element & (1 << pos)) ? 1 : 0);
}
else
{
int graphic_mask = getMaskFromElement(element);
+ Bitmap *bitmap;
+ int src_x, src_y;
int mask_x, mask_y;
- int dx = px - lx * TILEX;
- int dy = py - ly * TILEY;
- mask_x = (graphic_mask % GFX_PER_LINE) * TILEX + dx;
- mask_y = (graphic_mask / GFX_PER_LINE) * TILEY + dy;
+ getGraphicSource(graphic_mask, 0, &bitmap, &src_x, &src_y);
+
+ 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
{
- if (px < REAL_SX || px >= REAL_SX + FULL_SXSIZE ||
- py < REAL_SY || py >= REAL_SY + FULL_SYSIZE)
- pixel = 1;
- else
- pixel = 0;
+ pixel = (SX + px < REAL_SX || SX + px >= REAL_SX + FULL_SXSIZE ||
+ SY + py < REAL_SY || SY + py >= REAL_SY + FULL_SYSIZE);
}
if ((Sign[laser.current_angle] & (1 << i)) && pixel)
{
int element;
int end = 0, rf = laser.num_edges;
-#if 0
- unsigned short color_scale = 0xFFFF / 15;
-#endif
-#if 0
- int testx, testy;
-#endif
+
+ /* do not scan laser again after the game was lost for whatever reason */
+ if (game_mm.game_over)
+ return;
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
{
end = 1;
laser.overloaded = TRUE;
+
break;
}
ELY = (LY - 2) / TILEY;
}
-
#if 0
printf("hit_mask (2) == '%x' (%d, %d) (%d, %d)\n",
hit_mask, LX, LY, ELX, ELY);
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))
if (HitBlock(element, hit_mask))
{
rf = 1;
+
break;
}
}
rf = laser.num_edges;
}
- /*
- element = Feld[ELX][ELY];
- laser.dest_element = element;
- */
-
-
-
-
#if 0
if (laser.dest_element != Feld[ELX][ELY])
{
}
#endif
-
if (!end && !laser.stops_inside_element && !StepBehind())
{
#if 0
LX -= XS;
LY -= YS;
+
AddLaserEdge(LX, LY);
}
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)
if (start_edge < 0)
{
Error(ERR_WARN, "DrawLaserExt: start_edge < 0");
+
return;
}
if (num_edges < 0)
{
Error(ERR_WARN, "DrawLaserExt: num_edges < 0");
+
return;
}
/* determine the starting edge, from which graphics need to be restored */
if (start_edge > 0)
{
- for(i=0; i<laser.num_damages; i++)
+ for (i = 0; i < laser.num_damages; i++)
{
if (laser.damage[i].edge == start_edge + 1)
{
damage_start = i;
+
break;
}
}
}
/* restore graphics from this starting edge to the end of damage list */
- for(i=damage_start; i<laser.num_damages; i++)
+ for (i = damage_start; i < laser.num_damages; i++)
{
int lx = laser.damage[i].x;
int ly = laser.damage[i].y;
ely = laser.damage[damage_start].y;
element = Feld[elx][ely];
-
#if 0
if (IS_BEAMER(element))
{
int i;
- for (i=0; i<laser.num_beamers; i++)
+ for (i = 0; i < laser.num_beamers; i++)
printf("-> %d\n", laser.beamer_edge[i]);
printf("DrawLaserExt: IS_BEAMER: [%d]: Hit[%d][%d] == %d [%d]\n",
mode, elx, ely, Hit[elx][ely], start_edge);
{
/* element is outgoing beamer */
laser.num_damages = damage_start + 1;
+
if (IS_BEAMER(element))
laser.current_angle = get_element_angle(element);
}
laser.num_edges = start_edge + 1;
if (start_edge == 0)
laser.current_angle = laser.start_angle;
+
LX = laser.edge[start_edge].x - (SX + 2);
LY = laser.edge[start_edge].y - (SY + 2);
XS = 2 * Step[laser.current_angle].x;
if (laser.num_edges - start_edge < 0)
{
Error(ERR_WARN, "DrawLaser: laser.num_edges - start_edge < 0");
+
return;
}
int tmp_start_edge = start_edge;
/* draw laser segments forward from the start to the last beamer */
- for (i=0; i<laser.num_beamers; i++)
+ for (i = 0; i < laser.num_beamers; i++)
{
int tmp_num_edges = laser.beamer_edge[i] - tmp_start_edge;
#endif
DrawLaserExt(tmp_start_edge, tmp_num_edges, DL_LASER_ENABLED);
+
tmp_start_edge = laser.beamer_edge[i];
}
int num_beamers = laser.num_beamers;
/* delete laser segments backward from the end to the first beamer */
- for (i=num_beamers-1; i>=0; i--)
+ for (i = num_beamers-1; i >= 0; i--)
{
int tmp_num_edges = last_num_edges - laser.beamer_edge[i];
break;
DrawLaserExt(laser.beamer_edge[i], tmp_num_edges, DL_LASER_DISABLED);
+
last_num_edges = laser.beamer_edge[i];
laser.num_beamers--;
}
}
}
else
+ {
DrawLaserExt(start_edge, laser.num_edges - start_edge, mode);
+ }
}
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);
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)
{
return FALSE;
}
-#endif
#if 0
printf("HitElement (2): element == %d\n", element);
((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--;
return TRUE;
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--;
return TRUE;
LX = ELX * TILEX + 14;
LY = ELY * TILEY + 14;
+
AddLaserEdge(LX, LY);
}
int step_size;
laser.num_damages--;
+
AddDamagedField(ELX, ELY);
+
laser.damage[laser.num_damages - 1].is_mirror = TRUE;
if (!Hit[ELX][ELY])
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;
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);
+ if (game_mm.kettles_still_needed > 0)
+ game_mm.kettles_still_needed--;
+
+ RaiseScore_MM(10);
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++)
+ for (y = 0; y < lev_fieldy; y++)
{
- for(x=0; x<lev_fieldx; x++)
+ for (x = 0; x < lev_fieldx; x++)
{
/* initiate opening animation of exit door */
if (Feld[x][y] == EL_EXIT_CLOSED)
if (IN_LEV_FIELD(blocking_x, blocking_y))
{
Feld[blocking_x][blocking_y] = EL_EMPTY;
+
DrawField_MM(blocking_x, blocking_y);
}
}
}
}
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;
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);
LX = ELX * TILEX + 14;
LY = ELY * TILEY + 14;
+
AddLaserEdge(LX, LY);
AddDamagedField(ELX, ELY);
+
laser.damage[laser.num_damages - 1].is_mirror = TRUE;
if (!Hit[ELX][ELY])
}
laser.beamer_edge[laser.num_beamers] = laser.num_edges;
+
AddLaserEdge(LX, LY);
AddDamagedField(ELX, ELY);
+
laser.damage[laser.num_damages - 1].is_mirror = TRUE;
if (!Hit[ELX][ELY])
}
AddDamagedField((LX + 2 * dx) / TILEX, (LY + 2 * dy) / TILEY);
+
LX += XS;
LY += YS;
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
{
LX -= XS;
LY -= YS;
}
-#endif
AddLaserEdge(LX, LY);
return FALSE;
}
else if (IS_GRID_STEEL_FIXED(element) || IS_GRID_STEEL_AUTO(element))
+ {
return HitReflectingWalls(element, hit_mask);
+ }
else
+ {
return HitAbsorbingWalls(element, hit_mask);
+ }
}
else if (IS_GRID_STEEL(element))
+ {
return HitReflectingWalls(element, hit_mask);
+ }
else /* IS_GRID_WOOD */
+ {
return HitAbsorbingWalls(element, hit_mask);
+ }
return TRUE;
}
check = TRUE;
- for(i=1; i<32; i++)
+ for (i = 1; i < 32; i++)
{
x = LX + i * XS;
y = LY + i * YS;
(hit_mask & hit_mask_diagonal2) == hit_mask_diagonal2)
{
laser.overloaded = (element == EL_GATE_STONE);
+
return TRUE;
}
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])
{
DrawLaser(Box[ELX][ELY] - 1, DL_LASER_DISABLED);
LX = ELX * TILEX + 14;
LY = ELY * TILEY + 14;
+
AddLaserEdge(LX, LY);
laser.stops_inside_element = TRUE;
boolean HitLaserSource(int element, int hit_mask)
{
- if (HitOnlyAnEdge(element, hit_mask))
- return FALSE;
+ if (HitOnlyAnEdge(element, hit_mask))
+ return FALSE;
- PlaySoundStereo(SND_AUTSCH, ST(ELX));
- laser.overloaded = TRUE;
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
- return TRUE;
+ laser.overloaded = 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;
+
if (!IS_DF_GRID(element))
AddLaserEdge(LX, LY);
}
AddLaserEdge(LX, LY);
+
XS = 2 * Step[laser.current_angle].x;
YS = 2 * Step[laser.current_angle].y;
(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);
LX += XS;
LY += YS;
+
AddLaserEdge(LX, LY);
return FALSE;
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);
*/
+
AddLaserEdge(LX - XS, LY - YS);
AddLaserEdge(LX - XS + (ABS(XS) == 4 ? XS/2 : 0),
LY - YS + (ABS(YS) == 4 ? YS/2 : 0));
LX += XS;
LY += YS;
+
AddLaserEdge(LX, LY);
return FALSE;
if (LX != last_LX || LY != last_LY || hit_mask == last_hit_mask)
{
AddDamagedField(ELX, ELY);
+
LX += 8 * XS;
LY += 8 * YS;
if (!HitOnlyAnEdge(element, hit_mask))
{
laser.overloaded = TRUE;
+
return TRUE;
}
(hit_mask == HIT_MASK_LEFT || hit_mask == HIT_MASK_RIGHT))
{
AddLaserEdge(LX - XS, LY - YS);
+
LX = LX + XS / 2;
LY = LY + YS;
}
(hit_mask == HIT_MASK_TOP || hit_mask == HIT_MASK_BOTTOM))
{
AddLaserEdge(LX - XS, LY - YS);
+
LX = LX + XS;
LY = LY + YS / 2;
}
element == EL_BLOCK_WOOD ||
element == EL_GATE_WOOD)
{
- PlaySoundStereo(SND_HOLZ, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
+
return TRUE;
}
{
int i;
- for(i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
{
if (mask == (1 << i) && (XS > 0) == (i % 2) && (YS > 0) == (i / 2))
mask = 15 - (8 >> i);
if (element2 != EL_EMPTY && !IS_WALL_AMOEBA(element2))
{
laser.dest_element = EL_EMPTY;
+
return TRUE;
}
MovDelay[x][y]--;
phase = MovDelay[x][y] / delay;
+
if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(x, y))
- DrawGraphic_MM(x, y, EL_EXIT_OPEN - phase);
+ DrawGraphicAnimation_MM(x, y, IMG_MM_EXIT_OPENING, 3 - phase);
if (!MovDelay[x][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;
int dx = RND(26), dy = RND(26);
getGraphicSource(graphic, 0, &bitmap, &gx, &gy);
+
BlitBitmap(bitmap, drawto, gx + dx, gy + dy, 6, 6,
SX + x * TILEX + dx, SY + y * TILEY + dy);
+
MarkTileDirty(x, y);
}
if (Feld[x][y] == EL_WALL_ICE)
Feld[x][y] = EL_EMPTY;
- for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i>=0; i--)
+ for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i >= 0; i--)
if (laser.damage[i].is_mirror)
break;
DrawLaser(0, DL_LASER_ENABLED);
}
else if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(x, y))
+ {
DrawWallsAnimation_MM(x, y, real_element, phase, wall_mask);
+ }
}
}
-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;
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;
}
Store[x][y] = center_element;
else
Store[x][y] = EL_EMPTY;
+
Store2[x][y] = mode;
Feld[x][y] = EL_EXPLODING_OPAQUE;
MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
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]))
Store[x][y] = EL_EMPTY;
}
-#if 0
- element = Feld[x][y] = Store[x][y];
-#endif
+ Feld[x][y] = Store[x][y];
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);
}
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;
+ graphic = IMG_EMPTY;
graphic_phase = 0;
}
}
- 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;
}
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(x, y, EX_PHASE_START, mode);
+ Explode_MM(x, y, EX_PHASE_START, mode);
}
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;
+ 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;
}
}
-void StartMoving(int x, int y)
+static void StartMoving_MM(int x, int y)
{
int element = Feld[x][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]) &&
{
Store[newx][newy] = Feld[newx][newy];
Feld[newx][newy] = EL_EMPTY;
+
DrawField_MM(newx, newy);
}
else if (!IN_LEV_FIELD(newx, newy) || !IS_FREE(newx, newy) ||
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];
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 &&
}
}
else /* still moving on */
+ {
DrawField_MM(x, y);
+ }
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 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])
+ return;
if (button == MB_RELEASED)
{
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)
if (!laser.fuse_off)
{
DrawLaser(0, DL_LASER_DISABLED);
+
/*
BackToFront();
*/
Feld[x][y] = element;
DrawField_MM(x, y);
+
/*
BackToFront();
*/
+
if (!laser.fuse_off)
ScanLaser();
}
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)
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);
}
hold_y = y;
}
else if (button == MB_RIGHTBUTTON && (hold_x != x || hold_y != y))
+ {
Feld[x][y] = get_rotated_element(Feld[x][y], ROTATE_RIGHT);
+ }
}
if (IS_GRID_STEEL_AUTO(Feld[x][y]) || IS_GRID_WOOD_AUTO(Feld[x][y]))
if (!DelayReached(&rotate_delay, AUTO_ROTATE_DELAY))
return;
- for (x=0; x<lev_fieldx; x++)
+ for (x = 0; x < lev_fieldx; x++)
{
- for (y=0; y<lev_fieldy; y++)
+ for (y = 0; y < lev_fieldy; y++)
{
int element = Feld[x][y];
+ /* do not rotate objects hit by the laser after the game was solved */
+ if (game_mm.level_solved && Hit[x][y])
+ continue;
+
if (IS_DF_MIRROR_AUTO(element) ||
IS_GRID_WOOD_AUTO(element) ||
IS_GRID_STEEL_AUTO(element) ||
if (bits & HIT_POS_EDGE)
{
- for(i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
if (ReadPixel(drawto,
SX + obx + 31 * (i % 2),
SY + oby + 31 * (i / 2)) == pen_ray)
if (bits & HIT_POS_BETWEEN)
{
- for(i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
if (ReadPixel(drawto,
SX + 4 + obx + 22 * (i % 2),
SY + 4 + oby + 22 * (i / 2)) == pen_ray)
{
int i, j;
- Bang(px, py);
+ Bang_MM(px, py);
if (game_mm.num_pacman <= 1)
{
return;
}
- for(i=0; i<game_mm.num_pacman; i++)
+ for (i = 0; i < game_mm.num_pacman; i++)
if (game_mm.pacman[i].x == px && game_mm.pacman[i].y == py)
break;
game_mm.num_pacman--;
- for(j=i; j<game_mm.num_pacman; j++)
+ for (j = i; j < game_mm.num_pacman; j++)
{
- game_mm.pacman[j].x = game_mm.pacman[j + 1].x;
- game_mm.pacman[j].y = game_mm.pacman[j + 1].y;
+ game_mm.pacman[j].x = game_mm.pacman[j + 1].x;
+ game_mm.pacman[j].y = game_mm.pacman[j + 1].y;
game_mm.pacman[j].dir = game_mm.pacman[j + 1].dir;
}
}
mult =- mult / 16;
old = color;
new = new << 4;
+
if (new > 0x100)
new = 0x001;
}
}
}
-void GameActions()
+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;
-#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++)
+ for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
Stop[x][y] = FALSE;
- for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
+ for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
{
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)
#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;
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)
{
int i;
- for(i=15; i>=0; i--)
+ for (i = 15; i >= 0; i--)
{
#if 0
SetRGB(pen_ray, 0x0000, 0x0000, i * color_scale);
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(50);
}
- StopSound(SND_WARNTON);
+ StopSound_MM(SND_MM_GAME_HEALTH_CHARGING);
FadeMusic();
DrawLaser(0, DL_LASER_DISABLED);
laser.overload_value = 0;
}
+ game_mm.laser_overload_value = laser.overload_value;
+
if (laser.overload_value < MAX_LASER_OVERLOAD - 8)
{
int color_up = 0xFF * laser.overload_value / MAX_LASER_OVERLOAD;
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));
+ 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));
+
DrawLaser(0, DL_LASER_ENABLED);
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);
- }
-
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 0
BlitBitmap(pix[PIX_DOOR], drawto,
DOOR_GFX_PAGEX4 + XX_OVERLOAD,
DOOR_GFX_PAGEY1 + YY_OVERLOAD + OVERLOAD_YSIZE
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;
}
{
int i;
- for(i=15; i>=0; i--)
+ 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(50);
}
DrawLaser(0, DL_LASER_DISABLED);
+
game_mm.game_over = TRUE;
game_mm.game_over_cause = GAME_OVER_OVERLOADED;
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))
laser.fuse_off = TRUE;
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)
graphic = el2gfx(element);
- for(i=0; i<50; i++)
+ for (i = 0; i < 50; i++)
{
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();
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;
return;
}
-
-
-
- for(i=0; i<5; i++)
+ for (i = 0; i < 5; i++)
{
int phase = i + 1;
LY = laser.edge[laser.num_edges].y - (SY + 2);
*/
- for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i>=0; i--)
+ for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i >= 0; i--)
if (laser.damage[i].is_mirror)
break;
if (element2 != EL_EMPTY && !IS_WALL_AMOEBA(element))
return;
- for (i = laser.num_damages - 1; i>=0; i--)
+ for (i = laser.num_damages - 1; i >= 0; i--)
if (laser.damage[i].is_mirror)
break;
x = laser.damage[k1].x;
y = laser.damage[k1].y;
+
DrawField_MM(x, y);
}
- for(i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
{
if (laser.wall_mask & (1 << i))
{
k2 = i;
- for(i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
{
if (laser.wall_mask & (1 << i))
{
{
laser.num_edges = r;
laser.num_damages = d;
+
DrawLaser(0, DL_LASER_DISABLED);
}
Feld[ELX][ELY] = element | laser.wall_mask;
+
dx = ELX;
dy = ELY;
de = Feld[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);
- 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;
}
#endif
-
-
DrawWallsAnimation_MM(dx, dy, de, 4, dm);
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--)
+ for (i = 4; i >= 0; i--)
{
DrawWallsAnimation_MM(dx, dy, de, i, dm);
+
BackToFront();
Delay(20);
}
if (XS < YS)
k += 2;
- for(i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
{
if (i)
k++;
if (k > 3)
- k=0;
+ k = 0;
x = ELX + Step[k * 4].x;
y = ELY + Step[k * 4].y;
if (i > 3)
{
laser.overloaded = (element == EL_BLOCK_STONE);
+
return;
}
- PlaySoundStereo(SND_BONG, ST(ELX));
+ PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_PUSHING);
Feld[ELX][ELY] = 0;
Feld[x][y] = element;
- DrawGraphic_MM(ELX, ELY, -1);
+ DrawGraphic_MM(ELX, ELY, IMG_EMPTY);
DrawField_MM(x, y);
if (element == EL_BLOCK_STONE && Box[ELX][ELY])
if (element == EL_FUEL_FULL && CT > 200)
{
- for(i=game_mm.energy_left; i<=MAX_LASER_ENERGY; i+=2)
+ 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();
return;
}
+void GameActions_MM(struct MouseActionInfo action, boolean warp_mode)
+{
+ ClickElement(action.lx, action.ly, action.button);
+
+ GameActions_MM_Ext(action, warp_mode);
+}
+
void MovePacMen()
{
static int p = -1;
int mx, my, ox, oy, nx, ny;
- int g, element;
+ int element;
int l;
if (++p >= game_mm.num_pacman)
p = 0;
+
game_mm.pacman[p].dir--;
- for(l=1; l<5; l++)
+ for (l = 1; l < 5; l++)
{
game_mm.pacman[p].dir++;
nx = ox + mx;
ny = oy + my;
element = Feld[nx][ny];
+
if (nx < 0 || nx > 15 || ny < 0 || ny > 11)
continue;
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)
{
+ int graphic = el2gfx(Feld[nx][ny]);
+ Bitmap *bitmap;
+ int src_x, src_y;
int i;
+ getGraphicSource(graphic, 0, &bitmap, &src_x, &src_y);
+
CT = Counter();
ox = SX + ox * TILEX;
oy = SY + oy * TILEY;
- for(i=1; i<33; i+=2)
- {
- BlitBitmap(pix[PIX_BACK], window,
- SX + g * TILEX, SY + 4 * TILEY, TILEX, TILEY,
+ for (i = 1; i < 33; i += 2)
+ BlitBitmap(bitmap, window,
+ src_x, src_y, TILEX, TILEY,
ox + i * mx, oy + i * my);
-#if 0
- FlushDisplay();
- Delay(1);
-#endif
- }
Ct = Ct + Counter() - CT;
}
+
DrawField_MM(nx, ny);
BackToFront();
if (ObjHit(nx, ny, HIT_POS_BETWEEN))
{
AddDamagedField(nx, ny);
+
laser.damage[laser.num_damages - 1].edge = 0;
}
}
if (element == EL_BOMB)
- {
DeletePacMan(nx, ny);
- }
if (IS_WALL_AMOEBA(element) &&
(LX + 2 * XS) / TILEX == nx &&
laser.num_edges--;
ScanLaser();
}
+
break;
}
}
-void GameWon()
+void GameWon_MM()
{
int hi_pos;
boolean raise_level = FALSE;
if (game_mm.energy_left)
{
if (setup.sound_loops)
- PlaySoundExt(SND_SIRR, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT, SND_CTRL_PLAY_LOOP);
+ PlaySoundExt(SND_SIRR, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
+ SND_CTRL_PLAY_LOOP);
- while(game_mm.energy_left > 0)
+ while (game_mm.energy_left > 0)
{
if (!setup.sound_loops)
PlaySoundStereo(SND_SIRR, SOUND_MAX_RIGHT);
/*
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;
}
else if (native_mm_level.time == 0) /* level without time limit */
{
if (setup.sound_loops)
- PlaySoundExt(SND_SIRR, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT, SND_CTRL_PLAY_LOOP);
+ PlaySoundExt(SND_SIRR, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
+ SND_CTRL_PLAY_LOOP);
- while(TimePlayed < 999)
+ while (TimePlayed < 999)
{
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
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);
+
if (raise_level)
level_nr++;
}
else
{
game_status = MAINMENU;
+
if (raise_level)
level_nr++;
+
// DrawMainMenu();
}
BackToFront();
}
-int NewHiScore()
+int NewHiScore_MM()
{
int k, l;
int position = -1;
game_mm.score < highscore[MAX_SCORE_ENTRIES - 1].Score)
return -1;
- for (k=0; k<MAX_SCORE_ENTRIES; k++)
+ for (k = 0; k < MAX_SCORE_ENTRIES; k++)
{
if (game_mm.score > highscore[k].Score)
{
int m = MAX_SCORE_ENTRIES - 1;
#ifdef ONE_PER_NAME
- for (l=k; l<MAX_SCORE_ENTRIES; l++)
+ for (l = k; l < MAX_SCORE_ENTRIES; l++)
if (!strcmp(setup.player_name, highscore[l].Name))
m = l;
if (m == k) /* player's new highscore overwrites his old one */
goto put_into_list;
#endif
- for (l=m; l>k; l--)
+ for (l = m; l>k; l--)
{
strcpy(highscore[l].Name, highscore[l - 1].Name);
highscore[l].Score = highscore[l - 1].Score;
highscore[k].Name[MAX_PLAYER_NAME_LEN] = '\0';
highscore[k].Score = game_mm.score;
position = k;
+
break;
}
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);
MovDir[x][y] = direction;
MovDir[newx][newy] = direction;
+
if (Feld[newx][newy] == EL_EMPTY)
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);
*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];
*comes_from_y = oldy;
}
-int MovingOrBlocked2Element(int x, int y)
+static int MovingOrBlocked2Element_MM(int x, int y)
{
int element = Feld[x][y];
{
int oldx, oldy;
- Blocked2Moving(x, y, &oldx, &oldy);
+ Blocked2Moving_MM(x, y, &oldx, &oldy);
+
return Feld[oldx][oldy];
}
- else
- return element;
+
+ return element;
}
#if 0
}
#endif
-void RemoveMovingField(int x, int y)
+static void RemoveMovingField_MM(int x, int y)
{
int oldx = x, oldy = y, newx = x, newy = 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;
}
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
DrawText(DX_SCORE, DY_SCORE, int2str(game_mm.score, 4),
FONT_TEXT_2);
#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;
}