siglus_scene_vm/runtime/forms/
joypad.rs1use anyhow::{Result, bail};
2
3use crate::runtime::input::JOYPAD_KEY_COUNT;
4use crate::runtime::{CommandContext, Value};
5
6pub fn dispatch(ctx: &mut CommandContext, _args: &[Value]) -> Result<bool> {
15 let Some(vm_call) = ctx.vm_call.as_ref() else {
16 return Ok(false);
17 };
18 let chain = &vm_call.element;
19 if chain.len() < 4 || chain[0] != ctx.ids.form_global_joypad as i32 {
20 return Ok(false);
21 }
22
23 if chain[1] != 0 || chain[2] != ctx.ids.elm_array {
26 return Ok(false);
27 }
28
29 if chain.len() == 4 {
32 ctx.push(Value::Element(chain.to_vec()));
33 return Ok(true);
34 }
35
36 let key_no = chain[3];
37 let op = chain[4] as i64;
38 if key_no < 0 || key_no as usize >= JOYPAD_KEY_COUNT {
39 bail!("joypad key index out of range: {key_no}");
40 }
41 let mut key_no = key_no as usize;
42 let config = &ctx.globals.syscom.original_config;
47 key_no = match key_no {
48 0 if config.joypad_swap_ab => 1,
49 1 if config.joypad_swap_ab => 0,
50 2 if config.joypad_swap_xy => 3,
51 3 if config.joypad_swap_xy => 2,
52 _ => key_no,
53 };
54
55 let v = if op == ctx.ids.key_op_on_down as i64 {
56 ctx.script_input.joypad_down_stock(key_no)
57 } else if op == ctx.ids.key_op_on_up as i64 {
58 ctx.script_input.joypad_up_stock(key_no)
59 } else if op == ctx.ids.key_op_on_down_up as i64 {
60 ctx.script_input.joypad_down_up_stock(key_no)
61 } else if op == ctx.ids.key_op_is_down as i64 {
62 ctx.script_input.joypad_is_down(key_no)
63 } else if op == ctx.ids.key_op_is_up as i64 {
64 !ctx.script_input.joypad_is_down(key_no)
65 } else {
66 bail!("unsupported joypad key operation: {op}");
67 };
68
69 ctx.push(Value::Int(if v { 1 } else { 0 }));
70 Ok(true)
71}