notch hell

This commit is contained in:
Michael Zhang 2021-01-08 02:41:33 -06:00
parent 7914d2bafb
commit e0875cd09e
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
6 changed files with 66 additions and 31 deletions

2
Cargo.lock generated
View file

@ -1132,7 +1132,7 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]]
name = "libosu"
version = "0.0.12"
source = "git+https://github.com/iptq/libosu?rev=5a8501aec0f4f2232507f80a65b8b31be8756414#5a8501aec0f4f2232507f80a65b8b31be8756414"
source = "git+https://github.com/iptq/libosu?rev=95a87c57e1075ffab473124d9564233028e79423#95a87c57e1075ffab473124d9564233028e79423"
dependencies = [
"anyhow",
"bitflags",

View file

@ -19,4 +19,4 @@ num = "0.3.1"
[dependencies.libosu]
git = "https://github.com/iptq/libosu"
rev = "5a8501aec0f4f2232507f80a65b8b31be8756414"
rev = "95a87c57e1075ffab473124d9564233028e79423"

View file

@ -17,7 +17,9 @@ extern_log! {
pub fn BASS_ChannelPause(handle: DWORD) -> BOOL;
pub fn BASS_ChannelGetLength(handle: DWORD, mode: DWORD) -> QWORD;
pub fn BASS_ChannelGetPosition(handle: DWORD, mode: DWORD) -> QWORD;
pub fn BASS_ChannelSetPosition(handle: DWORD, pos: QWORD, mode: DWORD);
pub fn BASS_ChannelBytes2Seconds(handle: DWORD, pos: QWORD) -> f64;
pub fn BASS_ChannelSeconds2Bytes(handle: DWORD, pos: f64) -> QWORD;
pub fn BASS_GetDevice() -> DWORD;
pub fn BASS_GetDeviceInfo(device: DWORD, info: *mut BASS_DEVICEINFO) -> BOOL;

View file

@ -76,4 +76,12 @@ impl Sound {
};
Ok(time)
}
pub fn set_position(&self, pos: f64) -> Result<()> {
unsafe {
let pos_bytes = bass::BASS_ChannelSeconds2Bytes(self.handle, pos);
bass::BASS_ChannelSetPosition(self.handle, pos_bytes, BASS_POS_BYTE);
}
Ok(())
}
}

View file

@ -48,7 +48,10 @@ impl Game {
self.beatmap = Beatmap::from_osz(&contents)?;
let dir = path.parent().unwrap();
self.song = Sound::create(dir.join(&self.beatmap.audio_filename)).map(Some)?;
let song = Sound::create(dir.join(&self.beatmap.audio_filename))?;
song.set_position(113.0)?;
self.song = Some(song);
Ok(())
}
@ -82,20 +85,40 @@ impl Game {
graphics::queue_text(ctx, &text, [0.0, 0.0], Some(WHITE));
graphics::draw_queued_text(ctx, DrawParam::default(), None, FilterMode::Linear)?;
struct DrawInfo<'a> {
hit_object: &'a HitObject,
opacity: f64,
end_time: f64,
}
let mut visible_hitobjects = Vec::new();
let approach_time = 0.75;
let preempt = (self.beatmap.difficulty.approach_preempt() as f64) / 1000.0;
let fade_in = (self.beatmap.difficulty.approach_fade_time() as f64) / 1000.0;
for ho in self.beatmap.hit_objects.iter() {
let ho_time = (ho.start_time.0 as f64) / 1000.0;
let end_time = match ho.kind {
HitObjectKind::Circle => ho_time,
let end_time;
let opacity = if time > ho_time - fade_in {
1.0
} else {
// TODO: calculate ease
(time - (ho_time - preempt)) / fade_in
};
match ho.kind {
HitObjectKind::Circle => end_time = ho_time,
HitObjectKind::Slider(_) => {
let duration = self.beatmap.get_slider_duration(ho).unwrap();
ho_time + duration / 1000.0
end_time = ho_time + duration / 1000.0;
}
HitObjectKind::Spinner(SpinnerInfo { end_time }) => (end_time.0 as f64) / 1000.0,
HitObjectKind::Spinner(SpinnerInfo {
end_time: spinner_end,
}) => end_time = (spinner_end.0 as f64) / 1000.0,
};
if ho_time - approach_time < time && time < end_time {
visible_hitobjects.push(ho);
if ho_time - preempt < time && time < end_time {
visible_hitobjects.push(DrawInfo {
hit_object: ho,
opacity,
end_time,
});
}
}
@ -104,15 +127,18 @@ impl Game {
let cs_osupx = self.beatmap.difficulty.circle_size_osupx();
let cs_real = cs_osupx * osupx_scale_x;
for ho in visible_hitobjects.iter() {
for draw_info in visible_hitobjects.iter() {
let ho = draw_info.hit_object;
let ho_time = (ho.start_time.0 as f64) / 1000.0;
let pos = [
EDITOR_SCREEN.x + osupx_scale_x * ho.pos.0 as f32,
EDITOR_SCREEN.y + osupx_scale_y * ho.pos.1 as f32,
];
let color = graphics::Color::new(1.0, 1.0, 1.0, draw_info.opacity as f32);
if let HitObjectKind::Slider(_) = ho.kind {
render_slider(ctx, EDITOR_SCREEN, &self.beatmap, ho)?;
let color = graphics::Color::new(1.0, 1.0, 1.0, 0.6 * draw_info.opacity as f32);
render_slider(ctx, EDITOR_SCREEN, &self.beatmap, ho, color)?;
}
let circ = Mesh::new_circle(
@ -121,15 +147,16 @@ impl Game {
pos,
cs_real,
1.0,
WHITE,
color,
)?;
graphics::draw(ctx, &circ, DrawParam::default())?;
if time < ho_time {
let time_diff = ho_time - time;
let approach_r = cs_real * (1.0 + 2.0 * time_diff as f32 / 0.75);
let approach = Mesh::new_circle(
ctx,
DrawMode::Stroke(StrokeOptions::default()),
DrawMode::Stroke(StrokeOptions::default().with_line_width(2.0)),
pos,
approach_r,
1.0,
@ -137,6 +164,7 @@ impl Game {
)?;
graphics::draw(ctx, &approach, DrawParam::default())?;
}
}
graphics::present(ctx)?;
Ok(())

View file

@ -17,6 +17,7 @@ pub fn render_slider(
rect: Rect,
beatmap: &Beatmap,
slider: &HitObject,
color: Color,
) -> Result<()> {
let mut control_points = vec![slider.pos];
let slider_info = match &slider.kind {
@ -62,12 +63,7 @@ pub fn render_slider(
.with_line_cap(LineCap::Round)
.with_line_join(LineJoin::Round)
.with_line_width(cs_real as f32 * 2.0);
let body = Mesh::new_polyline(
ctx,
DrawMode::Stroke(opts),
&spline_mapped,
Color::new(1.0, 1.0, 1.0, 0.5),
)?;
let body = Mesh::new_polyline(ctx, DrawMode::Stroke(opts), &spline_mapped, color)?;
graphics::draw(ctx, &body, DrawParam::default())?;
let frame = Mesh::new_polyline(
@ -153,11 +149,12 @@ fn get_spline(
c
}
SliderSplineKind::Bezier => {
// split the curve by red-anchors
let mut idx = 0;
let mut whole = Vec::new();
for i in 1..points.len() {
if points[i].0 == points[i - 1].0 && points[i].1 == points[i - 1].1 {
let spline = calculate_bezier(&points[idx..i - 1]);
let spline = calculate_bezier(&points[idx..i]);
whole.extend(spline);
idx = i;
continue;