Skip to content
Open
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
2 changes: 1 addition & 1 deletion phira/src/scene/unlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl Scene for UnlockScene {
match self.state {
State::Playing => {
if t > 0.05 {
self.video.render(t, asp, WHITE);
self.video.render(t, asp, WHITE, None);
}
}
State::Loading => {
Expand Down
6 changes: 4 additions & 2 deletions prpr/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,14 +460,16 @@ impl BinaryData for JudgeLine {

impl BinaryData for ChartSettings {
fn read_binary<R: Read>(r: &mut BinaryReader<R>) -> Result<Self> {
let pe_byte = r.read::<u8>()?;
Ok(Self {
pe_alpha_extension: r.read::<u8>()? == 1,
pe_alpha_extension: pe_byte & 1 != 0,
hold_partial_cover: r.read::<u8>()? == 1,
line_reference_y_axis: pe_byte >> 1 & 1 != 0,
})
}

fn write_binary<W: Write>(&self, w: &mut BinaryWriter<W>) -> Result<()> {
w.write_val(self.pe_alpha_extension as u8)?;
w.write_val((self.pe_alpha_extension as u8) | ((self.line_reference_y_axis as u8) << 1))?;
w.write_val(self.hold_partial_cover as u8)?;
Ok(())
}
Expand Down
38 changes: 25 additions & 13 deletions prpr/src/core/chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct ChartExtra {
pub struct ChartSettings {
pub pe_alpha_extension: bool,
pub hold_partial_cover: bool,
pub line_reference_y_axis: bool,
}

pub type HitSoundMap = HashMap<String, AudioClip>;
Expand Down Expand Up @@ -143,20 +144,31 @@ impl Chart {
}

pub fn render(&self, ui: &mut Ui, res: &mut Resource) {
#[cfg(feature = "video")]
for (video, attach) in &self.extra.videos {
if let Some(attach) = attach {
let line = &self.lines[attach.line];
let color = line.color.now_opt().unwrap_or(res.judge_line_color);
let mat = self.lines[attach.line].object.now(res);
res.apply_model_of(&mat, |res| {
video.render(res.time, res.aspect_ratio, color);
});
} else {
video.render(res.time, res.aspect_ratio, WHITE);
}
}
res.apply_model_of(&Matrix::identity().append_nonuniform_scaling(&Vector::new(if res.config.flip_x() { -1. } else { 1. }, -1.)), |res| {
#[cfg(feature = "video")]
for (video, attach) in &self.extra.videos {
if let Some(attach) = attach {
let line = &self.lines[attach.line];
let color = line.color.now_opt().unwrap_or(res.judge_line_color);
let line_scale = line.object.scale.now_with_def(1.0, 1.0);
let mat = Rotation2::new(
self.lines[attach.line].fetch_rot(&self.lines).to_radians() * attach.rotation_factor).to_homogeneous()
.append_translation(&self.lines[attach.line].fetch_pos(res, &self.lines).component_mul(&Vector::new(attach.position_x_factor, attach.position_y_factor)));
res.apply_model_of(&mat.append_nonuniform_scaling(&Vector::new(1., -1.)), |res| {
video.render(
res.time,
res.aspect_ratio,
color,
Some((line_scale.x, line_scale.y, attach.scale_x_mode, attach.scale_y_mode)),
);
});
} else {
res.apply_model_of(&Matrix::identity().append_nonuniform_scaling(&Vector::new(1., -1.)), |res| {
video.render(res.time, res.aspect_ratio, WHITE, None);
});
}
}

let mut guard = self.bpm_list.borrow_mut();
for id in &self.order {
self.lines[*id].render(ui, res, &self.lines, &mut guard, &self.settings, *id);
Expand Down
14 changes: 11 additions & 3 deletions prpr/src/core/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ impl JudgeLine {
pub fn render(&self, ui: &mut Ui, res: &mut Resource, lines: &[JudgeLine], bpm_list: &mut BpmList, settings: &ChartSettings, id: usize) {
let alpha = self.object.alpha.now_opt().unwrap_or(1.0) * res.alpha;
let color = self.color.now_opt();
let line_scaled = (self.object.scale.1.now() - 1.).abs() > 1e-4;
res.with_model(self.now_transform(res, lines), |res| {
if res.config.chart_debug {
res.apply_model(|_| {
Expand All @@ -248,8 +247,17 @@ impl JudgeLine {
JudgeLineKind::Normal => {
let mut color = color.unwrap_or(res.judge_line_color);
color.a *= alpha.max(0.0);
let len = res.info.line_length;
draw_line(-len, 0., len, 0., if line_scaled { 0.0076 } else { 0.01 }, color);
let len = if settings.line_reference_y_axis {
res.info.line_length / res.aspect_ratio
} else {
res.info.line_length
};
let thickness = if settings.line_reference_y_axis {
0.0150 / res.aspect_ratio
} else {
0.0100
};
draw_line(-len, 0., len, 0., thickness, color);
}
JudgeLineKind::Texture(texture, _) => {
let mut color = color.unwrap_or(WHITE);
Expand Down
74 changes: 73 additions & 1 deletion prpr/src/core/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,30 @@ thread_local! {
static VIDEO_BUFFERS: RefCell<[Vec<u8>; 3]> = RefCell::default();
}

fn f32_one() -> f32 {
1.
}



#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VideoAttach {
pub line: usize,
#[serde(default = "f32_one")]
pub position_x_factor: f32,
#[serde(default = "f32_one")]
pub position_y_factor: f32,
#[serde(default = "f32_one")]
pub rotation_factor: f32,
#[serde(default = "f32_one")]
pub alpha_factor: f32,
#[serde(default = "f32_one")]
pub tint_factor: f32,
#[serde(default)]
pub scale_x_mode: u8,
#[serde(default)]
pub scale_y_mode: u8,
}

pub struct Video {
Expand Down Expand Up @@ -131,7 +152,7 @@ impl Video {
Ok(())
}

pub fn render(&self, t: f64, aspect_ratio: f32, color: Color) {
pub fn render(&self, t: f64, aspect_ratio: f32, color: Color, line_scale: Option<(f32, f32, u8, u8)>) {
if !(0f64..self.duration).contains(&(t - self.start_time)) {
return;
}
Expand All @@ -141,6 +162,57 @@ impl Video {
let s = source_of_image(&self.tex_y, r, self.scale_type).unwrap_or_else(|| Rect::new(0., 0., 1., 1.));
let dim = 1. - self.dim.now();
let color = Color::new(dim * color.r, dim * color.g, dim * color.b, self.alpha.now_opt().unwrap_or(1.) * color.a);

let (r, s) = if let Some((sx, sy, mode_x, mode_y)) = line_scale {
match (mode_x, mode_y) {
(0, 0) => (r, s),
_ => {
let mut r = r;
let mut s = s;

// Scale mode: scale vertices, mirror with negative values
if mode_x == 1 {
r = Rect::new(r.x, r.y, r.w * sx.abs(), r.h);
if sx < 0. {
s = Rect::new(s.right(), s.y, -s.w, s.h);
}
}
if mode_y == 1 {
r = Rect::new(r.x, r.y, r.w, r.h * sy.abs());
if sy < 0. {
s = Rect::new(s.x, s.bottom(), s.w, -s.h);
}
}

// Clip mode: clip both vertices and texture proportionally
if mode_x == 2 {
let clip = sx.abs().min(1.0);
let offset_r = r.w * (1.0 - clip) / 2.0;
let offset_s = s.w * (1.0 - clip) / 2.0;
r = Rect::new(r.x + offset_r, r.y, r.w * clip, r.h);
s = Rect::new(s.x + offset_s, s.y, s.w * clip, s.h);
if sx < 0. {
s = Rect::new(s.right(), s.y, -s.w, s.h);
}
}
if mode_y == 2 {
let clip = sy.abs().min(1.0);
let offset_r = r.h * (1.0 - clip) / 2.0;
let offset_s = s.h * (1.0 - clip) / 2.0;
r = Rect::new(r.x, r.y + offset_r, r.w, r.h * clip);
s = Rect::new(s.x, s.y + offset_s, s.w, s.h * clip);
if sy < 0. {
s = Rect::new(s.x, s.bottom(), s.w, -s.h);
}
}

(r, s)
}
}
} else {
(r, s)
};

let vertices = [
Vertex::new(r.x, r.y, 0., s.x, s.y, color),
Vertex::new(r.right(), r.y, 0., s.right(), s.y, color),
Expand Down
16 changes: 13 additions & 3 deletions prpr/src/parse/pgr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,15 @@ fn parse_judge_line(pgr: PgrJudgeLine, max_time: f64, format_version: u32) -> Re
Ok(JudgeLine {
object: Object {
alpha: parse_float_events(r, pgr.alpha_events).with_context(|| ptl!("alpha-events-parse-failed"))?,
scale: AnimVector(AnimFloat::fixed(5.75 / 6.0), AnimFloat::default()),
rotation: parse_float_events(r, pgr.rotate_events).with_context(|| ptl!("rotate-events-parse-failed"))?,
translation: {
match format_version {
1 => parse_move_events_fv1(r, pgr.move_events).with_context(|| ptl!("move-events-parse-failed"))?,
3 => parse_move_events(r, pgr.move_events).with_context(|| ptl!("move-events-parse-failed"))?,
_ => ptl!(bail "unknown-format-version"),
}
},
..Default::default()
}
},
ctrl_obj: RefCell::default(),
kind: JudgeLineKind::Normal,
Expand Down Expand Up @@ -293,5 +293,15 @@ pub fn parse_phigros(source: &str, extra: ChartExtra) -> Result<Chart> {
.collect::<Result<Vec<_>>>()?;

process_lines(&mut lines);
Ok(Chart::new(pgr.offset, lines, BpmList::default(), ChartSettings::default(), extra, HashMap::new()))
Ok(Chart::new(
pgr.offset,
lines,
BpmList::default(),
ChartSettings {
line_reference_y_axis: true,
..Default::default()
},
extra,
HashMap::new()
))
}
30 changes: 12 additions & 18 deletions prpr/src/parse/rpe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
core::{
Anim, AnimFloat, AnimVector, BezierTween, BpmList, Chart, ChartExtra, ChartSettings, ClampedTween, CtrlObject, GeneralIntTween, GifFrames,
HitSoundMap, IntClampedTween, IntStaticTween, JudgeLine, JudgeLineCache, JudgeLineKind, Keyframe, Note, NoteKind, Object, StaticTween,
Triple, TweenFunction, Tweenable, UIElement, EPS, HEIGHT_RATIO,
Triple, TweenFunction, Tweenable, UIElement, Vector, EPS, HEIGHT_RATIO,
},
ext::{NotNanExt, SafeTexture},
fs::FileSystem,
Expand Down Expand Up @@ -685,38 +685,32 @@ async fn parse_judge_line(
.as_ref()
.map(|it| parse_events(r, it, None, bezier_map))
.transpose()?
.unwrap_or_default();
.unwrap_or(
if factor == 1. {
Anim::default()
} else {
Anim::fixed(1.0)
}
);
res.map_value(|v| v * factor);
Ok(res)
}
let factor = if rpe.texture == "line.png" { 1. } else { 2. / RPE_WIDTH };
let image_factor = if rpe.texture == "line.png" { 1. } else { 2. / RPE_WIDTH };
rpe.extended
.as_ref()
.map(|e| -> Result<_> {
Ok(AnimVector(
parse(
r,
&e.scale_x_events,
factor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这段行为和之前不同?可以原因吗(0.5 vs 1)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已确认在rpe.rs中缩放判定线会导致video attach无法获取到原始缩放,所以当贴图名称为line.png时rpe.rs不缩放,在game.rs对RPE谱调整判定线长度

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原先的判定线缩放0.5也不准确,RPE的判定线长度实际为4000.0 / RPE_WIDTH

* if rpe.texture == "line.png"
&& rpe
.extended
.as_ref()
.and_then(|it| it.text_events.as_ref())
.is_none_or(|it| it.is_empty())
&& rpe.attach_ui.is_none()
{
0.5
} else {
1.
},
image_factor,
bezier_map,
)?,
parse(r, &e.scale_y_events, factor, bezier_map)?,
parse(r, &e.scale_y_events, image_factor, bezier_map)?,
))
})
.transpose()?
.unwrap_or_default()
.unwrap_or(AnimVector::fixed(Vector::new(image_factor, image_factor)))
},
},
ctrl_obj: RefCell::new(CtrlObject {
Expand Down
10 changes: 7 additions & 3 deletions prpr/src/scene/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ use super::{
use crate::{
bin::BinaryReader,
config::{Config, Mods},
core::{copy_fbo, BadNote, Chart, ChartExtra, Effect, Point, Resource, UIElement, Vector, PGR_FONT},
ext::{parse_time, screen_aspect, semi_white, RectExt, SafeTexture, ScaleType},
core::{BadNote, Chart, ChartExtra, Effect, PGR_FONT, Point, Resource, UIElement, Vector, copy_fbo},
ext::{RectExt, SafeTexture, ScaleType, parse_time, screen_aspect, semi_white},
fs::FileSystem,
info::{ChartFormat, ChartInfo},
judge::Judge,
parse::{parse_extra, parse_pec, parse_phigros, parse_rpe},
parse::{RPE_WIDTH, parse_extra, parse_pec, parse_phigros, parse_rpe},
task::Task,
time::TimeManager,
ui::{RectButton, TextPainter, Ui},
Expand Down Expand Up @@ -293,6 +293,10 @@ impl GameScene {
.await
.context("Failed to load resources")?;

if matches!(chart_format, ChartFormat::Rpe) {
res.info.line_length *= 4000. / RPE_WIDTH / 6.;
}

// Prepare extra sfx from chart.hitsounds
chart.hitsounds.drain().for_each(|(name, clip)| {
if let Ok(clip) = res.create_sfx(clip) {
Expand Down
Loading