This repository was archived by the owner on Jan 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WASM-4: create Pinput test cartridge project
- Loading branch information
1 parent
74a7ed9
commit 85e5240
Showing
9 changed files
with
350 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,5 @@ | |
/web/extension/logo-*.png | ||
|
||
/release/artifacts/* | ||
|
||
/WASM-4/pinput_tester/target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
[build] | ||
target = "wasm32-unknown-unknown" | ||
|
||
[target.wasm32-unknown-unknown] | ||
rustflags = [ | ||
# Import memory from WASM-4 | ||
"-C", "link-arg=--import-memory", | ||
"-C", "link-arg=--initial-memory=65536", | ||
"-C", "link-arg=--max-memory=65536", | ||
|
||
# Temporary workaround for #255 issue. | ||
# Reserve 8192 bytes of Rust stack space, offset from 6560. | ||
# Bump this value, 16-byte aligned, if the framebuffer gets corrupted. | ||
"-C", "link-arg=-zstack-size=14752", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/target |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[package] | ||
name = "cart" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[lib] | ||
crate-type = ["cdylib"] | ||
|
||
[dependencies] | ||
buddy-alloc = { version = "0.4.1", optional = true } | ||
|
||
[profile.release] | ||
opt-level = "z" | ||
lto = true | ||
|
||
[features] | ||
# use `--no-default-features` or comment out next line to disable allocator | ||
default = ["buddy-alloc"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# pinput_tester | ||
|
||
A game written in Rust for the [WASM-4](https://wasm4.org) fantasy console. | ||
|
||
## Building | ||
|
||
Build the cart by running: | ||
|
||
```shell | ||
cargo build --release | ||
``` | ||
|
||
Then run it with: | ||
|
||
```shell | ||
w4 run target/wasm32-unknown-unknown/release/cart.wasm | ||
``` | ||
|
||
For more info about setting up WASM-4, see the [quickstart guide](https://wasm4.org/docs/getting-started/setup?code-lang=rust#quickstart). | ||
|
||
## Links | ||
|
||
- [Documentation](https://wasm4.org/docs): Learn more about WASM-4. | ||
- [Snake Tutorial](https://wasm4.org/docs/tutorials/snake/goal): Learn how to build a complete game | ||
with a step-by-step tutorial. | ||
- [GitHub](https://github.com/aduros/wasm4): Submit an issue or PR. Contributions are welcome! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use buddy_alloc::{BuddyAllocParam, FastAllocParam, NonThreadsafeAlloc}; | ||
|
||
// These values can be tuned | ||
const FAST_HEAP_SIZE: usize = 4 * 1024; // 4 KB | ||
const HEAP_SIZE: usize = 16 * 1024; // 16 KB | ||
const LEAF_SIZE: usize = 16; | ||
|
||
static mut FAST_HEAP: [u8; FAST_HEAP_SIZE] = [0u8; FAST_HEAP_SIZE]; | ||
static mut HEAP: [u8; HEAP_SIZE] = [0u8; HEAP_SIZE]; | ||
|
||
#[global_allocator] | ||
static ALLOC: NonThreadsafeAlloc = unsafe { | ||
let fast_param = FastAllocParam::new(FAST_HEAP.as_ptr(), FAST_HEAP_SIZE); | ||
let buddy_param = BuddyAllocParam::new(HEAP.as_ptr(), HEAP_SIZE, LEAF_SIZE); | ||
NonThreadsafeAlloc::new(fast_param, buddy_param) | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#[cfg(feature = "buddy-alloc")] | ||
mod alloc; | ||
mod wasm4; | ||
use wasm4::*; | ||
|
||
#[rustfmt::skip] | ||
const SMILEY: [u8; 8] = [ | ||
0b11000011, | ||
0b10000001, | ||
0b00100100, | ||
0b00100100, | ||
0b00000000, | ||
0b00100100, | ||
0b10011001, | ||
0b11000011, | ||
]; | ||
|
||
#[no_mangle] | ||
fn update() { | ||
unsafe { *DRAW_COLORS = 2 } | ||
text("Hello from Rust!", 10, 10); | ||
|
||
let gamepad = unsafe { *GAMEPAD1 }; | ||
if gamepad & BUTTON_1 != 0 { | ||
unsafe { *DRAW_COLORS = 4 } | ||
} | ||
|
||
blit(&SMILEY, 76, 76, 8, 8, BLIT_1BPP); | ||
text("Press X to blink", 16, 90); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
// | ||
// WASM-4: https://wasm4.org/docs | ||
|
||
#![allow(unused)] | ||
|
||
// ┌───────────────────────────────────────────────────────────────────────────┐ | ||
// │ │ | ||
// │ Platform Constants │ | ||
// │ │ | ||
// └───────────────────────────────────────────────────────────────────────────┘ | ||
|
||
pub const SCREEN_SIZE: u32 = 160; | ||
|
||
// ┌───────────────────────────────────────────────────────────────────────────┐ | ||
// │ │ | ||
// │ Memory Addresses │ | ||
// │ │ | ||
// └───────────────────────────────────────────────────────────────────────────┘ | ||
|
||
pub const PALETTE: *mut [u32; 4] = 0x04 as *mut [u32; 4]; | ||
pub const DRAW_COLORS: *mut u16 = 0x14 as *mut u16; | ||
pub const GAMEPAD1: *const u8 = 0x16 as *const u8; | ||
pub const GAMEPAD2: *const u8 = 0x17 as *const u8; | ||
pub const GAMEPAD3: *const u8 = 0x18 as *const u8; | ||
pub const GAMEPAD4: *const u8 = 0x19 as *const u8; | ||
pub const MOUSE_X: *const i16 = 0x1a as *const i16; | ||
pub const MOUSE_Y: *const i16 = 0x1c as *const i16; | ||
pub const MOUSE_BUTTONS: *const u8 = 0x1e as *const u8; | ||
pub const SYSTEM_FLAGS: *mut u8 = 0x1f as *mut u8; | ||
pub const NETPLAY: *const u8 = 0x20 as *const u8; | ||
pub const FRAMEBUFFER: *mut [u8; 6400] = 0xa0 as *mut [u8; 6400]; | ||
|
||
pub const BUTTON_1: u8 = 1; | ||
pub const BUTTON_2: u8 = 2; | ||
pub const BUTTON_LEFT: u8 = 16; | ||
pub const BUTTON_RIGHT: u8 = 32; | ||
pub const BUTTON_UP: u8 = 64; | ||
pub const BUTTON_DOWN: u8 = 128; | ||
|
||
pub const MOUSE_LEFT: u8 = 1; | ||
pub const MOUSE_RIGHT: u8 = 2; | ||
pub const MOUSE_MIDDLE: u8 = 4; | ||
|
||
pub const SYSTEM_PRESERVE_FRAMEBUFFER: u8 = 1; | ||
pub const SYSTEM_HIDE_GAMEPAD_OVERLAY: u8 = 2; | ||
|
||
// ┌───────────────────────────────────────────────────────────────────────────┐ | ||
// │ │ | ||
// │ Drawing Functions │ | ||
// │ │ | ||
// └───────────────────────────────────────────────────────────────────────────┘ | ||
|
||
/// Copies pixels to the framebuffer. | ||
pub fn blit(sprite: &[u8], x: i32, y: i32, width: u32, height: u32, flags: u32) { | ||
unsafe { extern_blit(sprite.as_ptr(), x, y, width, height, flags) } | ||
} | ||
extern "C" { | ||
#[link_name = "blit"] | ||
fn extern_blit(sprite: *const u8, x: i32, y: i32, width: u32, height: u32, flags: u32); | ||
} | ||
|
||
/// Copies a subregion within a larger sprite atlas to the framebuffer. | ||
#[allow(clippy::too_many_arguments)] | ||
pub fn blit_sub( | ||
sprite: &[u8], | ||
x: i32, | ||
y: i32, | ||
width: u32, | ||
height: u32, | ||
src_x: u32, | ||
src_y: u32, | ||
stride: u32, | ||
flags: u32, | ||
) { | ||
unsafe { | ||
extern_blit_sub( | ||
sprite.as_ptr(), | ||
x, | ||
y, | ||
width, | ||
height, | ||
src_x, | ||
src_y, | ||
stride, | ||
flags, | ||
) | ||
} | ||
} | ||
extern "C" { | ||
#[link_name = "blitSub"] | ||
fn extern_blit_sub( | ||
sprite: *const u8, | ||
x: i32, | ||
y: i32, | ||
width: u32, | ||
height: u32, | ||
src_x: u32, | ||
src_y: u32, | ||
stride: u32, | ||
flags: u32, | ||
); | ||
} | ||
|
||
pub const BLIT_2BPP: u32 = 1; | ||
pub const BLIT_1BPP: u32 = 0; | ||
pub const BLIT_FLIP_X: u32 = 2; | ||
pub const BLIT_FLIP_Y: u32 = 4; | ||
pub const BLIT_ROTATE: u32 = 8; | ||
|
||
/// Draws a line between two points. | ||
pub fn line(x1: i32, y1: i32, x2: i32, y2: i32) { | ||
unsafe { extern_line(x1, y1, x2, y2) } | ||
} | ||
extern "C" { | ||
#[link_name = "line"] | ||
fn extern_line(x1: i32, y1: i32, x2: i32, y2: i32); | ||
} | ||
|
||
/// Draws an oval (or circle). | ||
pub fn oval(x: i32, y: i32, width: u32, height: u32) { | ||
unsafe { extern_oval(x, y, width, height) } | ||
} | ||
extern "C" { | ||
#[link_name = "oval"] | ||
fn extern_oval(x: i32, y: i32, width: u32, height: u32); | ||
} | ||
|
||
/// Draws a rectangle. | ||
pub fn rect(x: i32, y: i32, width: u32, height: u32) { | ||
unsafe { extern_rect(x, y, width, height) } | ||
} | ||
extern "C" { | ||
#[link_name = "rect"] | ||
fn extern_rect(x: i32, y: i32, width: u32, height: u32); | ||
} | ||
|
||
/// Draws text using the built-in system font. | ||
pub fn text<T: AsRef<str>>(text: T, x: i32, y: i32) { | ||
let text_ref = text.as_ref(); | ||
unsafe { extern_text(text_ref.as_ptr(), text_ref.len(), x, y) } | ||
} | ||
extern "C" { | ||
#[link_name = "textUtf8"] | ||
fn extern_text(text: *const u8, length: usize, x: i32, y: i32); | ||
} | ||
|
||
/// Draws a vertical line | ||
pub fn vline(x: i32, y: i32, len: u32) { | ||
unsafe { | ||
extern_vline(x, y, len); | ||
} | ||
} | ||
|
||
extern "C" { | ||
#[link_name = "vline"] | ||
fn extern_vline(x: i32, y: i32, len: u32); | ||
} | ||
|
||
/// Draws a horizontal line | ||
pub fn hline(x: i32, y: i32, len: u32) { | ||
unsafe { | ||
extern_hline(x, y, len); | ||
} | ||
} | ||
|
||
extern "C" { | ||
#[link_name = "hline"] | ||
fn extern_hline(x: i32, y: i32, len: u32); | ||
} | ||
|
||
// ┌───────────────────────────────────────────────────────────────────────────┐ | ||
// │ │ | ||
// │ Sound Functions │ | ||
// │ │ | ||
// └───────────────────────────────────────────────────────────────────────────┘ | ||
|
||
/// Plays a sound tone. | ||
pub fn tone(frequency: u32, duration: u32, volume: u32, flags: u32) { | ||
unsafe { extern_tone(frequency, duration, volume, flags) } | ||
} | ||
extern "C" { | ||
#[link_name = "tone"] | ||
fn extern_tone(frequency: u32, duration: u32, volume: u32, flags: u32); | ||
} | ||
|
||
pub const TONE_PULSE1: u32 = 0; | ||
pub const TONE_PULSE2: u32 = 1; | ||
pub const TONE_TRIANGLE: u32 = 2; | ||
pub const TONE_NOISE: u32 = 3; | ||
pub const TONE_MODE1: u32 = 0; | ||
pub const TONE_MODE2: u32 = 4; | ||
pub const TONE_MODE3: u32 = 8; | ||
pub const TONE_MODE4: u32 = 12; | ||
pub const TONE_PAN_LEFT: u32 = 16; | ||
pub const TONE_PAN_RIGHT: u32 = 32; | ||
|
||
// ┌───────────────────────────────────────────────────────────────────────────┐ | ||
// │ │ | ||
// │ Storage Functions │ | ||
// │ │ | ||
// └───────────────────────────────────────────────────────────────────────────┘ | ||
|
||
extern "C" { | ||
/// Reads up to `size` bytes from persistent storage into the pointer `dest`. | ||
pub fn diskr(dest: *mut u8, size: u32) -> u32; | ||
|
||
/// Writes up to `size` bytes from the pointer `src` into persistent storage. | ||
pub fn diskw(src: *const u8, size: u32) -> u32; | ||
} | ||
|
||
// ┌───────────────────────────────────────────────────────────────────────────┐ | ||
// │ │ | ||
// │ Other Functions │ | ||
// │ │ | ||
// └───────────────────────────────────────────────────────────────────────────┘ | ||
|
||
/// Prints a message to the debug console. | ||
pub fn trace<T: AsRef<str>>(text: T) { | ||
let text_ref = text.as_ref(); | ||
unsafe { extern_trace(text_ref.as_ptr(), text_ref.len()) } | ||
} | ||
extern "C" { | ||
#[link_name = "traceUtf8"] | ||
fn extern_trace(trace: *const u8, length: usize); | ||
} |