notch hell
This commit is contained in:
parent
7914d2bafb
commit
e0875cd09e
6 changed files with 66 additions and 31 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -19,4 +19,4 @@ num = "0.3.1"
|
|||
|
||||
[dependencies.libosu]
|
||||
git = "https://github.com/iptq/libosu"
|
||||
rev = "5a8501aec0f4f2232507f80a65b8b31be8756414"
|
||||
rev = "95a87c57e1075ffab473124d9564233028e79423"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
52
src/game.rs
52
src/game.rs
|
@ -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(())
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue