Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPE 1.5.0 update #373

Merged
merged 21 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ inner.rs

# Test

/test
/log*
/build_event_debug.sh
24 changes: 19 additions & 5 deletions phira/src/scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,7 @@ pub fn load_tos_and_policy() {
let mut guard = LOAD_TOS_TASK.lock().unwrap();
if guard.is_none() {
let modified = get_data().terms_modified.clone();
*guard = Some(Task::new(async move {
Client::fetch_terms(modified.as_deref())
.await
.context("failed to fetch terms")
}));
*guard = Some(Task::new(async move { Client::fetch_terms(modified.as_deref()).await.context("failed to fetch terms") }));
}
}

Expand Down Expand Up @@ -357,3 +353,21 @@ pub fn render_release_to_refresh(ui: &mut Ui, cx: f32, off: f32) {
.color(semi_white(p * 0.8))
.draw();
}

#[cfg(test)]
mod tests {
use std::ops::DerefMut;

use fs::load_info;

use super::*;

#[tokio::test]
async fn test_parse_chart() -> Result<()> {
// Put the chart in phira(workspace, not crate)/test which is ignored by git
let mut fs = fs_from_path("../../../test")?;
let info = load_info(fs.as_mut()).await?;
let _chart = prpr::scene::GameScene::load_chart(fs.deref_mut(), &info).await?;
Ok(())
}
}
3 changes: 3 additions & 0 deletions prpr/locales/en-US/parser.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ incline-events-parse-failed = Failed to parse incline events
paint-events-parse-failed = Failed to parse paint events
text-events-parse-failed = Failed to parse text events
color-events-parse-failed = Failed to parse color events
gif-events-parse-failed = Failed to parse gif events

illustration-load-failed = Failed to load illustration at { $path }
gif-load-failed = Failed to load gif at { $path }

judge-line-location-name = In judge line #{ $jlid } ({ $name })
hitsound-missing = Hitsound `{ $name }` is missing

# pgr
event-not-contiguous = Events should be contiguous
Expand Down
3 changes: 3 additions & 0 deletions prpr/locales/zh-CN/parser.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ incline-events-parse-failed = incline 事件解析失败
paint-events-parse-failed = paint 事件解析失败
text-events-parse-failed = text 事件解析失败
color-events-parse-failed = color 事件解析失败
gif-events-parse-failed = gif 事件解析失败

illustration-load-failed = 位于 { $path } 的插图加载失败
gif-load-failed = 位于 { $path } 的 gif 加载失败

judge-line-location-name = #{ $jlid } ({ $name }) 判定线中
hitsound-missing = 缺少打击音 `{ $name }`

# pgr
event-not-contiguous = 事件应当连续
Expand Down
35 changes: 22 additions & 13 deletions prpr/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ use crate::{
Anim, AnimVector, BezierTween, BpmList, Chart, ChartExtra, ChartSettings, ClampedTween, CtrlObject, JudgeLine, JudgeLineCache, JudgeLineKind,
Keyframe, Note, NoteKind, Object, StaticTween, Tweenable, UIElement,
},
judge::JudgeStatus,
judge::{HitSound, JudgeStatus},
parse::process_lines,
};
use anyhow::{bail, Result};
use byteorder::{LittleEndian as LE, ReadBytesExt, WriteBytesExt};
use macroquad::{prelude::Color, texture::Texture2D};
use std::{
cell::RefCell,
collections::HashMap,
io::{Read, Write},
ops::Deref,
rc::Rc,
Expand Down Expand Up @@ -315,18 +316,22 @@ impl BinaryData for CtrlObject {

impl BinaryData for Note {
fn read_binary<R: Read>(r: &mut BinaryReader<R>) -> Result<Self> {
Ok(Self {
object: r.read()?,
kind: match r.read::<u8>()? {
0 => NoteKind::Click,
1 => NoteKind::Hold {
end_time: r.read()?,
end_height: r.read()?,
},
2 => NoteKind::Flick,
3 => NoteKind::Drag,
_ => bail!("invalid note kind"),
let object = r.read()?;
let kind = match r.read::<u8>()? {
0 => NoteKind::Click,
1 => NoteKind::Hold {
end_time: r.read()?,
end_height: r.read()?,
},
2 => NoteKind::Flick,
3 => NoteKind::Drag,
_ => bail!("invalid note kind"),
};
let hitsound = HitSound::default_from_kind(&kind);
Ok(Self {
object,
kind,
hitsound,
time: r.time()?,
height: r.read()?,
speed: if r.read()? { r.read::<f32>()? } else { 1. },
Expand Down Expand Up @@ -374,6 +379,7 @@ impl BinaryData for JudgeLine {
1 => JudgeLineKind::Texture(Texture2D::empty().into(), r.read()?),
2 => JudgeLineKind::Text(r.read()?),
3 => JudgeLineKind::Paint(r.read()?, RefCell::default()),
4 => unimplemented!(),
_ => bail!("invalid judge line kind"),
};
let height = r.read()?;
Expand Down Expand Up @@ -423,6 +429,9 @@ impl BinaryData for JudgeLine {
w.write_val(3_u8)?;
w.write(events)?;
}
JudgeLineKind::TextureGif(..) => {
bail!("gif texture binary not supported");
}
}
w.write(&self.height)?;
w.array(&self.notes)?;
Expand Down Expand Up @@ -461,7 +470,7 @@ impl BinaryData for Chart {
let mut lines = r.array()?;
process_lines(&mut lines);
let settings = r.read()?;
Ok(Chart::new(offset, lines, BpmList::new(vec![(0., 60.)]), settings, ChartExtra::default()))
Ok(Chart::new(offset, lines, BpmList::new(vec![(0., 60.)]), settings, ChartExtra::default(), HashMap::new()))
}

fn write_binary<W: Write>(&self, w: &mut BinaryWriter<W>) -> Result<()> {
Expand Down
8 changes: 4 additions & 4 deletions prpr/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ mod anim;
pub use anim::{Anim, AnimFloat, AnimVector, Keyframe};

mod chart;
pub use chart::{Chart, ChartExtra, ChartSettings};
pub use chart::{Chart, ChartExtra, ChartSettings, HitSoundMap};

mod effect;
pub use effect::{Effect, Uniform};

mod line;
pub use line::{JudgeLine, JudgeLineCache, JudgeLineKind, UIElement};
pub use line::{GifFrames, JudgeLine, JudgeLineCache, JudgeLineKind, UIElement};

mod note;
use macroquad::prelude::set_pc_assets_folder;
pub use note::{BadNote, Note, NoteKind, RenderConfig};
pub use note::{BadNote, HitSound, Note, NoteKind, RenderConfig};

mod object;
pub use object::{CtrlObject, Object};
Expand All @@ -44,7 +44,7 @@ mod render;
pub use render::{copy_fbo, internal_id, MSRenderTarget};

mod resource;
pub use resource::{NoteStyle, ParticleEmitter, ResPackInfo, Resource, ResourcePack, DPI_VALUE};
pub use resource::{NoteStyle, ParticleEmitter, ResPackInfo, Resource, ResourcePack, BUFFER_SIZE, DPI_VALUE};

mod smooth;
pub use smooth::Smooth;
Expand Down
11 changes: 9 additions & 2 deletions prpr/src/core/chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use super::{BpmList, Effect, JudgeLine, JudgeLineKind, Matrix, Resource, UIEleme
use crate::{fs::FileSystem, judge::JudgeStatus, ui::Ui};
use anyhow::{Context, Result};
use macroquad::prelude::*;
use std::cell::RefCell;
use sasa::AudioClip;
use std::{cell::RefCell, collections::HashMap};
use tracing::warn;

#[derive(Default)]
Expand All @@ -19,6 +20,8 @@ pub struct ChartSettings {
pub hold_partial_cover: bool,
}

pub type HitSoundMap = HashMap<String, AudioClip>;

pub struct Chart {
pub offset: f32,
pub lines: Vec<JudgeLine>,
Expand All @@ -33,10 +36,12 @@ pub struct Chart {
pub order: Vec<usize>,
/// TODO: docs from RPE
pub attach_ui: [Option<usize>; 7],

pub hitsounds: HitSoundMap,
}

impl Chart {
pub fn new(offset: f32, lines: Vec<JudgeLine>, bpm_list: BpmList, settings: ChartSettings, extra: ChartExtra) -> Self {
pub fn new(offset: f32, lines: Vec<JudgeLine>, bpm_list: BpmList, settings: ChartSettings, extra: ChartExtra, hitsounds: HitSoundMap) -> Self {
let mut attach_ui = [None; 7];
let mut order = (0..lines.len())
.filter(|it| {
Expand All @@ -58,6 +63,8 @@ impl Chart {

order,
attach_ui,

hitsounds,
}
}

Expand Down
56 changes: 56 additions & 0 deletions prpr/src/core/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,46 @@ impl UIElement {
}
}

pub struct GifFrames {
/// time of each frame in milliseconds
frames: Vec<(u128, SafeTexture)>,
/// milliseconds
total_time: u128,
}

impl GifFrames {
pub fn new(frames: Vec<(u128, SafeTexture)>) -> Self {
let total_time = frames.iter().map(|(time, _)| *time).sum();
Self { frames, total_time }
}

pub fn get_time_frame(&self, time: u128) -> &SafeTexture {
let mut time = time % self.total_time;
for (t, frame) in &self.frames {
if time < *t {
return frame;
}
time -= t;
}
&self.frames.last().unwrap().1
}

pub fn get_prog_frame(&self, prog: f32) -> &SafeTexture {
let time = (prog * self.total_time as f32) as u128;
self.get_time_frame(time)
}

pub fn total_time(&self) -> u128 {
self.total_time
}
}

#[derive(Default)]
pub enum JudgeLineKind {
#[default]
Normal,
Texture(SafeTexture, String),
TextureGif(Anim<f32>, GifFrames, String),
Text(Anim<String>),
Paint(Anim<f32>, RefCell<(Option<RenderPass>, bool)>),
}
Expand Down Expand Up @@ -141,6 +176,9 @@ impl JudgeLine {
JudgeLineKind::Paint(anim, ..) => {
anim.set_time(res.time);
}
JudgeLineKind::TextureGif(anim, ..) => {
anim.set_time(res.time);
}
_ => {}
}
self.color.set_time(res.time);
Expand Down Expand Up @@ -215,6 +253,24 @@ impl JudgeLine {
},
);
}
JudgeLineKind::TextureGif(anim, frames, _) => {
let t = anim.now_opt().unwrap_or(0.0);
let frame = frames.get_prog_frame(t);
let mut color = color.unwrap_or(WHITE);
color.a = alpha.max(0.0);
let hf = vec2(frame.width(), frame.height());
draw_texture_ex(
**frame,
-hf.x / 2.,
-hf.y / 2.,
color,
DrawTextureParams {
dest_size: Some(hf),
flip_y: true,
..Default::default()
},
);
}
JudgeLineKind::Text(anim) => {
let mut color = color.unwrap_or(WHITE);
color.a = alpha.max(0.0);
Expand Down
6 changes: 5 additions & 1 deletion prpr/src/core/note.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use super::{chart::ChartSettings, BpmList, CtrlObject, JudgeLine, Matrix, Object, Point, Resource};
use crate::{judge::JudgeStatus, parse::RPE_HEIGHT};
pub use crate::{
judge::{HitSound, JudgeStatus},
parse::RPE_HEIGHT,
};
use macroquad::prelude::*;

const HOLD_PARTICLE_INTERVAL: f32 = 0.15;
Expand Down Expand Up @@ -28,6 +31,7 @@ impl NoteKind {
pub struct Note {
pub object: Object,
pub kind: NoteKind,
pub hitsound: HitSound,
pub time: f32,
pub height: f32,
pub speed: f32,
Expand Down
20 changes: 18 additions & 2 deletions prpr/src/core/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ use macroquad::prelude::*;
use miniquad::{gl::GLuint, Texture, TextureWrap};
use sasa::{AudioClip, AudioManager, Sfx};
use serde::Deserialize;
use std::{cell::RefCell, collections::BTreeMap, ops::DerefMut, path::Path, sync::atomic::AtomicU32};
use std::{
cell::RefCell,
collections::{BTreeMap, HashMap},
ops::DerefMut,
path::Path,
sync::atomic::AtomicU32,
};

pub const MAX_SIZE: usize = 64; // needs tweaking
pub static DPI_VALUE: AtomicU32 = AtomicU32::new(250);
pub const BUFFER_SIZE: usize = 1024;

#[inline]
fn default_scale() -> f32 {
Expand Down Expand Up @@ -333,6 +340,8 @@ impl NoteBuffer {
}
}

pub type SfxMap = HashMap<String, Sfx>;

pub struct Resource {
pub config: Config,
pub info: ChartInfo,
Expand Down Expand Up @@ -367,6 +376,8 @@ pub struct Resource {
pub sfx_drag: Sfx,
pub sfx_flick: Sfx,

pub extra_sfxs: SfxMap,

pub chart_target: Option<MSRenderTarget>,
pub no_effect: bool,

Expand Down Expand Up @@ -424,7 +435,7 @@ impl Resource {
let mut audio = create_audio_manger(&config)?;
let music = AudioClip::new(fs.load_file(&info.music).await?)?;
let track_length = music.length();
let buffer_size = Some(1024);
let buffer_size = Some(BUFFER_SIZE);
let sfx_click = audio.create_sfx(res_pack.sfx_click.clone(), buffer_size)?;
let sfx_drag = audio.create_sfx(res_pack.sfx_drag.clone(), buffer_size)?;
let sfx_flick = audio.create_sfx(res_pack.sfx_flick.clone(), buffer_size)?;
Expand Down Expand Up @@ -471,6 +482,7 @@ impl Resource {
sfx_click,
sfx_drag,
sfx_flick,
extra_sfxs: SfxMap::new(),

chart_target: None,
no_effect,
Expand All @@ -481,6 +493,10 @@ impl Resource {
})
}

pub fn create_sfx(&mut self, clip: AudioClip) -> Result<Sfx> {
self.audio.create_sfx(clip, Some(BUFFER_SIZE))
}

pub fn emit_at_origin(&mut self, rotation: f32, color: Color) {
if !self.config.particle {
return;
Expand Down
Loading