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;
- /* !!! THIS ONLY REALLY WORKS WITH anim_frames == 7 (MOVEMENT FRAMES) !!! */
- /* !!! (ELSE sync_frame DOES NOT START WITH 0 AND MOVEMENT LOOK WRONG !!! */
- /* !!! (AND anim_frames == 15 FOR SLOW MOVEMENT AND SO ON) !!! */
#if 1
/* (we also need anim_delay here for movement animations with less frames) */
int anim_delay = graphic_info[graphic].anim_delay;
- int anim_pos = (dx ? ABS(dx) : ABS(dy));
int sync_frame = anim_pos * anim_frames * anim_delay / TILESIZE;
#else
- int sync_frame = (dx ? ABS(dx) : ABS(dy)) * anim_frames / TILESIZE;
+ 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! */
frame = getGraphicAnimationFrame(graphic, sync_frame);
#if 0
- printf("::: %d [%d, %d]\n", frame, sync_frame, dy);
+#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 */
DrawPlayer(PLAYERINFO(x, y));
}
-#define TEST_DRAW_PLAYER_OVER_PUSHED_ELEMENT 1
+#define DRAW_PLAYER_OVER_PUSHED_ELEMENT 1
void DrawPlayer(struct PlayerInfo *player)
{
}
}
-#if !TEST_DRAW_PLAYER_OVER_PUSHED_ELEMENT
+#if !DRAW_PLAYER_OVER_PUSHED_ELEMENT
/* ----------------------------------------------------------------------- */
/* draw player himself */
/* ----------------------------------------------------------------------- */
}
#endif
-#if TEST_DRAW_PLAYER_OVER_PUSHED_ELEMENT
+#if DRAW_PLAYER_OVER_PUSHED_ELEMENT
if (player->GfxPos)
{
if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
#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]\n",
- jx, px, player->GfxPos, player->is_pushing, dx, sxx, pxx,
- IS_MOVING(jx, jy), graphic, frame);
+ 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
}
#endif
-#if TEST_DRAW_PLAYER_OVER_PUSHED_ELEMENT
+#if DRAW_PLAYER_OVER_PUSHED_ELEMENT
/* ----------------------------------------------------------------------- */
/* draw player himself */
/* ----------------------------------------------------------------------- */
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)
#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)