Skip to content

Commit

Permalink
convert timings (it compiles)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nertsal committed Oct 23, 2024
1 parent d9edd2c commit 3e3ebc9
Show file tree
Hide file tree
Showing 34 changed files with 313 additions and 262 deletions.
4 changes: 2 additions & 2 deletions crates/ctl-core/src/legacy/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ fn convert_level(beat_time: crate::FloatTime, value: Level) -> crate::Level {
.events
.into_iter()
.map(|event| crate::TimedEvent {
beat: convert_time(beat_time, event.beat),
time: convert_time(beat_time, event.beat),
event: match event.event {
Event::Light(light) => crate::Event::Light(crate::LightEvent {
light: crate::LightSerde {
Expand Down Expand Up @@ -245,5 +245,5 @@ fn convert_frame(beat_time: crate::FloatTime, value: MoveFrame) -> crate::MoveFr
}

fn convert_time(beat_time: crate::FloatTime, time: crate::FloatTime) -> crate::Time {
crate::convert_time(beat_time * time)
crate::seconds_to_time(beat_time * time)
}
10 changes: 5 additions & 5 deletions crates/ctl-core/src/model/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct Level {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TimedEvent {
/// The beat on which the event should happen.
pub beat: Time,
pub time: Time,
pub event: Event,
}

Expand Down Expand Up @@ -40,7 +40,7 @@ pub struct LightEvent {

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Telegraph {
/// How long (in beats) before the event should the telegraph occur.
/// How long (in milliseconds) before the event should the telegraph occur.
pub precede_time: Time,
/// How fast the telegraph is.
pub speed: Coord,
Expand All @@ -51,11 +51,11 @@ impl Level {
Self { events: Vec::new() }
}

/// Calculate the last beat when anything happens.
pub fn last_beat(&self) -> Time {
/// Calculate the last time when anything happens.
pub fn last_time(&self) -> Time {
self.events
.iter()
.map(|event| event.beat + event.duration())
.map(|event| event.time + event.duration())
.max()
.unwrap_or(Time::ZERO)
}
Expand Down
8 changes: 4 additions & 4 deletions crates/ctl-core/src/model/movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use super::*;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Movement {
/// Time (in beats) to spend fading into the initial position.
/// Time (in milliseconds) to spend fading into the initial position.
pub fade_in: Time,
/// Time (in beats) to spend fading out of the last keyframe.
/// Time (in milliseconds) to spend fading out of the last keyframe.
pub fade_out: Time,
pub initial: Transform,
#[serde(default)]
Expand Down Expand Up @@ -126,9 +126,9 @@ impl Interpolatable for Transform {
}

impl MoveFrame {
pub fn scale(lerp_time: Time, scale: impl Float) -> Self {
pub fn scale(lerp_time: impl Float, scale: impl Float) -> Self {
Self {
lerp_time,
lerp_time: seconds_to_time(FloatTime::new(lerp_time.as_f32())),
interpolation: MoveInterpolation::default(),
change_curve: None,
transform: Transform::scale(scale),
Expand Down
47 changes: 38 additions & 9 deletions crates/ctl-core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,50 @@ pub type Name = Arc<str>;
/// 1000 means that each time unit is a millisecond.
pub const TIME_IN_FLOAT_TIME: Time = 1000;

pub fn convert_time(time: FloatTime) -> Time {
pub fn seconds_to_time(time: FloatTime) -> Time {
(time.as_f32() / TIME_IN_FLOAT_TIME as f32).round() as Time
}

pub fn time_to_seconds(time: Time) -> FloatTime {
FloatTime::new(time as f32 * TIME_IN_FLOAT_TIME as f32)
}

#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BeatTime {
/// 1 unit is 1/16 of a beat (typically a 1/64th note).
units: Time,
}

impl BeatTime {
const UNITS_PER_BEAT: Time = 16;
/// A whole beat (typically a 1/4th note)
pub const WHOLE: Self = Self {
units: Self::UNITS_PER_BEAT,
};
/// A half beat (typically a 1/8th note)
pub const HALF: Self = Self {
units: Self::UNITS_PER_BEAT / 2,
};
/// A quarter beat (typically a 1/16th note)
pub const QUARTER: Self = Self {
units: Self::UNITS_PER_BEAT / 4,
};
/// An eighth beat (typically a 1/32th note)
pub const EIGHTH: Self = Self {
units: Self::UNITS_PER_BEAT / 8,
};

/// From whole beats.
pub fn from_beats(beats: Time) -> Self {
Self { units: beats * 64 }
Self {
units: beats * Self::UNITS_PER_BEAT,
}
}

/// From quarter beats.
pub fn from_4ths(quarters: Time) -> Self {
Self {
units: quarters * 16,
units: quarters * (Self::UNITS_PER_BEAT / 4),
}
}

Expand All @@ -39,7 +63,17 @@ impl BeatTime {
}

pub fn as_millis(&self, beat_time: Time) -> Time {
self.units * beat_time / 16
self.units * beat_time / Self::UNITS_PER_BEAT
}
}

impl Mul<Time> for BeatTime {
type Output = Self;

fn mul(self, rhs: Time) -> Self::Output {
Self {
units: self.units * rhs,
}
}
}

Expand Down Expand Up @@ -119,11 +153,6 @@ impl GroupInfo {
}

impl MusicInfo {
/// Returns the duration (in seconds) of a single beat.
pub fn beat_time(&self) -> FloatTime {
r32(60.0) / self.bpm
}

/// Return the list of authors in a readable string format.
pub fn authors(&self) -> String {
let authors = self.authors.iter().map(|author| author.name.as_ref());
Expand Down
2 changes: 1 addition & 1 deletion crates/ctl-server/src/server/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ fn validate_group(group: &LevelSet<LevelFull>) -> Result<()> {
for level in &group.levels {
// TODO: check realtime
// but i think the format will change to use realtime inside the level
let duration = level.data.last_beat();
let duration = level.data.last_time();
if duration < LEVEL_MIN_DURATION * ctl_core::types::TIME_IN_FLOAT_TIME {
return Err(RequestError::LevelTooSmall);
}
Expand Down
34 changes: 19 additions & 15 deletions src/editor/action/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ pub enum LevelAction {
SelectLight(LightId),
DeselectLight,
ToggleDanger(LightId),
ChangeFadeOut(LightId, Time),
ChangeFadeIn(LightId, Time),
ChangeFadeOut(LightId, Change<Time>),
ChangeFadeIn(LightId, Change<Time>),
MoveLight(LightId, Change<Time>, Change<vec2<Coord>>),

// Waypoint actions
Expand All @@ -46,10 +46,10 @@ pub enum Change<T> {
}

impl<T: Sub<Output = T>> Change<T> {
pub fn into_delta(self, reference_value: T) -> Self {
pub fn into_delta(self, reference_value: T) -> T {
match self {
Change::Add(_) => self,
Change::Set(target_value) => Change::Add(target_value.sub(reference_value)),
Change::Add(delta) => delta,
Change::Set(target_value) => target_value.sub(reference_value),
}
}
}
Expand Down Expand Up @@ -94,8 +94,8 @@ impl LevelAction {
LevelAction::NewWaypoint => false,
LevelAction::PlaceWaypoint(_) => false,
LevelAction::ScaleWaypoint(_, _, delta) => *delta == Coord::ZERO,
LevelAction::ChangeFadeOut(_, delta) => *delta == 0,
LevelAction::ChangeFadeIn(_, delta) => *delta == 0,
LevelAction::ChangeFadeOut(_, delta) => delta.is_noop(&0),
LevelAction::ChangeFadeIn(_, delta) => delta.is_noop(&0),
LevelAction::DeselectLight => false,
LevelAction::SelectLight(_) => false,
LevelAction::SelectWaypoint(_) => false,
Expand Down Expand Up @@ -187,7 +187,9 @@ impl LevelEditor {
if let Some(event) = self.level.events.get_mut(id.event) {
if let Event::Light(light) = &mut event.event {
let movement = &mut light.light.movement;
movement.change_fade_out(movement.fade_out + change);
let mut value = movement.fade_out;
change.apply(&mut value);
movement.change_fade_out(value);
self.save_state(HistoryLabel::FadeOut(id));
}
}
Expand All @@ -197,8 +199,9 @@ impl LevelEditor {
if let Event::Light(light) = &mut event.event {
let movement = &mut light.light.movement;
let from = movement.fade_in;
let change = change.into_delta(from);
movement.change_fade_in(movement.fade_in + change);
event.beat -= movement.fade_in - from;
event.time -= movement.fade_in - from;
self.save_state(HistoryLabel::FadeIn(id));
}
}
Expand Down Expand Up @@ -256,9 +259,10 @@ impl LevelEditor {
return;
};

change_time.apply(&mut timed_event.beat);
change_time.apply(&mut timed_event.time);

let change_pos = change_pos.into_delta(event.light.movement.initial.translation);
let change_pos =
Change::Add(change_pos.into_delta(event.light.movement.initial.translation));
change_pos.apply(&mut event.light.movement.initial.translation);
for frame in &mut event.light.movement.key_frames {
change_pos.apply(&mut frame.transform.translation);
Expand Down Expand Up @@ -455,7 +459,7 @@ impl LevelEditor {
let beat = start_beat - light.light.movement.fade_in - light.telegraph.precede_time;
let event = commit_light(light.clone());
let event = TimedEvent {
beat,
time: beat,
event: Event::Light(event),
};

Expand Down Expand Up @@ -509,18 +513,18 @@ impl LevelEditor {
let time =
self.current_time - light.light.movement.fade_in - light.telegraph.precede_time;
light.light.movement.key_frames.push_front(MoveFrame {
lerp_time: event.beat - time,
lerp_time: event.time - time,
interpolation,
change_curve,
transform,
});
event.beat = time;
event.time = time;
}
Some(i) => {
// Insert keyframe
let last = light.light.movement.timed_positions().nth(i);
if let Some((_, _, last_time)) = last {
let last_time = event.beat + light.telegraph.precede_time + last_time;
let last_time = event.time + light.telegraph.precede_time + last_time;
let lerp_time = self.current_time - last_time;

light.light.movement.key_frames.insert(
Expand Down
4 changes: 2 additions & 2 deletions src/editor/action/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl EditorState {
delta.min(current)
} else {
-delta.abs().min(
level_editor.level.last_beat() - timeline.visible_scroll() - current,
level_editor.level.last_time() - timeline.visible_scroll() - current,
)
};
timeline.scroll(delta);
Expand Down Expand Up @@ -158,7 +158,7 @@ impl EditorState {
// delta = ((delta * 4.0).round() / 4.0).as_r32();

match waypoint {
WaypointId::Initial => event.beat += delta,
WaypointId::Initial => event.time += delta,
WaypointId::Frame(i) => {
if let Some(frame) = light.light.movement.key_frames.get_mut(i)
{
Expand Down
4 changes: 2 additions & 2 deletions src/editor/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use super::*;
#[load(serde = "ron")]
pub struct EditorConfig {
pub grid: GridConfig,
/// How much of the music to playback when scrolling.
pub playback_duration: Time,
/// How much of the music to playback when scrolling (in seconds).
pub playback_duration: FloatTime,
pub scroll_slow: Time,
pub scroll_normal: Time,
pub scroll_fast: Time,
Expand Down
6 changes: 3 additions & 3 deletions src/editor/handle_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,9 @@ impl EditorState {
let scroll = scroll.as_f32() as Time;
let change = scroll * self.editor.config.scroll_slow;
let action = if shift {
LevelAction::ChangeFadeOut(id, change)
LevelAction::ChangeFadeOut(id, Change::Add(change))
} else {
LevelAction::ChangeFadeIn(id, change)
LevelAction::ChangeFadeIn(id, Change::Add(change))
};
actions.push(action.into());
}
Expand Down Expand Up @@ -367,7 +367,7 @@ impl EditorState {
let target = DragTarget::Light {
double,
light: LightId { event },
initial_time: e.beat,
initial_time: e.time,
initial_translation: light.light.movement.initial.translation,
};
actions.push(EditorStateAction::StartDrag(target));
Expand Down
Loading

0 comments on commit 3e3ebc9

Please sign in to comment.