siglus_scene_vm/runtime/commands/
audio.rs1use anyhow::Result;
2
3use crate::runtime::commands::util;
4use crate::runtime::{Command, CommandContext, Value};
5
6fn clamp_u8(x: i64) -> u8 {
7 if x <= 0 {
8 return 0;
9 }
10 if x >= 255 {
11 return 255;
12 }
13 x as u8
14}
15
16fn pct_to_raw(pct: i64) -> u8 {
17 let p = if pct < 0 {
18 0
19 } else if pct > 100 {
20 100
21 } else {
22 pct
23 };
24 ((p as u32 * 255) / 100) as u8
26}
27
28pub fn handle(ctx: &mut CommandContext, cmd: &Command) -> Result<bool> {
33 let name = cmd.name.to_ascii_uppercase();
34 let args = util::strip_vm_meta(&cmd.args);
35
36 if matches!(
38 name.as_str(),
39 "BGM" | "BGM_PLAY" | "BGMSTART" | "PLAYBGM" | "BGMON"
40 ) {
41 let file = args.iter().find_map(|v| match v {
42 Value::Str(s) => Some(s.as_str()),
43 _ => None,
44 });
45 if let Some(f) = file {
46 let (bgm, audio) = (&mut ctx.bgm, &mut ctx.audio);
48 let _ = bgm.play_name(audio, f);
49 }
50 return Ok(true);
51 }
52 if matches!(name.as_str(), "BGM_STOP" | "BGMSTOP" | "STOPBGM" | "BGMOFF") {
53 let _ = ctx.bgm.stop();
54 return Ok(true);
55 }
56 if matches!(name.as_str(), "BGM_VOL" | "BGM_VOLUME" | "BGMVOLUME") {
57 let vol = args.iter().find_map(|v| match v {
59 Value::Int(x) => Some(*x),
60 _ => None,
61 });
62 if let Some(v) = vol {
63 let raw = if v <= 100 { pct_to_raw(v) } else { clamp_u8(v) };
64 let (bgm, audio) = (&mut ctx.bgm, &mut ctx.audio);
65 let _ = bgm.set_volume_raw(audio, raw);
66 }
67 return Ok(true);
68 }
69 if matches!(name.as_str(), "BGM_PAUSE" | "BGMPAUSE") {
70 let _ = ctx.bgm.pause();
71 return Ok(true);
72 }
73 if matches!(name.as_str(), "BGM_RESUME" | "BGMRESUME") {
74 let _ = ctx.bgm.resume();
75 return Ok(true);
76 }
77
78 if matches!(name.as_str(), "SE" | "SE_PLAY" | "SEPLAY") {
80 let file = args.iter().find_map(|v| match v {
81 Value::Str(s) => Some(s.as_str()),
82 _ => None,
83 });
84 if let Some(f) = file {
85 let (se, audio) = (&mut ctx.se, &mut ctx.audio);
86 let _ = se.play_file_name(audio, f);
87 }
88 return Ok(true);
89 }
90 if matches!(name.as_str(), "SE_STOP" | "SESTOP") {
91 let _ = ctx.se.stop(None);
92 return Ok(true);
93 }
94 if matches!(name.as_str(), "SE_VOL" | "SE_VOLUME" | "SEVOLUME") {
95 let vol = args.iter().find_map(|v| match v {
96 Value::Int(x) => Some(*x),
97 _ => None,
98 });
99 if let Some(v) = vol {
100 let raw = if v <= 100 { pct_to_raw(v) } else { clamp_u8(v) };
101 let (se, audio) = (&mut ctx.se, &mut ctx.audio);
102 let _ = se.set_volume_raw(audio, raw);
103 }
104 return Ok(true);
105 }
106
107 if matches!(name.as_str(), "PCM" | "PCM_PLAY" | "PCMPLAY") {
109 let file = args.iter().find_map(|v| match v {
110 Value::Str(s) => Some(s.as_str()),
111 _ => None,
112 });
113 if let Some(f) = file {
114 let (pcm, audio) = (&mut ctx.pcm, &mut ctx.audio);
115 let _ = pcm.play_file_name(audio, f);
116 }
117 return Ok(true);
118 }
119 if matches!(name.as_str(), "PCM_STOP" | "PCMSTOP") {
120 let _ = ctx.pcm.stop(None);
121 return Ok(true);
122 }
123
124 Ok(false)
125}