1use std::num::NonZeroU64;
4
5use crate::{
6 bms::{
7 Decimal,
8 command::{
9 JudgeLevel, ObjId,
10 channel::Channel,
11 time::{ObjTime, Track},
12 },
13 },
14 command::channel::NoteChannelId,
15};
16
17use crate::bms::command::{graphics::Argb, minor_command::SwBgaEvent};
18
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22pub struct WavObj {
23 pub offset: ObjTime,
25 pub channel_id: NoteChannelId,
27 pub wav_id: ObjId,
29}
30
31impl PartialOrd for WavObj {
32 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
33 Some(self.cmp(other))
34 }
35}
36
37impl Ord for WavObj {
38 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
39 self.offset
40 .cmp(&other.offset)
41 .then(self.wav_id.cmp(&other.wav_id))
42 }
43}
44
45impl WavObj {
46 pub(crate) fn dangling() -> Self {
47 Self {
48 offset: ObjTime::new(
49 1,
50 0,
51 NonZeroU64::new(1).expect("1 should be a valid NonZeroU64"),
52 ),
53 channel_id: NoteChannelId::bgm(),
54 wav_id: ObjId::null(),
55 }
56 }
57}
58
59#[derive(Debug, Clone)]
61#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
62pub struct BpmChangeObj {
63 pub time: ObjTime,
65 pub bpm: Decimal,
67}
68
69impl PartialEq for BpmChangeObj {
70 fn eq(&self, other: &Self) -> bool {
71 self.time == other.time
72 }
73}
74
75impl Eq for BpmChangeObj {}
76
77impl PartialOrd for BpmChangeObj {
78 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
79 Some(self.cmp(other))
80 }
81}
82
83impl Ord for BpmChangeObj {
84 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
85 self.time.cmp(&other.time)
86 }
87}
88
89#[derive(Debug, Clone)]
91#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
92pub struct SectionLenChangeObj {
93 pub track: Track,
95 pub length: Decimal,
97}
98
99impl PartialEq for SectionLenChangeObj {
100 fn eq(&self, other: &Self) -> bool {
101 self.track == other.track
102 }
103}
104
105impl Eq for SectionLenChangeObj {}
106
107impl PartialOrd for SectionLenChangeObj {
108 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
109 Some(self.cmp(other))
110 }
111}
112
113impl Ord for SectionLenChangeObj {
114 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
115 self.track.cmp(&other.track)
116 }
117}
118
119#[derive(Debug, Clone)]
121#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
122pub struct StopObj {
123 pub time: ObjTime,
125 pub duration: Decimal,
129}
130
131impl PartialEq for StopObj {
132 fn eq(&self, other: &Self) -> bool {
133 self.time == other.time
134 }
135}
136
137impl Eq for StopObj {}
138
139impl PartialOrd for StopObj {
140 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
141 Some(self.cmp(other))
142 }
143}
144
145impl Ord for StopObj {
146 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
147 self.time.cmp(&other.time)
148 }
149}
150
151#[derive(Debug, Clone, Copy)]
153#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
154pub struct BgaObj {
155 pub time: ObjTime,
157 pub id: ObjId,
159 pub layer: BgaLayer,
161}
162
163impl PartialEq for BgaObj {
164 fn eq(&self, other: &Self) -> bool {
165 self.time == other.time
166 }
167}
168
169impl Eq for BgaObj {}
170
171impl PartialOrd for BgaObj {
172 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
173 Some(self.cmp(other))
174 }
175}
176
177impl Ord for BgaObj {
178 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
179 self.time.cmp(&other.time)
180 }
181}
182
183#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
185#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
186#[non_exhaustive]
187pub enum BgaLayer {
188 Base,
190 Poor,
192 Overlay,
194 Overlay2,
198}
199
200impl BgaLayer {
201 #[must_use]
203 pub const fn from_channel(channel: Channel) -> Option<Self> {
204 match channel {
205 Channel::BgaBase => Some(Self::Base),
206
207 Channel::BgaBaseArgb | Channel::BgaBaseOpacity => Some(Self::Base),
208 Channel::BgaLayer => Some(Self::Overlay),
209
210 Channel::BgaLayerArgb | Channel::BgaLayerOpacity => Some(Self::Overlay),
211 Channel::BgaLayer2 => Some(Self::Overlay2),
212
213 Channel::BgaLayer2Argb | Channel::BgaLayer2Opacity => Some(Self::Overlay2),
214 Channel::BgaPoor => Some(Self::Poor),
215
216 Channel::BgaPoorArgb | Channel::BgaPoorOpacity => Some(Self::Poor),
217 _ => None,
218 }
219 }
220
221 #[must_use]
223 pub const fn to_channel(self) -> Channel {
224 match self {
225 Self::Base => Channel::BgaBase,
226 Self::Overlay => Channel::BgaLayer,
227 Self::Overlay2 => Channel::BgaLayer2,
228 Self::Poor => Channel::BgaPoor,
229 }
230 }
231}
232
233#[derive(Debug, Clone)]
235#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
236pub struct ScrollingFactorObj {
237 pub time: ObjTime,
239 pub factor: Decimal,
241}
242
243impl PartialEq for ScrollingFactorObj {
244 fn eq(&self, other: &Self) -> bool {
245 self.time == other.time
246 }
247}
248
249impl Eq for ScrollingFactorObj {}
250
251impl PartialOrd for ScrollingFactorObj {
252 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
253 Some(self.cmp(other))
254 }
255}
256
257impl Ord for ScrollingFactorObj {
258 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
259 self.time.cmp(&other.time)
260 }
261}
262
263#[derive(Debug, Clone)]
265#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
266pub struct SpeedObj {
267 pub time: ObjTime,
269 pub factor: Decimal,
271}
272
273impl PartialEq for SpeedObj {
274 fn eq(&self, other: &Self) -> bool {
275 self.time == other.time
276 }
277}
278
279impl Eq for SpeedObj {}
280
281impl PartialOrd for SpeedObj {
282 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
283 Some(self.cmp(other))
284 }
285}
286
287impl Ord for SpeedObj {
288 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
289 self.time.cmp(&other.time)
290 }
291}
292
293#[derive(Debug, Clone, Eq, PartialEq)]
295#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
296pub struct BgaOpacityObj {
297 pub time: ObjTime,
299 pub layer: BgaLayer,
301 pub opacity: u8,
303}
304
305#[derive(Debug, Clone, Eq, PartialEq)]
307#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
308pub struct BgaArgbObj {
309 pub time: ObjTime,
311 pub layer: BgaLayer,
313 pub argb: Argb,
315}
316
317#[derive(Debug, Clone, Eq, PartialEq)]
319#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
320pub struct BgmVolumeObj {
321 pub time: ObjTime,
323 pub volume: u8,
325}
326
327#[derive(Debug, Clone, Eq, PartialEq)]
329#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
330pub struct KeyVolumeObj {
331 pub time: ObjTime,
333 pub volume: u8,
335}
336
337#[derive(Debug, Clone, Eq, PartialEq)]
339#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
340pub struct SeekObj {
341 pub time: ObjTime,
343 pub position: Decimal,
345}
346
347#[derive(Debug, Clone, Eq, PartialEq)]
349#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
350pub struct TextObj {
351 pub time: ObjTime,
353 pub text: String,
355}
356
357#[derive(Debug, Clone, Eq, PartialEq)]
359#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
360pub struct JudgeObj {
361 pub time: ObjTime,
363 pub judge_level: JudgeLevel,
365}
366
367#[derive(Debug, Clone, Eq, PartialEq)]
369#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
370pub struct BgaKeyboundObj {
371 pub time: ObjTime,
373 pub event: SwBgaEvent,
375}
376
377#[derive(Debug, Clone, Eq, PartialEq)]
379#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
380pub struct OptionObj {
381 pub time: ObjTime,
383 pub option: String,
385}