fn calc_pos(
    current_time: f64,
    time: f64,
    chart: &dyn chart::Chart,
    scroll_speed: f64,
    current_timing_point_index: usize,
) -> f64 {
    let mut iterator = chart.timing_points()[current_timing_point_index..]
        .iter()
        .take_while(|tp| tp.offset < time)
        .peekable();

    let mut last_sv_tp: Option<&chart::TimingPoint> = None;
    let mut last_bpm_tp: Option<&chart::TimingPoint> = {
        // it should be the first timing point, but if it's not, the map is still playable
        match chart.timing_points().first() {
            Some(tp) if tp.is_bpm() => Some(tp),
            Some(_) => None,
            None => {
                remani_warn!("Osu chart has no timing points!");
                None
            }
        }
    };
    // get the last timing point before the current time, if one exists.
    while iterator.peek().is_some() {
        if iterator.peek().unwrap().offset < current_time {
            let tp = iterator.next().unwrap();
            if tp.is_sv() {
                last_sv_tp = Some(tp);
            } else {
                last_sv_tp = None;
                last_bpm_tp = Some(tp);
            }
        } else {
            break;
        }
    }

    let mut pos: f64;

    let value = last_bpm_tp
        .map(|t| t.value.inner() / chart.primary_bpm())
        .unwrap_or(1.0)
        * last_sv_tp.map(|t| t.value.inner()).unwrap_or(1.0);

    if let Some(tp) = iterator.peek() {
        pos = (tp.offset - current_time) * value;
    } else {
        return (time - current_time) * value * scroll_speed;
    }

    while let Some(tp) = iterator.next() {
        let value = if tp.is_sv() {
            last_bpm_tp
                .map(|t| t.value.inner() / chart.primary_bpm())
                .unwrap_or(1.0)
                * tp.value.inner()
        } else {
            // bpm timing point
            last_bpm_tp = Some(tp);
            tp.value.inner() / chart.primary_bpm()
        };

        if let Some(ntp) = iterator.peek() {
            pos += (ntp.offset - tp.offset) * value;
        } else {
            // if last
            pos += (time - tp.offset) * value;
            break;
        }
    }
    pos * scroll_speed
}
/// Given the time in seconds from the start of the song, calculate the position, taking into
/// account SV changes. Return value is an f64 between 0.0 and 1.0, 0.0 being at the judgement
/// line, and 1.0 being at the top of the stage.
///
/// Used to calculate note position.
Given the time in seconds from the start of the song, calculate the position, taking into
account SV changes. Return value is an f64 between 0.0 and 1.0, 0.0 being at the judgement
line, and 1.0 being at the top of the stage.

Used to calculate note position.
Given the time in seconds from the start of the song calculate the position taking into account SV changes . Return value is an f64 between 0 . 0 and 1 . 0 0 . 0 being at the judgement line and 1 . 0 being at the top of the stage . Used to calculate note position .
fn calc_pos(
    current_time: f64,
    time: f64,
    chart: &dyn chart::Chart,
    scroll_speed: f64,
    current_timing_point_index: usize,
) -> f64 {
    let mut iterator = chart.timing_points()[current_timing_point_index..]
        .iter()
        .take_while(|tp| tp.offset < time)
        .peekable();
    let mut last_sv_tp: Option<&chart::TimingPoint> = None;
    let mut last_bpm_tp: Option<&chart::TimingPoint> = {
        // it should be the first timing point, but if it's not, the map is still playable
        match chart.timing_points().first() {
            Some(tp) if tp.is_bpm() => Some(tp),
            Some(_) => None,
            None => {
                remani_warn!("Osu chart has no timing points!");
                None
            }
        }
    };
    // get the last timing point before the current time, if one exists.
    while iterator.peek().is_some() {
        if iterator.peek().unwrap().offset < current_time {
            let tp = iterator.next().unwrap();
            if tp.is_sv() {
                last_sv_tp = Some(tp);
            } else {
                last_sv_tp = None;
                last_bpm_tp = Some(tp);
            }
        } else {
            break;
        }
    }
    let mut pos: f64;
    let value = last_bpm_tp
        .map(|t| t.value.inner() / chart.primary_bpm())
        .unwrap_or(1.0)
        * last_sv_tp.map(|t| t.value.inner()).unwrap_or(1.0);
    if let Some(tp) = iterator.peek() {
        pos = (tp.offset - current_time) * value;
    } else {
        return (time - current_time) * value * scroll_speed;
    }
    while let Some(tp) = iterator.next() {
        let value = if tp.is_sv() {
            last_bpm_tp
                .map(|t| t.value.inner() / chart.primary_bpm())
                .unwrap_or(1.0)
                * tp.value.inner()
        } else {
            // bpm timing point
            last_bpm_tp = Some(tp);
            tp.value.inner() / chart.primary_bpm()
        };
        if let Some(ntp) = iterator.peek() {
            pos += (ntp.offset - tp.offset) * value;
        } else {
            // if last
            pos += (time - tp.offset) * value;
            break;
        }
    }
    pos * scroll_speed
}
fn calc_pos ( current_time : f64 , time : f64 , chart : & dyn chart :: Chart , scroll_speed : f64 , current_timing_point_index : usize , ) -> f64 { let mut iterator = chart . timing_points ( ) [ current_timing_point_index .. ] . iter ( ) . take_while ( | tp | tp . offset < time ) . peekable ( ) ; let mut last_sv_tp : Option < & chart :: TimingPoint > = None ; let mut last_bpm_tp : Option < & chart :: TimingPoint > = { // it should be the first timing point, but if it's not, the map is still playable match chart . timing_points ( ) . first ( ) { Some ( tp ) if tp . is_bpm ( ) => Some ( tp ) , Some ( _ ) => None , None => { remani_warn ! ( " " ) ; None } } } ; // get the last timing point before the current time, if one exists. while iterator . peek ( ) . is_some ( ) { if iterator . peek ( ) . unwrap ( ) . offset < current_time { let tp = iterator . next ( ) . unwrap ( ) ; if tp . is_sv ( ) { last_sv_tp = Some ( tp ) ; } else { last_sv_tp = None ; last_bpm_tp = Some ( tp ) ; } } else { break ; } } let mut pos : f64 ; let value = last_bpm_tp . map ( | t | t . value . inner ( ) / chart . primary_bpm ( ) ) . unwrap_or ( 1.0 ) * last_sv_tp . map ( | t | t . value . inner ( ) ) . unwrap_or ( 1.0 ) ; if let Some ( tp ) = iterator . peek ( ) { pos = ( tp . offset - current_time ) * value ; } else { return ( time - current_time ) * value * scroll_speed ; } while let Some ( tp ) = iterator . next ( ) { let value = if tp . is_sv ( ) { last_bpm_tp . map ( | t | t . value . inner ( ) / chart . primary_bpm ( ) ) . unwrap_or ( 1.0 ) * tp . value . inner ( ) } else { // bpm timing point last_bpm_tp = Some ( tp ) ; tp . value . inner ( ) / chart . primary_bpm ( ) } ; if let Some ( ntp ) = iterator . peek ( ) { pos += ( ntp . offset - tp . offset ) * value ; } else { // if last pos += ( time - tp . offset ) * value ; break ; } } pos * scroll_speed }
Given the time in seconds from the start of the song, calculate the position, taking into
account SV changes.
Given the time in seconds from the start of the song calculate the position taking into account SV changes .
current_time
f64
time
f64
chart
&dyn chart::Chart
scroll_speed
f64
current_timing_point_index
usize
current_time
f64
time
f64
chart
&dyn chart::Chart
scroll_speed
f64
current_timing_point_index
usize