draw the background image
This commit is contained in:
parent
09d26a9022
commit
27859bc05a
8 changed files with 77 additions and 9 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -830,6 +830,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bass-sys",
|
"bass-sys",
|
||||||
"ggez",
|
"ggez",
|
||||||
|
"image",
|
||||||
"libosu",
|
"libosu",
|
||||||
"log",
|
"log",
|
||||||
"num",
|
"num",
|
||||||
|
@ -1282,10 +1283,12 @@ dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"color_quant",
|
"color_quant",
|
||||||
"gif",
|
"gif",
|
||||||
|
"jpeg-decoder",
|
||||||
"num-iter",
|
"num-iter",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"png",
|
"png",
|
||||||
|
"scoped_threadpool",
|
||||||
"tiff",
|
"tiff",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1364,6 +1367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cc797adac5f083b8ff0ca6f6294a999393d76e197c36488e2ef732c4715f6fa3"
|
checksum = "cc797adac5f083b8ff0ca6f6294a999393d76e197c36488e2ef732c4715f6fa3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2505,6 +2509,12 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped_threadpool"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
|
|
@ -22,6 +22,7 @@ stderrlog = "0.5.1"
|
||||||
num = "0.3.1"
|
num = "0.3.1"
|
||||||
ordered-float = "2.0.1"
|
ordered-float = "2.0.1"
|
||||||
structopt = "0.3.21"
|
structopt = "0.3.21"
|
||||||
|
image = "0.23.12"
|
||||||
|
|
||||||
[dependencies.libosu]
|
[dependencies.libosu]
|
||||||
git = "https://github.com/iptq/libosu"
|
git = "https://github.com/iptq/libosu"
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ggez::Context;
|
use ggez::{
|
||||||
|
graphics::{self, Color, DrawParam},
|
||||||
|
Context,
|
||||||
|
};
|
||||||
|
|
||||||
use super::Game;
|
use super::Game;
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
pub(super) fn draw_background(&self, ctx: &mut Context) -> Result<()> {
|
pub(super) fn draw_background(&self, ctx: &mut Context) -> Result<()> {
|
||||||
|
if let Some(image) = &self.background_image {
|
||||||
|
let dim = Color::new(1.0, 1.0, 1.0, 0.35);
|
||||||
|
graphics::draw(ctx, image, DrawParam::default().color(dim))?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,11 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ggez::{
|
use ggez::{
|
||||||
event::{EventHandler, KeyCode, KeyMods},
|
event::{EventHandler, KeyCode, KeyMods, MouseButton},
|
||||||
graphics::{self, Color, DrawParam, FilterMode, Rect, Text, WHITE},
|
graphics::{self, Color, DrawParam, FilterMode, Image, Rect, Text, WHITE},
|
||||||
Context, GameError, GameResult,
|
Context, GameError, GameResult,
|
||||||
};
|
};
|
||||||
|
use image::io::Reader as ImageReader;
|
||||||
use libosu::{
|
use libosu::{
|
||||||
beatmap::Beatmap,
|
beatmap::Beatmap,
|
||||||
hitobject::{HitObjectKind, SpinnerInfo},
|
hitobject::{HitObjectKind, SpinnerInfo},
|
||||||
|
@ -28,6 +29,7 @@ use crate::audio::{AudioEngine, Sound};
|
||||||
use crate::beatmap::{BeatmapExt, STACK_DISTANCE};
|
use crate::beatmap::{BeatmapExt, STACK_DISTANCE};
|
||||||
use crate::hitobject::HitObjectExt;
|
use crate::hitobject::HitObjectExt;
|
||||||
use crate::skin::Skin;
|
use crate::skin::Skin;
|
||||||
|
use crate::utils;
|
||||||
|
|
||||||
pub const PLAYFIELD_BOUNDS: Rect = Rect::new(112.0, 122.0, 800.0, 600.0);
|
pub const PLAYFIELD_BOUNDS: Rect = Rect::new(112.0, 122.0, 800.0, 600.0);
|
||||||
pub const DEFAULT_COLORS: &[(f32, f32, f32)] = &[
|
pub const DEFAULT_COLORS: &[(f32, f32, f32)] = &[
|
||||||
|
@ -48,6 +50,7 @@ pub struct Game {
|
||||||
frame: usize,
|
frame: usize,
|
||||||
slider_cache: SliderCache,
|
slider_cache: SliderCache,
|
||||||
combo_colors: Vec<Color>,
|
combo_colors: Vec<Color>,
|
||||||
|
background_image: Option<Image>,
|
||||||
|
|
||||||
keymap: HashSet<KeyCode>,
|
keymap: HashSet<KeyCode>,
|
||||||
current_uninherited_timing_point: Option<TimingPoint>,
|
current_uninherited_timing_point: Option<TimingPoint>,
|
||||||
|
@ -74,6 +77,7 @@ impl Game {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(r, g, b)| Color::new(*r, *g, *b, 1.0))
|
.map(|(r, g, b)| Color::new(*r, *g, *b, 1.0))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
background_image: None,
|
||||||
|
|
||||||
keymap: HashSet::new(),
|
keymap: HashSet::new(),
|
||||||
current_uninherited_timing_point: None,
|
current_uninherited_timing_point: None,
|
||||||
|
@ -81,7 +85,7 @@ impl Game {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_beatmap(&mut self, path: impl AsRef<Path>) -> Result<()> {
|
pub fn load_beatmap(&mut self, ctx: &mut Context, path: impl AsRef<Path>) -> Result<()> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
|
|
||||||
let mut file = File::open(&path)?;
|
let mut file = File::open(&path)?;
|
||||||
|
@ -118,6 +122,25 @@ impl Game {
|
||||||
|
|
||||||
let dir = path.parent().unwrap();
|
let dir = path.parent().unwrap();
|
||||||
|
|
||||||
|
// TODO: more background images possible?
|
||||||
|
for evt in self.beatmap.inner.events.iter() {
|
||||||
|
use libosu::events::Event;
|
||||||
|
if let Event::Background(evt) = evt {
|
||||||
|
let path = utils::fuck_you_windows(dir, &evt.filename)?;
|
||||||
|
if let Some(path) = path {
|
||||||
|
let img = ImageReader::open(path)?.decode()?;
|
||||||
|
let img_buf = img.into_rgba8();
|
||||||
|
let image = Image::from_rgba8(
|
||||||
|
ctx,
|
||||||
|
img_buf.width() as u16,
|
||||||
|
img_buf.height() as u16,
|
||||||
|
img_buf.as_raw(),
|
||||||
|
)?;
|
||||||
|
self.background_image = Some(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let song = Sound::create(dir.join(&self.beatmap.inner.audio_filename))?;
|
let song = Sound::create(dir.join(&self.beatmap.inner.audio_filename))?;
|
||||||
self.song = Some(song);
|
self.song = Some(song);
|
||||||
self.timestamp_changed()?;
|
self.timestamp_changed()?;
|
||||||
|
@ -395,6 +418,8 @@ impl EventHandler for Game {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mouse_button_down_event(&mut self, ctx: &mut Context, _: MouseButton, x: f32, y: f32) {}
|
||||||
|
|
||||||
fn key_up_event(&mut self, _: &mut Context, keycode: KeyCode, _: KeyMods) {
|
fn key_up_event(&mut self, _: &mut Context, keycode: KeyCode, _: KeyMods) {
|
||||||
use KeyCode::*;
|
use KeyCode::*;
|
||||||
match keycode {
|
match keycode {
|
||||||
|
|
|
@ -189,7 +189,10 @@ impl Game {
|
||||||
.with_line_width(BOUNDS.h)
|
.with_line_width(BOUNDS.h)
|
||||||
.with_line_cap(LineCap::Round),
|
.with_line_cap(LineCap::Round),
|
||||||
),
|
),
|
||||||
&[Point2::from([head_x, body_y]), Point2::from([tail_x, body_y])],
|
&[
|
||||||
|
Point2::from([head_x, body_y]),
|
||||||
|
Point2::from([tail_x, body_y]),
|
||||||
|
],
|
||||||
color,
|
color,
|
||||||
)?;
|
)?;
|
||||||
graphics::draw(ctx, &body, DrawParam::default())?;
|
graphics::draw(ctx, &body, DrawParam::default())?;
|
||||||
|
|
|
@ -12,6 +12,7 @@ mod beatmap;
|
||||||
mod game;
|
mod game;
|
||||||
mod hitobject;
|
mod hitobject;
|
||||||
mod skin;
|
mod skin;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ fn main() -> Result<()> {
|
||||||
game.skin.load_all(&mut ctx)?;
|
game.skin.load_all(&mut ctx)?;
|
||||||
|
|
||||||
if let Some(path) = opt.path {
|
if let Some(path) = opt.path {
|
||||||
game.load_beatmap(path)?;
|
game.load_beatmap(&mut ctx, path)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(start_time) = opt.start_time {
|
if let Some(start_time) = opt.start_time {
|
||||||
|
|
|
@ -92,9 +92,7 @@ impl Texture {
|
||||||
graphics::draw(
|
graphics::draw(
|
||||||
ctx,
|
ctx,
|
||||||
image,
|
image,
|
||||||
param
|
param.scale([x_scale, y_scale]).offset([0.5, 0.5]),
|
||||||
.scale([x_scale, y_scale])
|
|
||||||
.offset([0.5, 0.5]),
|
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
22
src/utils.rs
Normal file
22
src/utils.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
pub fn fuck_you_windows(
|
||||||
|
parent: impl AsRef<Path>,
|
||||||
|
name: impl AsRef<str>,
|
||||||
|
) -> Result<Option<PathBuf>> {
|
||||||
|
let parent = parent.as_ref();
|
||||||
|
let name = name.as_ref();
|
||||||
|
|
||||||
|
let name_lower = name.to_ascii_lowercase();
|
||||||
|
for entry in parent.read_dir()? {
|
||||||
|
let entry = entry?;
|
||||||
|
let entry_lower = entry.file_name().to_str().unwrap().to_ascii_lowercase();
|
||||||
|
if name_lower == entry_lower {
|
||||||
|
return Ok(Some(entry.path()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue