/* blit playfield from scroll buffer to normal back buffer for fading in */
BlitScreenToBitmap_EM(backbuffer);
}
- else if (game_status == GAME_MODE_PLAYING && !game.envelope_active)
+ else if (game_status == GAME_MODE_PLAYING &&
+ level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ {
+ /* currently there is no partial redraw -- always redraw whole playfield */
+ RedrawPlayfield_SP(TRUE);
+
+ /* blit playfield from scroll buffer to normal back buffer for fading in */
+ BlitScreenToBitmap_SP(backbuffer);
+ }
+ else if (game_status == GAME_MODE_PLAYING &&
+ !game.envelope_active)
{
if (force_redraw)
{
}
#endif
- /* !!! what abount fade_mask == REDRAW_FIELD | REDRAW_ALL ??? !!! */
+ /* !!! what about fade_mask == REDRAW_FIELD | REDRAW_ALL ??? !!! */
#if 0
printf("::: NOW FADING %d ... [%d]\n", fade_mode, fade_type);
int y1 = y;
int x2 = x + SIGN(dx);
int y2 = y + SIGN(dy);
+#if 0
+ /* !!! DOES NOT WORK FOR SLOW MOVEMENT !!! */
+ int sync_frame = GfxFrame[LEVELX(x)][LEVELY(y)];
+#else
+ /* movement with two-tile animations must be sync'ed with movement position,
+ not with current GfxFrame (which can be higher when using slow movement) */
+ int anim_pos = (dx ? ABS(dx) : ABS(dy));
int anim_frames = graphic_info[graphic].anim_frames;
- int sync_frame = (dx ? ABS(dx) : ABS(dy)) * anim_frames / TILESIZE;
+#if 1
+ /* (we also need anim_delay here for movement animations with less frames) */
+ int anim_delay = graphic_info[graphic].anim_delay;
+ int sync_frame = anim_pos * anim_frames * anim_delay / TILESIZE;
+#else
+ int sync_frame = anim_pos * anim_frames / TILESIZE;
+#endif
+#endif
boolean draw_start_tile = (cut_mode != CUT_ABOVE); /* only for falling! */
boolean draw_end_tile = (cut_mode != CUT_BELOW); /* only for falling! */
/* re-calculate animation frame for two-tile movement animation */
frame = getGraphicAnimationFrame(graphic, sync_frame);
+#if 0
+#if 0
+ printf("::: %d, %d, %d => %d [%d]\n",
+ anim_pos, anim_frames, anim_delay, sync_frame, graphic);
+#else
+ printf("::: %d, %d => %d\n",
+ anim_pos, anim_frames, sync_frame);
+#endif
+#endif
+
+#if 0
+ printf("::: %d [%d, %d] [%d] [%d]\n", frame, sync_frame, dy,
+ GfxFrame[LEVELX(x)][LEVELY(y)], mask_mode);
+#endif
+
/* check if movement start graphic inside screen area and should be drawn */
if (draw_start_tile && IN_SCR_FIELD(x1, y1))
{
DrawPlayer(PLAYERINFO(x, y));
}
+#define DRAW_PLAYER_OVER_PUSHED_ELEMENT 1
+
void DrawPlayer(struct PlayerInfo *player)
{
int jx = player->jx;
}
}
+#if !DRAW_PLAYER_OVER_PUSHED_ELEMENT
/* ----------------------------------------------------------------------- */
/* draw player himself */
/* ----------------------------------------------------------------------- */
DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
}
+#endif
+
+#if DRAW_PLAYER_OVER_PUSHED_ELEMENT
+ if (player->GfxPos)
+ {
+ if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
+ sxx = player->GfxPos;
+ else
+ syy = player->GfxPos;
+ }
+#endif
/* ----------------------------------------------------------------------- */
/* draw things the player is pushing, if needed */
#endif
/* draw background element under pushed element (like the Sokoban field) */
+#if 1
+ if (game.use_masked_pushing && IS_MOVING(jx, jy))
+ {
+ /* this allows transparent pushing animation over non-black background */
+
+ if (Back[jx][jy])
+ DrawLevelElement(jx, jy, Back[jx][jy]);
+ else
+ DrawLevelElement(jx, jy, EL_EMPTY);
+
+ if (Back[next_jx][next_jy])
+ DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+ else
+ DrawLevelElement(next_jx, next_jy, EL_EMPTY);
+ }
+ else if (Back[next_jx][next_jy])
+ DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+#else
if (Back[next_jx][next_jy])
DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+#endif
+#if 0
+ printf("::: %d, %d, %d, %d [%d] [%d, %d, %d] [%d] [%d, %d] [%d, %d]\n",
+ jx, px, player->GfxPos, player->StepFrame,
+ player->is_pushing,
+ dx, sxx, pxx,
+ IS_MOVING(jx, jy),
+ graphic, frame,
+ GfxFrame[jx][jy], GfxFrame[next_jx][next_jy]);
+#endif
+
+#if 1
+ /* do not draw (EM style) pushing animation when pushing is finished */
+ /* (two-tile animations usually do not contain start and end frame) */
+ if (graphic_info[graphic].double_movement && !IS_MOVING(jx, jy))
+ DrawLevelElement(next_jx, next_jy, Feld[next_jx][next_jy]);
+ else
+ DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING);
+#else
/* masked drawing is needed for EMC style (double) movement graphics */
+ /* !!! (ONLY WHEN DRAWING PUSHED ELEMENT OVER THE PLAYER) !!! */
DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING);
+#endif
+ }
+#endif
+
+#if DRAW_PLAYER_OVER_PUSHED_ELEMENT
+ /* ----------------------------------------------------------------------- */
+ /* draw player himself */
+ /* ----------------------------------------------------------------------- */
+
+ graphic = getPlayerGraphic(player, move_dir);
+
+ /* in the case of changed player action or direction, prevent the current
+ animation frame from being restarted for identical animations */
+ if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
+ player->Frame = last_player_frame;
+
+ frame = getGraphicAnimationFrame(graphic, player->Frame);
+
+ if (player->GfxPos)
+ {
+ if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
+ sxx = player->GfxPos;
+ else
+ syy = player->GfxPos;
+ }
+
+ if (!setup.soft_scrolling && ScreenMovPos)
+ sxx = syy = 0;
+
+ if (player_is_opaque)
+ DrawGraphicShifted(sx, sy, sxx, syy, graphic, frame,NO_CUTTING,NO_MASKING);
+ else
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
+
+ if (SHIELD_ON(player))
+ {
+ int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE :
+ IMG_SHIELD_NORMAL_ACTIVE);
+ int frame = getGraphicAnimationFrame(graphic, -1);
+
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
}
#endif
}
}
- if (game_status == GAME_MODE_PLAYING &&
- level.game_engine_type == GAME_ENGINE_TYPE_EM)
- BlitScreenToBitmap_EM(backbuffer);
+ if (game_status == GAME_MODE_PLAYING)
+ {
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ BlitScreenToBitmap_EM(backbuffer);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ BlitScreenToBitmap_SP(backbuffer);
+ }
/* disable deactivated drawing when quick-loading level tape recording */
if (tape.playing && tape.deactivate_display)
MV_NONE);
}
+int map_element_RND_to_SP(int element_rnd)
+{
+ int element_sp = 0x20; /* map unknown elements to yellow "hardware" */
+
+ if (element_rnd >= EL_SP_START &&
+ element_rnd <= EL_SP_END)
+ element_sp = element_rnd - EL_SP_START;
+ else if (element_rnd == EL_EMPTY_SPACE)
+ element_sp = 0x00;
+ else if (element_rnd == EL_INVISIBLE_WALL)
+ element_sp = 0x28;
+
+ return element_sp;
+}
+
+int map_element_SP_to_RND(int element_sp)
+{
+ int element_rnd = EL_UNKNOWN;
+
+ if (element_sp >= 0x00 &&
+ element_sp <= 0x27)
+ element_rnd = EL_SP_START + element_sp;
+ else if (element_sp == 0x28)
+ element_rnd = EL_INVISIBLE_WALL;
+
+ return element_rnd;
+}
+
+int map_action_SP_to_RND(int action_sp)
+{
+ switch (action_sp)
+ {
+ case actActive: return ACTION_ACTIVE;
+ case actImpact: return ACTION_IMPACT;
+ case actExploding: return ACTION_EXPLODING;
+ case actDigging: return ACTION_DIGGING;
+ case actSnapping: return ACTION_SNAPPING;
+ case actCollecting: return ACTION_COLLECTING;
+ case actPassing: return ACTION_PASSING;
+ case actPushing: return ACTION_PUSHING;
+ case actDropping: return ACTION_DROPPING;
+
+ default: return ACTION_DEFAULT;
+ }
+}
+
int get_next_element(int element)
{
switch (element)
{
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
return InitEngineRandom_EM(seed);
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ return InitEngineRandom_SP(seed);
else
return InitEngineRandom_RND(seed);
}
#endif
}
+void getGraphicSource_SP(struct GraphicInfo_SP *g_sp,
+ int graphic, int sync_frame, int x, int y)
+{
+ int frame = getGraphicAnimationFrame(graphic, sync_frame);
+
+ getGraphicSource(graphic, frame, &g_sp->bitmap, &g_sp->src_x, &g_sp->src_y);
+}
+
+boolean isNextAnimationFrame_SP(int graphic, int sync_frame)
+{
+ return (IS_NEXT_FRAME(sync_frame, graphic));
+}
+
+int getGraphicInfo_Delay(int graphic)
+{
+ return graphic_info[graphic].anim_delay;
+}
+
void PlayMenuSoundExt(int sound)
{
if (sound == SND_UNDEFINED)