+ if (mode == SCROLL_INIT)
+ {
+ player->actual_frame_counter = FrameCounter;
+ player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
+
+ if (Feld[last_jx][last_jy] == EL_EMPTY)
+ Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING;
+
+#if 0
+ DrawPlayer(player);
+#endif
+ return;
+ }
+ else if (!FrameReached(&player->actual_frame_counter, 1))
+ return;
+
+ player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize;
+ player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
+
+ if (Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING)
+ Feld[last_jx][last_jy] = EL_EMPTY;
+
+ /* before DrawPlayer() to draw correct player graphic for this case */
+ if (player->MovPos == 0)
+ CheckGravityMovement(player);
+
+#if 0
+ DrawPlayer(player); /* needed here only to cleanup last field */
+#endif
+
+ if (player->MovPos == 0) /* player reached destination field */
+ {
+ if (IS_PASSABLE(Feld[last_jx][last_jy]))
+ {
+ /* continue with normal speed after quickly moving through gate */
+ HALVE_PLAYER_SPEED(player);
+
+ /* be able to make the next move without delay */
+ player->move_delay = 0;
+ }
+
+ player->last_jx = jx;
+ player->last_jy = jy;
+
+ if (Feld[jx][jy] == EL_EXIT_OPEN ||
+ Feld[jx][jy] == EL_SP_EXIT_OPEN)
+ {
+ DrawPlayer(player); /* needed here only to cleanup last field */
+ RemoveHero(player);
+
+ if (local_player->friends_still_needed == 0 ||
+ Feld[jx][jy] == EL_SP_EXIT_OPEN)
+ player->LevelSolved = player->GameOver = TRUE;
+ }
+
+ if (tape.single_step && tape.recording && !tape.pausing &&
+ !player->programmed_action)
+ TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+ }
+}
+
+void ScrollScreen(struct PlayerInfo *player, int mode)
+{
+ static unsigned long screen_frame_counter = 0;
+
+ if (mode == SCROLL_INIT)
+ {
+ /* set scrolling step size according to actual player's moving speed */
+ ScrollStepSize = TILEX / player->move_delay_value;
+
+ screen_frame_counter = FrameCounter;
+ ScreenMovDir = player->MovDir;
+ ScreenMovPos = player->MovPos;
+ ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize);
+ return;
+ }
+ else if (!FrameReached(&screen_frame_counter, 1))
+ return;
+
+ if (ScreenMovPos)
+ {
+ ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * ScrollStepSize;
+ ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize);
+ redraw_mask |= REDRAW_FIELD;
+ }
+ else
+ ScreenMovDir = MV_NO_MOVING;
+}
+
+void TestIfPlayerTouchesCustomElement(int x, int y)
+{
+#if 0
+ static boolean check_changing = FALSE;
+#endif
+ static int xy[4][2] =
+ {
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
+ static int change_sides[4][2] =
+ {
+ /* center side border side */
+ { CH_SIDE_TOP, CH_SIDE_BOTTOM }, /* check top */
+ { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* check left */
+ { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* check right */
+ { CH_SIDE_BOTTOM, CH_SIDE_TOP } /* check bottom */
+ };
+ int i;
+
+#if 0
+ if (check_changing) /* prevent this function from running into a loop */
+ return;
+
+ check_changing = TRUE;
+#endif
+
+ for (i=0; i<4; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int center_side = change_sides[i][0];
+ int border_side = change_sides[i][1];
+
+ if (!IN_LEV_FIELD(xx, yy))
+ continue;
+
+#if 1
+ if (IS_PLAYER(x, y))
+ {
+ CheckTriggeredElementSideChange(xx, yy, Feld[xx][yy], border_side,
+ CE_OTHER_GETS_TOUCHED);
+ CheckElementSideChange(xx, yy, Feld[xx][yy], border_side,
+ CE_TOUCHED_BY_PLAYER, -1);
+ }
+ else if (IS_PLAYER(xx, yy))
+ {
+ CheckTriggeredElementSideChange(x, y, Feld[x][y], center_side,
+ CE_OTHER_GETS_TOUCHED);
+ CheckElementSideChange(x, y, Feld[x][y], center_side,
+ CE_TOUCHED_BY_PLAYER, -1);
+
+ break;
+ }
+#else
+ if (IS_PLAYER(x, y))
+ {
+ CheckTriggeredElementChange(xx, yy, Feld[xx][yy], CE_OTHER_GETS_TOUCHED);
+ CheckElementChange(xx, yy, Feld[xx][yy], CE_TOUCHED_BY_PLAYER);
+ }
+ else if (IS_PLAYER(xx, yy))
+ {
+ CheckTriggeredElementChange(x, y, Feld[x][y], CE_OTHER_GETS_TOUCHED);
+ CheckElementChange(x, y, Feld[x][y], CE_TOUCHED_BY_PLAYER);
+
+ break;
+ }
+#endif
+ }
+
+#if 0
+ check_changing = FALSE;
+#endif
+}
+
+void TestIfElementTouchesCustomElement(int x, int y)
+{
+#if 0
+ static boolean check_changing = FALSE;
+#endif
+ static int xy[4][2] =