Skip to content

Commit

Permalink
WIP, w4wr: Fix getting host function args, implement draw
Browse files Browse the repository at this point in the history
  • Loading branch information
osa1 committed May 2, 2024
1 parent bb5bd2a commit c7d6d63
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 38 deletions.
4 changes: 4 additions & 0 deletions crates/libwasmrun/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ impl Mem {
self.mem[addr as usize..(addr + len) as usize].fill(value);
Ok(())
}

pub fn range(&self, start: u32, end: u32) -> &[u8] {
&self.mem[start as usize..end as usize]
}
}

pub(crate) fn store_16_le_unchecked(value: u16, mem: &mut [u8], addr: usize) {
Expand Down
2 changes: 1 addition & 1 deletion crates/libwasmrun/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl Value {
Value::I128(0i128)
}

pub(crate) fn expect_i32(&self) -> i32 {
pub fn expect_i32(&self) -> i32 {
match self {
Value::I32(i) => *i,
_ => panic!("expect_i32: found {:?}", self),
Expand Down
142 changes: 105 additions & 37 deletions crates/w4wr/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ fn main() {
],
ret_tys: vec![],
fun: Rc::new(move |rt, _mem_addr| {
let flags = rt.pop_i32()?;
let volume = rt.pop_i32()?;
let duration = rt.pop_i32()?;
let frequency = rt.pop_i32()?;
let frequency = rt.get_local(0)?.expect_i32();
let duration = rt.get_local(1)?.expect_i32();
let volume = rt.get_local(2)?.expect_i32();
let flags = rt.get_local(3)?.expect_i32();
w4state.tone(frequency, duration, volume, flags, rt);
Ok(vec![])
}),
Expand All @@ -63,13 +63,13 @@ fn main() {
],
ret_tys: vec![],
fun: Rc::new(move |rt, _mem_addr| {
let flags = rt.pop_i32()?;
let height = rt.pop_i32()?;
let width = rt.pop_i32()?;
let y = rt.pop_i32()?;
let x = rt.pop_i32()?;
let sprite_ptr = rt.pop_i32()?;
w4state.blit(flags, height, width, y, x, sprite_ptr, rt);
let sprite_ptr = rt.get_local(0)?.expect_i32();
let x = rt.get_local(0)?.expect_i32();
let y = rt.get_local(1)?.expect_i32();
let width = rt.get_local(3)?.expect_i32();
let height = rt.get_local(4)?.expect_i32();
let flags = rt.get_local(5)?.expect_i32();
w4state.blit(sprite_ptr, x, y, width, height, flags, rt);
Ok(vec![])
}),
},
Expand All @@ -85,15 +85,33 @@ fn main() {
],
ret_tys: vec![],
fun: Rc::new(move |rt, _mem_addr| {
let y = rt.pop_i32()?;
let x = rt.pop_i32()?;
let byte_length = rt.pop_i32()?;
let str = rt.pop_i32()?;
let str = rt.get_local(0)?.expect_i32();
let byte_length = rt.get_local(1)?.expect_i32();
let x = rt.get_local(2)?.expect_i32();
let y = rt.get_local(3)?.expect_i32();
w4state.text_utf16(str, byte_length, x, y, rt);
Ok(vec![])
}),
},
),
(
"text".to_string(),
HostFunDecl {
arg_tys: vec![
ValueType::I32, // str
ValueType::I32, // x
ValueType::I32, // y
],
ret_tys: vec![],
fun: Rc::new(move |rt, _mem_addr| {
let str = rt.get_local(0)?.expect_i32();
let x = rt.get_local(1)?.expect_i32();
let y = rt.get_local(2)?.expect_i32();
w4state.text(str, x, y, rt);
Ok(vec![])
}),
},
),
(
"rect".to_string(),
HostFunDecl {
Expand All @@ -105,10 +123,10 @@ fn main() {
],
ret_tys: vec![],
fun: Rc::new(move |rt, _mem_addr| {
let height = rt.pop_i32()?;
let width = rt.pop_i32()?;
let y = rt.pop_i32()?;
let x = rt.pop_i32()?;
let x = rt.get_local(0)?.expect_i32();
let y = rt.get_local(1)?.expect_i32();
let width = rt.get_local(2)?.expect_i32();
let height = rt.get_local(3)?.expect_i32();
w4state.rect(x, y, width, height, rt);
Ok(vec![])
}),
Expand All @@ -120,7 +138,7 @@ fn main() {

let module_addr = exec::instantiate(&mut rt, module).unwrap();

let start_fun_idx = rt.get_module(module_addr).get_start().unwrap();
let start_fun_idx = rt.get_module(module_addr).get_start();
let update_fun_idx = rt
.get_module(module_addr)
.get_exported_fun_idx("update")
Expand Down Expand Up @@ -156,11 +174,13 @@ fn main() {
let mut pixels = {
let window_size = window.inner_size();
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window);
Pixels::new(screen_width as u32, screen_height as u32, surface_texture).unwrap()
Pixels::new(160, 160, surface_texture).unwrap()
};

exec::invoke(&mut rt, module_addr, start_fun_idx).unwrap();
exec::finish(&mut rt).unwrap();
if let Some(start_fun_idx) = start_fun_idx {
exec::invoke(&mut rt, module_addr, start_fun_idx).unwrap();
exec::finish(&mut rt).unwrap();
}

event_loop.run(move |event, _, control_flow| {
if let Event::RedrawRequested(_) = event {
Expand All @@ -173,9 +193,9 @@ fn main() {
}

if let Event::UserEvent(()) = event {
println!("tick");
exec::invoke(&mut rt, module_addr, update_fun_idx);
exec::finish(&mut rt);
println!("tick {:?}", update_fun_idx);
exec::invoke(&mut rt, module_addr, update_fun_idx).unwrap();
exec::finish(&mut rt).unwrap();
window.request_redraw();
return;
}
Expand All @@ -198,15 +218,9 @@ fn main() {
}

// Update internal state and request a redraw.
// world.update();
window.request_redraw();
}
});

// loop {
// exec::invoke(&mut rt, module_addr, update_fun_idx).unwrap();
// exec::finish(&mut rt).unwrap();
// }
}

const PALETTE_ADDR: u32 = 0x4; // 16 bytes
Expand Down Expand Up @@ -251,8 +265,6 @@ impl W4State {
}

fn rect(&self, x: i32, y: i32, width: i32, height: i32, rt: &mut Runtime) {
println!("rect");

let x = x as u32;
let y = y as u32;
let width = width as u32;
Expand Down Expand Up @@ -324,18 +336,74 @@ impl W4State {

// TODO: Apply flags.

println!("blit");
println!("NOT IMPLEMENTED: blit");
}

fn tone(&self, frequency: i32, duration: i32, volume: i32, flags: i32, rt: &mut Runtime) {
println!("tone");
println!("NOT IMPLEMENTED: tone");
}

fn text_utf16(&self, str_addr: i32, byte_length: i32, x: i32, y: i32, rt: &mut Runtime) {
println!("textUtf16");
println!("NOT IMPLEMENTED: textUtf16");
}

fn text(&self, str_addr: i32, x: i32, y: i32, rt: &mut Runtime) {
println!("NOT IMPLEMENTED: text");
}

fn draw(&self, frame: &mut [u8], rt: &mut Runtime) {
let mem = rt.get_mem(self.mem);

let mut frame_offset = 0;
for frame_byte in mem.range(FRAMEBUFFER_ADDR, FRAMEBUFFER_ADDR + 6400) {
let color = frame_byte & 0b11;
let (r, g, b) = self.get_palette_color(color, rt);

frame[frame_offset] = r;
frame[frame_offset + 1] = g;
frame[frame_offset + 2] = b;
frame[frame_offset + 3] = 0xFF;
frame_offset += 4;

let color = (frame_byte & 0b1100) >> 2;
let (r, g, b) = self.get_palette_color(color, rt);

frame[frame_offset] = r;
frame[frame_offset + 1] = g;
frame[frame_offset + 2] = b;
frame[frame_offset + 3] = 0xFF;
frame_offset += 4;

let color = (frame_byte & 0b110000) >> 4;
let (r, g, b) = self.get_palette_color(color, rt);

frame[frame_offset] = r;
frame[frame_offset + 1] = g;
frame[frame_offset + 2] = b;
frame[frame_offset + 3] = 0xFF;
frame_offset += 4;

let color = (frame_byte & 0b11000000) >> 6;
let (r, g, b) = self.get_palette_color(color, rt);

frame[frame_offset] = r;
frame[frame_offset + 1] = g;
frame[frame_offset + 2] = b;
frame[frame_offset + 3] = 0xFF;
frame_offset += 4;
}

assert_eq!(frame_offset, frame.len());
}

/// Get (r, g, b) of `color` from the palette.
fn get_palette_color(&self, color: u8, rt: &Runtime) -> (u8, u8, u8) {
let mem = rt.get_mem(self.mem);
let rgb = mem.load_32_le(PALETTE_ADDR + u32::from(color)).unwrap();
(
((rgb & 0xFF0000) >> 16) as u8,
((rgb & 0xFF00) >> 8) as u8,
(rgb & 0xFF) as u8,
)
}
}

0 comments on commit c7d6d63

Please sign in to comment.