prometeu-runtime/crates/core/src/native_interface.rs
2026-01-15 15:32:16 +00:00

75 lines
2.8 KiB
Rust

use crate::Machine;
use crate::vm::{NativeInterface, Value, VirtualMachine};
impl NativeInterface for Machine {
fn call(&mut self, id: u32, vm: &mut VirtualMachine) -> Result<u64, String> {
match id {
// system.has_cart() -> bool
0x0001 => {
vm.push(Value::Boolean(self.cartridge.is_some()));
Ok(10)
}
// system.run_cart()
0x0002 => {
if let Some(cart) = self.cartridge.as_ref() {
vm.rom = cart.rom.clone();
vm.constant_pool = cart.constant_pool.clone();
vm.pc = 0;
vm.operand_stack.clear();
vm.call_stack.clear();
vm.halted = false;
} else {
return Err("No cartridge inserted".into());
}
Ok(100)
}
// gfx.clear(color_index)
0x1001 => {
let color_idx = vm.pop_integer()? as usize;
let color = self.get_color(color_idx);
self.gfx.clear(color);
Ok(100)
}
// gfx.draw_rect(x, y, w, h, color_index)
0x1002 => {
let color_idx = vm.pop_integer()? as usize;
let h = vm.pop_integer()? as i32;
let w = vm.pop_integer()? as i32;
let y = vm.pop_integer()? as i32;
let x = vm.pop_integer()? as i32;
let color = self.get_color(color_idx);
self.gfx.fill_rect(x, y, w, h, color);
Ok(200)
}
// input.get_pad(button_id) -> bool
0x2001 => {
let button_id = vm.pop_integer()? as u32;
let is_down = self.is_button_down(button_id);
vm.push(Value::Boolean(is_down));
Ok(50)
}
// audio.play_sample(sample_id, voice_id, volume, pan, pitch)
// sample_id: 0=square, 1=kick, 2=snare
0x3001 => {
let pitch = vm.pop_number()?;
let pan = vm.pop_integer()? as u8;
let volume = vm.pop_integer()? as u8;
let voice_id = vm.pop_integer()? as usize;
let sample_id = vm.pop_integer()? as u32;
let sample = match sample_id {
0 => self.sample_square.clone(),
1 => self.sample_kick.clone(),
2 => self.sample_snare.clone(),
_ => None,
};
if let Some(s) = sample {
self.audio.play(s, voice_id, volume, pan, pitch, 0, crate::peripherals::LoopMode::Off);
}
Ok(300)
}
_ => Err(format!("Unknown native call: 0x{:08X}", id)),
}
}
}