siglus_scene_vm/runtime/commands/
bg.rs1use anyhow::Result;
2
3use crate::runtime::commands::util::strip_vm_meta;
4use crate::runtime::{Command, CommandContext, Value};
5
6fn arg_as_str(args: &[Value], idx: usize) -> Option<&str> {
7 match args.get(idx) {
8 Some(Value::Str(s)) => Some(s.as_str()),
9 _ => None,
10 }
11}
12
13fn last_i64(args: &[Value]) -> Option<i64> {
14 args.iter().rev().find_map(|v| match v {
15 Value::Int(i) => Some(*i),
16 _ => None,
17 })
18}
19
20fn collect_i64(args: &[Value]) -> Vec<i64> {
21 args.iter()
22 .filter_map(|v| match v {
23 Value::Int(i) => Some(*i),
24 _ => None,
25 })
26 .collect()
27}
28
29pub fn handle(ctx: &mut CommandContext, cmd: &Command) -> Result<bool> {
30 let name = cmd.name.to_ascii_uppercase();
31
32 if name == "BG" {
33 let args = strip_vm_meta(&cmd.args);
34 let bg_name = match arg_as_str(args, 0) {
35 Some(s) => s,
36 None => return Ok(false),
37 };
38 let frame_idx = args
39 .get(1)
40 .and_then(|v| v.as_i64())
41 .and_then(|x| usize::try_from(x).ok())
42 .unwrap_or(0);
43 let (gfx, images, layers) = (&mut ctx.gfx, &mut ctx.images, &mut ctx.layers);
44 gfx.object_create(images, layers, 0, 0, bg_name, 1, 0, 0, frame_idx as i64)?;
45 return Ok(true);
46 }
47
48 if matches!(name.as_str(), "BG_CLEAR" | "BG_OFF" | "BGCLEAR") {
49 {
51 let (gfx, images, layers) = (&mut ctx.gfx, &mut ctx.images, &mut ctx.layers);
52 let _ = gfx.object_clear(images, layers, 0, 0);
53 }
54 ctx.layers.clear_bg();
55 return Ok(true);
56 }
57
58 if matches!(name.as_str(), "BG_ALPHA" | "BGALPHA" | "BG_A") {
59 let args = strip_vm_meta(&cmd.args);
60 let alpha_i = match last_i64(args) {
61 Some(v) => v,
62 None => return Ok(false),
63 };
64 let alpha = alpha_i.clamp(0, 255);
65 let (gfx, images, layers) = (&mut ctx.gfx, &mut ctx.images, &mut ctx.layers);
66 gfx.object_set_alpha(images, layers, 0, 0, alpha)?;
67 return Ok(true);
68 }
69
70 if matches!(name.as_str(), "BG_X" | "BGX") {
71 let args = strip_vm_meta(&cmd.args);
72 if let Some(x) = last_i64(args) {
73 let (gfx, images, layers) = (&mut ctx.gfx, &mut ctx.images, &mut ctx.layers);
74 gfx.object_set_x(images, layers, 0, 0, x)?;
75 return Ok(true);
76 }
77 return Ok(false);
78 }
79
80 if matches!(name.as_str(), "BG_Y" | "BGY") {
81 let args = strip_vm_meta(&cmd.args);
82 if let Some(y) = last_i64(args) {
83 let (gfx, images, layers) = (&mut ctx.gfx, &mut ctx.images, &mut ctx.layers);
84 gfx.object_set_y(images, layers, 0, 0, y)?;
85 return Ok(true);
86 }
87 return Ok(false);
88 }
89
90 if matches!(name.as_str(), "BG_POS" | "BGPOS" | "BG_MOVE" | "BGMOVE") {
91 let args = strip_vm_meta(&cmd.args);
94 let ints = collect_i64(args);
95 if ints.len() >= 2 {
96 let x = ints[ints.len() - 2];
97 let y = ints[ints.len() - 1];
98 let (gfx, images, layers) = (&mut ctx.gfx, &mut ctx.images, &mut ctx.layers);
99 gfx.object_set_pos(images, layers, 0, 0, x, y)?;
100 if ints.len() >= 3 {
101 let dur = ints[ints.len() - 3];
102 if dur > 0 {
103 ctx.wait.wait_ms(dur as u64);
104 }
105 }
106 return Ok(true);
107 }
108 return Ok(false);
109 }
110
111 if matches!(
112 name.as_str(),
113 "BG_PAT" | "BGPAT" | "BG_FRAME" | "BGFRAME" | "BG_NO" | "BGNO"
114 ) {
115 let args = strip_vm_meta(&cmd.args);
116 if let Some(p) = last_i64(args) {
117 let (gfx, images, layers) = (&mut ctx.gfx, &mut ctx.images, &mut ctx.layers);
118 gfx.object_set_patno(images, layers, 0, 0, p)?;
119 return Ok(true);
120 }
121 return Ok(false);
122 }
123
124 if matches!(name.as_str(), "BG_FADE" | "BGFADE") {
125 let args = strip_vm_meta(&cmd.args);
127 let ints = collect_i64(args);
128 if ints.len() >= 2 {
129 let alpha = ints[ints.len() - 2].clamp(0, 255);
130 let dur = ints[ints.len() - 1];
131 let (gfx, images, layers) = (&mut ctx.gfx, &mut ctx.images, &mut ctx.layers);
132 gfx.object_set_alpha(images, layers, 0, 0, alpha)?;
133 if dur > 0 {
134 ctx.wait.wait_ms(dur as u64);
135 }
136 return Ok(true);
137 }
138 return Ok(false);
139 }
140
141 if name.starts_with("BG") {
144 return Ok(true);
145 }
146
147 Ok(false)
148}