Init skeleton project
This commit is contained in:
parent
feacad0f22
commit
0961572000
|
@ -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",
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
/target
|
|
@ -0,0 +1,16 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "buddy-alloc"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3240a4cb09cf0da6a51641bd40ce90e96ea6065e3a1adc46434029254bcc2d09"
|
||||
|
||||
[[package]]
|
||||
name = "cart"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"buddy-alloc",
|
||||
]
|
|
@ -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"]
|
|
@ -0,0 +1,26 @@
|
|||
# ld53
|
||||
|
||||
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!
|
|
@ -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)
|
||||
};
|
|
@ -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);
|
||||
}
|
|
@ -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<[u8]>>(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);
|
||||
}
|
Loading…
Reference in New Issue