return ly;
}
+static int getLevelFromScreenX_MM(int sx)
+{
+#if 0
+ int level_xsize = level.native_mm_level->fieldx;
+ int full_xsize = level_xsize * TILESIZE_VAR;
+
+ sx -= (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0);
+#endif
+
+ int px = sx - SX;
+ int lx = px / TILESIZE_VAR;
+
+ return lx;
+}
+
+static int getLevelFromScreenY_MM(int sy)
+{
+#if 0
+ int level_ysize = level.native_mm_level->fieldy;
+ int full_ysize = level_ysize * TILESIZE_VAR;
+
+ sy -= (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0);
+#endif
+
+ int py = sy - SY;
+ int ly = py / TILESIZE_VAR;
+
+ return ly;
+}
+
int getLevelFromScreenX(int x)
{
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
return getLevelFromScreenX_EM(x);
if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
return getLevelFromScreenX_SP(x);
+ if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ return getLevelFromScreenX_MM(x);
else
return getLevelFromScreenX_RND(x);
}
return getLevelFromScreenY_EM(y);
if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
return getLevelFromScreenY_SP(y);
+ if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ return getLevelFromScreenY_MM(y);
else
return getLevelFromScreenY_RND(y);
}
{
int sx = SCREENX(x);
int sy = SCREENY(y);
+ char *token_name;
printf_line("-", 79);
printf("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y);
return;
}
- printf(" Feld: %d\t['%s']\n", Feld[x][y],
- element_info[Feld[x][y]].token_name);
+ token_name = element_info[Feld[x][y]].token_name;
+
+ printf(" Feld: %d\t['%s']\n", Feld[x][y], token_name);
printf(" Back: %s\n", print_if_not_empty(Back[x][y]));
printf(" Store: %s\n", print_if_not_empty(Store[x][y]));
printf(" Store2: %s\n", print_if_not_empty(Store2[x][y]));
RedrawPlayfield_EM(TRUE);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
RedrawPlayfield_SP(TRUE);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ RedrawPlayfield_MM();
else if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
RedrawPlayfield_RND();
BlitScreenToBitmap_EM(target_bitmap);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
BlitScreenToBitmap_SP(target_bitmap);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ BlitScreenToBitmap_MM(target_bitmap);
else if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
BlitScreenToBitmap_RND(target_bitmap);
BorderElement = EL_EMPTY;
+ /* the MM game engine does not use a visible border element */
+ if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ return;
+
for (y = 0; y < lev_fieldy && BorderElement == EL_EMPTY; y++)
{
for (x = 0; x < lev_fieldx; x++)
}
}
-void FloodFillLevel(int from_x, int from_y, int fill_element,
- short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY],
- int max_fieldx, int max_fieldy)
+void FloodFillLevelExt(int from_x, int from_y, int fill_element,
+ int max_array_fieldx, int max_array_fieldy,
+ short field[max_array_fieldx][max_array_fieldy],
+ int max_fieldx, int max_fieldy)
{
int i,x,y;
int old_element;
y = from_y + check[i][1];
if (IN_FIELD(x, y, max_fieldx, max_fieldy) && field[x][y] == old_element)
- FloodFillLevel(x, y, fill_element, field, max_fieldx, max_fieldy);
+ FloodFillLevelExt(x, y, fill_element, max_array_fieldx, max_array_fieldy,
+ field, max_fieldx, max_fieldy);
}
safety--;
}
+void FloodFillLevel(int from_x, int from_y, int fill_element,
+ short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY],
+ int max_fieldx, int max_fieldy)
+{
+ FloodFillLevelExt(from_x, from_y, fill_element,
+ MAX_LEV_FIELDX, MAX_LEV_FIELDY, field,
+ max_fieldx, max_fieldy);
+}
+
void SetRandomAnimationValue(int x, int y)
{
gfx.anim_random_frame = GfxRandom[x][y];
*y = *y * tilesize / g->tile_size;
}
-void getFixedGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
- int *x, int *y, boolean get_backside)
-{
- getSizedGraphicSourceExt(graphic, frame, TILESIZE, bitmap, x, y,
- get_backside);
-}
-
void getSizedGraphicSource(int graphic, int frame, int tilesize,
Bitmap **bitmap, int *x, int *y)
{
MarkTileDirty(x / tilesize, y / tilesize);
}
+void DrawSizedGraphicThruMask(int x, int y, int graphic, int frame,
+ int tilesize)
+{
+ DrawSizedGraphicThruMaskExt(drawto, SX + x * tilesize, SY + y * tilesize,
+ graphic, frame, tilesize);
+ MarkTileDirty(x / tilesize, y / tilesize);
+}
+
void DrawSizedGraphicExt(DrawBuffer *d, int x, int y, int graphic, int frame,
int tilesize)
{
BlitBitmap(src_bitmap, d, src_x, src_y, tilesize, tilesize, x, y);
}
+void DrawSizedGraphicThruMaskExt(DrawBuffer *d, int x, int y, int graphic,
+ int frame, int tilesize)
+{
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+
+ getSizedGraphicSource(graphic, frame, tilesize, &src_bitmap, &src_x, &src_y);
+ BlitBitmapMasked(src_bitmap, d, src_x, src_y, tilesize, tilesize, x, y);
+}
+
void DrawMiniGraphic(int x, int y, int graphic)
{
DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic);
}
}
+static void DrawSizedWallExt_MM(int dst_x, int dst_y, int element, int tilesize,
+ int (*el2img_function)(int), boolean masked,
+ int element_bits_draw)
+{
+ int element_base = map_mm_wall_element(element);
+ int element_bits = (IS_DF_WALL(element) ?
+ element - EL_DF_WALL_START :
+ IS_MM_WALL(element) ?
+ element - EL_MM_WALL_START : EL_EMPTY) & 0x000f;
+ int graphic = el2img_function(element_base);
+ int tilesize_draw = tilesize / 2;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int i;
+
+ getSizedGraphicSource(graphic, 0, tilesize_draw, &src_bitmap, &src_x, &src_y);
+
+ for (i = 0; i < 4; i++)
+ {
+ int dst_draw_x = dst_x + (i % 2) * tilesize_draw;
+ int dst_draw_y = dst_y + (i / 2) * tilesize_draw;
+
+ if (!(element_bits_draw & (1 << i)))
+ continue;
+
+ if (element_bits & (1 << i))
+ {
+ if (masked)
+ BlitBitmapMasked(src_bitmap, drawto, src_x, src_y,
+ tilesize_draw, tilesize_draw, dst_draw_x, dst_draw_y);
+ else
+ BlitBitmap(src_bitmap, drawto, src_x, src_y,
+ tilesize_draw, tilesize_draw, dst_draw_x, dst_draw_y);
+ }
+ else
+ {
+ if (!masked)
+ ClearRectangle(drawto, dst_draw_x, dst_draw_y,
+ tilesize_draw, tilesize_draw);
+ }
+ }
+}
+
+void DrawSizedWallParts_MM(int x, int y, int element, int tilesize,
+ boolean masked, int element_bits_draw)
+{
+ DrawSizedWallExt_MM(SX + x * tilesize, SY + y * tilesize,
+ element, tilesize, el2edimg, masked, element_bits_draw);
+}
+
+void DrawSizedWall_MM(int dst_x, int dst_y, int element, int tilesize,
+ int (*el2img_function)(int))
+{
+ DrawSizedWallExt_MM(dst_x, dst_y, element, tilesize, el2img_function, FALSE,
+ 0x000f);
+}
+
+void DrawSizedElementExt(int x, int y, int element, int tilesize,
+ boolean masked)
+{
+ if (IS_MM_WALL(element))
+ {
+ DrawSizedWallExt_MM(SX + x * tilesize, SY + y * tilesize,
+ element, tilesize, el2edimg, masked, 0x000f);
+ }
+ else
+ {
+ int graphic = el2edimg(element);
+
+ if (masked)
+ DrawSizedGraphicThruMask(x, y, graphic, 0, tilesize);
+ else
+ DrawSizedGraphic(x, y, graphic, 0, tilesize);
+ }
+}
+
void DrawSizedElement(int x, int y, int element, int tilesize)
{
- int graphic;
+ DrawSizedElementExt(x, y, element, tilesize, FALSE);
+}
- graphic = el2edimg(element);
- DrawSizedGraphic(x, y, graphic, 0, tilesize);
+void DrawSizedElementThruMask(int x, int y, int element, int tilesize)
+{
+ DrawSizedElementExt(x, y, element, tilesize, TRUE);
}
void DrawMiniElement(int x, int y, int element)
boolean no_delay = (tape.warp_forward);
unsigned int anim_delay = 0;
int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
- int anim_delay_value = (no_delay ? 0 : frame_delay_value) / 2;
+ int anim_delay_value = MAX(1, (no_delay ? 0 : frame_delay_value) / 2);
int font_nr = FONT_ENVELOPE_1 + envelope_nr;
int font_width = getFontWidth(font_nr);
int font_height = getFontHeight(font_nr);
boolean ffwd_delay = (tape.playing && tape.fast_forward);
boolean no_delay = (tape.warp_forward);
int delay_value = (ffwd_delay ? delay_value_fast : delay_value_normal);
- int anim_delay_value = (no_delay ? 0 : delay_value + 500 * 0) / 2;
+ int anim_delay_value = MAX(1, (no_delay ? 0 : delay_value + 500 * 0) / 2);
unsigned int anim_delay = 0;
int tile_size = MAX(request.step_offset, 1);
void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize)
{
- Bitmap *src_bitmap;
- int src_x, src_y;
- int graphic = el2preimg(element);
+ if (IS_MM_WALL(element))
+ {
+ DrawSizedWall_MM(dst_x, dst_y, element, tilesize, el2preimg);
+ }
+ else
+ {
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int graphic = el2preimg(element);
- getSizedGraphicSource(graphic, 0, tilesize, &src_bitmap, &src_x, &src_y);
- BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize, tilesize, dst_x,dst_y);
+ getSizedGraphicSource(graphic, 0, tilesize, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize, tilesize,
+ dst_x, dst_y);
+ }
}
void DrawLevel(int draw_background_mask)
while (still_wait)
{
- if (PendingEvent())
- {
- Event event;
-
- WaitEvent(&event);
+ Event event;
+ if (NextValidEvent(&event))
+ {
switch (event.type)
{
case EVENT_BUTTONPRESS:
{
if (level_solved)
{
- SetDrawtoField(DRAW_TO_FIELDBUFFER);
+ /* the MM game engine does not use a special (scrollable) field buffer */
+ if (level.game_engine_type != GAME_ENGINE_TYPE_MM)
+ SetDrawtoField(DRAW_TO_FIELDBUFFER);
HandleGameActions();
}
}
+int map_element_RND_to_MM(int element_rnd)
+{
+ return (element_rnd >= EL_MM_START_1 &&
+ element_rnd <= EL_MM_END_1 ?
+ EL_MM_START_1_NATIVE + element_rnd - EL_MM_START_1 :
+
+ element_rnd >= EL_MM_START_2 &&
+ element_rnd <= EL_MM_END_2 ?
+ EL_MM_START_2_NATIVE + element_rnd - EL_MM_START_2 :
+
+ element_rnd >= EL_CHAR_START &&
+ element_rnd <= EL_CHAR_END ?
+ EL_MM_CHAR_START_NATIVE + element_rnd - EL_CHAR_START :
+
+ element_rnd >= EL_MM_RUNTIME_START &&
+ element_rnd <= EL_MM_RUNTIME_END ?
+ EL_MM_RUNTIME_START_NATIVE + element_rnd - EL_MM_RUNTIME_START :
+
+ element_rnd >= EL_MM_DUMMY_START &&
+ element_rnd <= EL_MM_DUMMY_END ?
+ EL_MM_DUMMY_START_NATIVE + element_rnd - EL_MM_DUMMY_START :
+
+ EL_MM_EMPTY_NATIVE);
+}
+
+int map_element_MM_to_RND(int element_mm)
+{
+ return (element_mm == EL_MM_EMPTY_NATIVE ||
+ element_mm == EL_DF_EMPTY_NATIVE ?
+ EL_EMPTY :
+
+ element_mm >= EL_MM_START_1_NATIVE &&
+ element_mm <= EL_MM_END_1_NATIVE ?
+ EL_MM_START_1 + element_mm - EL_MM_START_1_NATIVE :
+
+ element_mm >= EL_MM_START_2_NATIVE &&
+ element_mm <= EL_MM_END_2_NATIVE ?
+ EL_MM_START_2 + element_mm - EL_MM_START_2_NATIVE :
+
+ element_mm >= EL_MM_CHAR_START_NATIVE &&
+ element_mm <= EL_MM_CHAR_END_NATIVE ?
+ EL_CHAR_START + element_mm - EL_MM_CHAR_START_NATIVE :
+
+ element_mm >= EL_MM_RUNTIME_START_NATIVE &&
+ element_mm <= EL_MM_RUNTIME_END_NATIVE ?
+ EL_MM_RUNTIME_START + element_mm - EL_MM_RUNTIME_START_NATIVE :
+
+ element_mm >= EL_MM_DUMMY_START_NATIVE &&
+ element_mm <= EL_MM_DUMMY_END_NATIVE ?
+ EL_MM_DUMMY_START + element_mm - EL_MM_DUMMY_START_NATIVE :
+
+ EL_EMPTY);
+}
+
+int map_action_MM_to_RND(int action_mm)
+{
+ /* all MM actions are defined to exactly match their RND counterparts */
+ return action_mm;
+}
+
+int map_sound_MM_to_RND(int sound_mm)
+{
+ switch (sound_mm)
+ {
+ case SND_MM_GAME_LEVELTIME_CHARGING:
+ return SND_GAME_LEVELTIME_CHARGING;
+
+ case SND_MM_GAME_HEALTH_CHARGING:
+ return SND_GAME_HEALTH_CHARGING;
+
+ default:
+ return SND_UNDEFINED;
+ }
+}
+
+int map_mm_wall_element(int element)
+{
+ return (element >= EL_MM_STEEL_WALL_START &&
+ element <= EL_MM_STEEL_WALL_END ?
+ EL_MM_STEEL_WALL :
+
+ element >= EL_MM_WOODEN_WALL_START &&
+ element <= EL_MM_WOODEN_WALL_END ?
+ EL_MM_WOODEN_WALL :
+
+ element >= EL_MM_ICE_WALL_START &&
+ element <= EL_MM_ICE_WALL_END ?
+ EL_MM_ICE_WALL :
+
+ element >= EL_MM_AMOEBA_WALL_START &&
+ element <= EL_MM_AMOEBA_WALL_END ?
+ EL_MM_AMOEBA_WALL :
+
+ element >= EL_DF_STEEL_WALL_START &&
+ element <= EL_DF_STEEL_WALL_END ?
+ EL_DF_STEEL_WALL :
+
+ element >= EL_DF_WOODEN_WALL_START &&
+ element <= EL_DF_WOODEN_WALL_END ?
+ EL_DF_WOODEN_WALL :
+
+ element);
+}
+
+int map_mm_wall_element_editor(int element)
+{
+ switch (element)
+ {
+ case EL_MM_STEEL_WALL: return EL_MM_STEEL_WALL_START;
+ case EL_MM_WOODEN_WALL: return EL_MM_WOODEN_WALL_START;
+ case EL_MM_ICE_WALL: return EL_MM_ICE_WALL_START;
+ case EL_MM_AMOEBA_WALL: return EL_MM_AMOEBA_WALL_START;
+ case EL_DF_STEEL_WALL: return EL_DF_STEEL_WALL_START;
+ case EL_DF_WOODEN_WALL: return EL_DF_WOODEN_WALL_START;
+
+ default: return element;
+ }
+}
+
int get_next_element(int element)
{
switch (element)
}
}
+int el2img_mm(int element_mm)
+{
+ return el2img(map_element_MM_to_RND(element_mm));
+}
+
int el_act_dir2img(int element, int action, int direction)
{
element = GFX_ELEMENT(element);
return InitEngineRandom_EM(seed);
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
return InitEngineRandom_SP(seed);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ return InitEngineRandom_MM(seed);
else
return InitEngineRandom_RND(seed);
}
void PlayMenuMusic()
{
char *curr_music = getCurrentlyPlayingMusicFilename();
- char *next_music = getMusicListEntry(menu.music[game_status])->filename;
+ char *next_music = getMusicInfoEntryFilename(menu.music[game_status]);
if (!strEqual(curr_music, next_music))
PlayMenuMusicExt(menu.music[game_status]);
static void FadeMenuMusic()
{
char *curr_music = getCurrentlyPlayingMusicFilename();
- char *next_music = getMusicListEntry(menu.music[game_status])->filename;
+ char *next_music = getMusicInfoEntryFilename(menu.music[game_status]);
if (!strEqual(curr_music, next_music))
FadeMusic();
void ChangeViewportPropertiesIfNeeded()
{
+ boolean use_mini_tilesize = (level.game_engine_type == GAME_ENGINE_TYPE_MM ?
+ FALSE : setup.small_game_graphics);
int gfx_game_mode = game_status;
int gfx_game_mode2 = (game_status == GAME_MODE_EDITOR ? GAME_MODE_DEFAULT :
game_status);
int new_ey = vp_door_3->y;
int new_exsize = vp_door_3->width;
int new_eysize = vp_door_3->height;
- int new_tilesize_var =
- (setup.small_game_graphics ? MINI_TILESIZE : game.tile_size);
-
+ int new_tilesize_var = (use_mini_tilesize ? MINI_TILESIZE : game.tile_size);
int tilesize = (gfx_game_mode == GAME_MODE_PLAYING ? new_tilesize_var :
gfx_game_mode == GAME_MODE_EDITOR ? MINI_TILESIZE : TILESIZE);
int new_scr_fieldx = new_sxsize / tilesize;