Basic output system
This commit is contained in:
@ -7,5 +7,6 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.82"
|
||||
minifb_host = { path = "../minifb_host" }
|
||||
player = { path = "../player" }
|
||||
viperid = { path = "../.." }
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use viperid::VResult;
|
||||
use viperid::{Device, VResult};
|
||||
|
||||
use crate::go_builder::GoBuilder;
|
||||
|
||||
@ -10,14 +10,15 @@ fn main() -> VResult<()> {
|
||||
let builder = GoBuilder::new(
|
||||
&PathBuf::from("example_project"))?;
|
||||
let wasm = builder.build()?;
|
||||
let mut executor = player::Executor::new(&wasm)?;
|
||||
let device = Device::new();
|
||||
|
||||
while executor.is_running() {
|
||||
println!("update started");
|
||||
let mut executor = player::Executor::new(device.share(), &wasm)?;
|
||||
|
||||
minifb_host::host(device, || {
|
||||
executor.update();
|
||||
println!("update completed");
|
||||
executor.get_error()?;
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -6,3 +6,5 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
minifb = "0.25.0"
|
||||
viperid = { path = "../.." }
|
||||
|
@ -0,0 +1,27 @@
|
||||
use minifb::{Window, WindowOptions};
|
||||
use viperid::{Device, VResult, SCREEN_H, SCREEN_W};
|
||||
|
||||
pub fn host(
|
||||
device: Device,
|
||||
mut update: impl FnMut() -> VResult<()>
|
||||
) -> VResult<()> {
|
||||
let mut window = Window::new(
|
||||
"viperid",
|
||||
SCREEN_W,
|
||||
SCREEN_H,
|
||||
WindowOptions::default()
|
||||
)?;
|
||||
|
||||
// limit to 60FPS
|
||||
window.limit_update_rate(Some(std::time::Duration::from_micros(16600)));
|
||||
|
||||
let mut buffer: Vec<u32> = vec![0; SCREEN_W * SCREEN_H];
|
||||
while window.is_open() {
|
||||
update()?;
|
||||
device.shared.screen.to_bitmap(&mut buffer);
|
||||
|
||||
window.update_with_buffer(&buffer, SCREEN_W, SCREEN_H)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,16 +1,28 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use viperid::VResult;
|
||||
use wasmi::{core::{HostError, Trap}, Caller, Linker};
|
||||
use wasmi::{core::{HostError, Trap}, Caller, Extern, Linker};
|
||||
|
||||
use crate::executor::ExecutorState;
|
||||
|
||||
pub(crate) fn integrate(linker: &mut Linker<ExecutorState>) -> VResult<()> {
|
||||
linker.func_wrap("viperid", "Pset", pset)?;
|
||||
|
||||
linker.func_wrap("viperid", "YieldFrame", yield_frame)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pset(mut caller: Caller<ExecutorState>, x: i32, y: i32, color: i32) -> Result<(), Trap> {
|
||||
let memory = match caller.get_export("memory") {
|
||||
Some(Extern::Memory(m)) => m,
|
||||
_ => return Err(wasmi::core::Trap::new(String::from("missing required memory export"))),
|
||||
};
|
||||
let(_, ctx) = memory.data_and_store_mut(&mut caller);
|
||||
ctx.device.shared.screen.pset(x, y, (color & 0xff) as u8);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn yield_frame(_caller: Caller<ExecutorState>) -> Result<(), Trap> {
|
||||
Err(Trap::from(YieldFrame {}))
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::mem;
|
||||
|
||||
use viperid::VResult;
|
||||
use viperid::{Device, VResult};
|
||||
use wasmi::{core::Trap, Engine, Linker, Module, Store, TypedFunc, TypedResumableCall, TypedResumableInvocation};
|
||||
|
||||
use crate::{engine_api::{self, YieldFrame}, wasi::{self, StockWasi}};
|
||||
@ -11,13 +11,15 @@ pub struct Executor {
|
||||
}
|
||||
|
||||
pub(crate) struct ExecutorState {
|
||||
wasi: wasi::StockWasi
|
||||
wasi: wasi::StockWasi,
|
||||
pub(crate) device: Device
|
||||
}
|
||||
|
||||
impl ExecutorState {
|
||||
fn new() -> Self {
|
||||
fn new(device: Device) -> Self {
|
||||
ExecutorState {
|
||||
wasi: StockWasi::new()
|
||||
wasi: StockWasi::new(),
|
||||
device
|
||||
}
|
||||
|
||||
}
|
||||
@ -25,12 +27,12 @@ impl ExecutorState {
|
||||
|
||||
|
||||
impl Executor {
|
||||
pub fn new(wasm: &[u8]) -> VResult<Self> {
|
||||
pub fn new(device: Device, wasm: &[u8]) -> VResult<Self> {
|
||||
let engine = Engine::default();
|
||||
|
||||
let module = Module::new(&engine, wasm)?;
|
||||
|
||||
let mut store = Store::new(&engine, ExecutorState::new());
|
||||
let mut store = Store::new(&engine, ExecutorState::new(device));
|
||||
|
||||
let mut linker = <Linker<ExecutorState>>::new(&engine);
|
||||
wasi::integrate(&mut linker, |hs| &mut hs.wasi)?;
|
||||
|
Reference in New Issue
Block a user