+ if(xmode == 2) {
+ // our camera is either in leftscrolling, rightscrolling or
+ // nonscrollingmode.
+ //
+ // when suddenly changing directions while scrolling into the other
+ // direction abort scrolling, since tux might be going left/right at a
+ // relatively small part of the map (like when jumping upwards)
+
+ // Find out direction in which the player moves
+ LookaheadMode walkDirection;
+ if (player_delta.x < -CAMERA_EPSILON) walkDirection = LOOKAHEAD_LEFT;
+ else if (player_delta.x > CAMERA_EPSILON) walkDirection = LOOKAHEAD_RIGHT;
+ else if (player->dir == ::LEFT) walkDirection = LOOKAHEAD_LEFT;
+ else walkDirection = LOOKAHEAD_RIGHT;
+
+ float LEFTEND, RIGHTEND;
+ if(config_.sensitive_x > 0) {
+ LEFTEND = SCREEN_WIDTH * config_.sensitive_x;
+ RIGHTEND = SCREEN_WIDTH * (1-config_.sensitive_x);
+ } else {
+ LEFTEND = SCREEN_WIDTH;
+ RIGHTEND = 0;
+ }
+
+ if(lookahead_mode == LOOKAHEAD_NONE) {
+ /* if we're undecided then look if we crossed the left or right
+ * "sensitive" area */
+ if(player_pos.x < cached_translation.x + LEFTEND) {
+ lookahead_mode = LOOKAHEAD_LEFT;
+ } else if(player_pos.x > cached_translation.x + RIGHTEND) {
+ lookahead_mode = LOOKAHEAD_RIGHT;
+ }
+ /* at the ends of a level it's obvious which way we will go */
+ if(player_pos.x < SCREEN_WIDTH*0.5) {
+ lookahead_mode = LOOKAHEAD_RIGHT;
+ } else if(player_pos.x >= sector->get_width() - SCREEN_WIDTH*0.5) {
+ lookahead_mode = LOOKAHEAD_LEFT;
+ }
+
+ changetime = -1;
+ } else if(lookahead_mode != walkDirection) {
+ /* player changed direction while camera was scrolling...
+ * he has to do this for a certain time to add robustness against
+ * sudden changes */
+ if(changetime < 0) {
+ changetime = game_time;
+ } else if(game_time - changetime > config_.dirchange_time) {
+ if(lookahead_mode == LOOKAHEAD_LEFT &&
+ player_pos.x > cached_translation.x + RIGHTEND) {
+ lookahead_mode = LOOKAHEAD_RIGHT;
+ } else if(lookahead_mode == LOOKAHEAD_RIGHT &&
+ player_pos.x < cached_translation.x + LEFTEND) {
+ lookahead_mode = LOOKAHEAD_LEFT;
+ } else {
+ lookahead_mode = LOOKAHEAD_NONE;
+ }
+ }
+ } else {
+ changetime = -1;
+ }
+
+ LEFTEND = SCREEN_WIDTH * config_.edge_x;
+ RIGHTEND = SCREEN_WIDTH * (1-config_.edge_x);
+
+ // calculate our scroll target depending on scroll mode
+ float target_x;
+ if(lookahead_mode == LOOKAHEAD_LEFT)
+ target_x = player_pos.x - RIGHTEND;
+ else if(lookahead_mode == LOOKAHEAD_RIGHT)
+ target_x = player_pos.x - LEFTEND;
+ else
+ target_x = cached_translation.x;
+
+ // that's the distance we would have to travel to reach target_x
+ float delta_x = cached_translation.x - target_x;
+ // the speed we'd need to travel to reach target_x in this frame
+ float speed_x = delta_x / elapsed_time;
+
+ // limit our speed
+ float player_speed_x = player_delta.x / elapsed_time;
+ float maxv = config_.max_speed_x + (fabsf(player_speed_x * config_.dynamic_max_speed_x));
+ speed_x = clamp(speed_x, -maxv, maxv);
+
+ // apply scrolling
+ cached_translation.x -= speed_x * elapsed_time;