Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented mouse/controller input, tracef!(), added DrawIndex arg to drawing primitives #10

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions wasm4/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ edition = "2021"
[features]
std = []
include-sprites = ["dep:wasm4-impl"]
tracef = ["dep:format_no_std"]

[dependencies]
bitflags = "1.3.2"
format_no_std = { version = "1.2.0", optional = true }

[dependencies.wasm4-sys]
path = "../wasm4-sys"
Expand Down
90 changes: 90 additions & 0 deletions wasm4/src/control.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use core::marker::PhantomData;

use wasm4_sys::*;

pub struct Controls {
pub mouse: Mouse,
pub gamepads: [Gamepad; 4],
}

pub struct Mouse(PhantomData<*const ()>);
impl Mouse {
pub(crate) unsafe fn new_() -> Self {
Self(PhantomData)
}
pub fn state(&self) -> MouseState {
let buttons = unsafe { *MOUSE_BUTTONS };
let x = unsafe { *MOUSE_X };
let y = unsafe { *MOUSE_Y };

MouseState {
x,
y,
buttons: MouseButtons {
left: buttons & MOUSE_LEFT != 0,
right: buttons & MOUSE_RIGHT != 0,
middle: buttons & MOUSE_MIDDLE != 0,
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MouseState {
pub x: i16,
pub y: i16,
pub buttons: MouseButtons,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MouseButtons {
pub left: bool,
pub right: bool,
pub middle: bool,
}

pub struct Gamepad(*const u8);
impl Gamepad {
pub(crate) unsafe fn new_(gamepad: *const u8) -> Self {
Self(gamepad)
}
pub fn state(&self) -> GamepadState {
let gamepad = unsafe { *self.0 };

GamepadState {
buttons: [
gamepad & BUTTON_1 != 0,
gamepad & BUTTON_2 != 0,
],
dpad: Directions {
up: gamepad & BUTTON_UP != 0,
down: gamepad & BUTTON_DOWN != 0,
left: gamepad & BUTTON_LEFT != 0,
right: gamepad & BUTTON_RIGHT != 0,
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct GamepadState {
pub buttons: [bool; 2],
pub dpad: Directions,
}
impl GamepadState {
pub fn clean(self) -> Self {
GamepadState {
buttons: self.buttons,
dpad: Directions {
up: self.dpad.up && !self.dpad.down,
down: self.dpad.down && !self.dpad.up,
left: self.dpad.left && !self.dpad.right,
right: self.dpad.right && !self.dpad.left,
},
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Directions {
up: bool,
down: bool,
left: bool,
right: bool,
}
72 changes: 60 additions & 12 deletions wasm4/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,76 @@ impl Framebuffer {
unsafe { &*(wasm4_sys::FRAMEBUFFER.cast::<[Cell<u8>; 6400]>()) }
}

pub fn line(&self, start: [i32; 2], end: [i32; 2]) {
unsafe { wasm4_sys::line(start[0], start[1], end[0], end[1]) }
pub fn line(&self, start: [i32; 2], end: [i32; 2], color: DrawIndex) {
unsafe {
wasm4_sys::DRAW_COLORS.write(DrawIndices::from_array([
color,
Default::default(),
Default::default(),
Default::default(),
]).into());
wasm4_sys::line(start[0], start[1], end[0], end[1]);
}
}

pub fn hline(&self, start: [i32; 2], len: u32) {
unsafe { wasm4_sys::hline(start[0], start[1], len) }
pub fn hline(&self, start: [i32; 2], len: u32, color: DrawIndex) {
unsafe {
wasm4_sys::DRAW_COLORS.write(DrawIndices::from_array([
color,
Default::default(),
Default::default(),
Default::default(),
]).into());
wasm4_sys::hline(start[0], start[1], len);
}
}

pub fn vline(&self, start: [i32; 2], len: u32) {
unsafe { wasm4_sys::vline(start[0], start[1], len) }
pub fn vline(&self, start: [i32; 2], len: u32, color: DrawIndex) {
unsafe {
wasm4_sys::DRAW_COLORS.write(DrawIndices::from_array([
color,
Default::default(),
Default::default(),
Default::default(),
]).into());
wasm4_sys::vline(start[0], start[1], len);
}
}

pub fn oval(&self, start: [i32; 2], shape: [u32; 2]) {
unsafe { wasm4_sys::oval(start[0], start[1], shape[0], shape[1]) }
pub fn oval(&self, start: [i32; 2], shape: [u32; 2], fill: DrawIndex, outline: DrawIndex) {
unsafe {
wasm4_sys::DRAW_COLORS.write(DrawIndices::from_array([
fill,
outline,
Default::default(),
Default::default(),
]).into());
wasm4_sys::oval(start[0], start[1], shape[0], shape[1]);
}
}

pub fn rect(&self, start: [i32; 2], shape: [u32; 2]) {
unsafe { wasm4_sys::rect(start[0], start[1], shape[0], shape[1]) }
pub fn rect(&self, start: [i32; 2], shape: [u32; 2], fill: DrawIndex, outline: DrawIndex) {
unsafe {
wasm4_sys::DRAW_COLORS.write(DrawIndices::from_array([
fill,
outline,
Default::default(),
Default::default(),
]).into());
wasm4_sys::rect(start[0], start[1], shape[0], shape[1]);
}
}

pub fn text(&self, text: &str, start: [i32; 2]) {
unsafe { wasm4_sys::textUtf8(text.as_ptr(), text.len(), start[0], start[1]) }
pub fn text(&self, text: &str, start: [i32; 2], fg: DrawIndex, bg: DrawIndex) {
unsafe {
wasm4_sys::DRAW_COLORS.write(DrawIndices::from_array([
fg,
bg,
Default::default(),
Default::default(),
]).into());
wasm4_sys::textUtf8(text.as_ptr(), text.len(), start[0], start[1]);
}
}

pub fn blit(&self, sprite: &impl Blit, start: [i32; 2], transform: BlitTransform) {
Expand Down
25 changes: 25 additions & 0 deletions wasm4/src/format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#[macro_export]
macro_rules! tracef {
($($arg:tt)*) => {{
$crate::trace($crate::format::format_no_std::show(
unsafe { match &mut $crate::format::BUF_SLICE {
Some(slice) => slice,
None => panic!("Logger not initialized"),
}},
::core::format_args!($($arg)*)
).unwrap());
}};
}

pub use format_no_std;

pub static mut BUF_SLICE: Option<&mut [u8]> = None;

pub struct Log;
impl Log {
pub(crate) fn new_() -> Self { Log }
pub fn init(self, buf: &'static mut [u8]) {
unsafe { BUF_SLICE = Some(buf) };
}
}

4 changes: 4 additions & 0 deletions wasm4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ pub mod __private;
pub mod draw;
pub mod rt;
pub mod sound;
pub mod control;
mod utils;

pub use self::utils::OutOfDomainError;
pub use wasm4_sys as sys;

#[cfg(feature = "tracef")]
pub mod format;

pub fn trace(msg: &str) {
unsafe { sys::traceUtf8(msg.as_ptr(), msg.len()) }
}
14 changes: 14 additions & 0 deletions wasm4/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ pub trait Runtime {
pub struct Resources {
pub sound: crate::sound::Audio,
pub framebuffer: crate::draw::Framebuffer,
pub controls: crate::control::Controls,
#[cfg(feature = "tracef")]
pub logger: crate::format::Log,
}

#[doc(hidden)]
Expand All @@ -18,6 +21,17 @@ impl Resources {
Resources {
sound: crate::sound::Audio(()),
framebuffer: crate::draw::Framebuffer::new_(),
controls: crate::control::Controls {
mouse: crate::control::Mouse::new_(),
gamepads: [
crate::control::Gamepad::new_(wasm4_sys::GAMEPAD1),
crate::control::Gamepad::new_(wasm4_sys::GAMEPAD2),
crate::control::Gamepad::new_(wasm4_sys::GAMEPAD3),
crate::control::Gamepad::new_(wasm4_sys::GAMEPAD4),
],
},
#[cfg(feature = "tracef")]
logger: crate::format::Log::new_(),
}
}
}
Expand Down