I just found out about the in development fantasy console
https://github.com/pgattic/wasm-experiment
Since I'm on Pop_OS! which is currently based on 24.04 I need to install a newer
version of cmake than what is in the default repos:
- https://apt.kitware.com/ (Following
For Ubuntu Noble Numbat (24.04)instructions)
I installed SDL3 from source, such as what is described in this article:
This tool is written in Rust, so I just had to cargo build --release and then symlink the resulting binary to somewhere in my $PATH
$ export WASM3_SOURCE=/home/peter/Code/GitHub/wasm3/wasm3
$ CC="zig cc -fno-sanitize=undefined" cmake -S . -B build/linux -DCMAKE_C_FLAGS="-std=c23" -DCMAKE_C_FLAGS="-D_GNU_SOURCE"[package]
name = "wc-zig"
author = "Peter Hellberg"
version = "0.0.1"
[build.code]
command = ["zig", "build"]
output = "zig-out/bin/cart.wasm"
[build.assets]
dir = "assets"
sprite_tiles = "spr.4bpp"
background_tiles = "bg.4bpp"
background_map = "bg.map"const std = @import("std");
pub fn build(b: *std.Build) !void {
const mod = b.createModule(.{
.root_source_file = b.path("src/cart.zig"),
.target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.os_tag = .wasi,
}),
.optimize = .ReleaseSmall,
});
mod.export_symbol_names = &[_][]const u8{
"setup",
"update",
};
const exe = b.addExecutable(.{
.name = "cart",
.root_module = mod,
});
exe.entry = .disabled;
exe.import_memory = false;
b.installArtifact(exe);
}pub extern "env" fn _rand() u32;
pub extern "env" fn _clearScreen(c: u8) void;
pub extern "env" fn _pSet(x: i32, y: i32, c: u8) void;
pub extern "env" fn _rect(x: i32, y: i32, w: u32, h: u32, c: u8) void;
pub extern "env" fn _rectFill(x: i32, y: i32, w: u32, h: u32, c: u8) void;
pub extern "env" fn _sprite(x: i32, y: i32, id: u8) void;
pub extern "env" fn _btn(btn: u8) bool;
pub extern "env" fn _btnP(btn: u8) bool;
pub extern "env" fn _printLnDbg(ptr: usize) void;
pub fn rand() u32 {
return _rand();
}
pub fn clearScreen(c: u8) void {
_clearScreen(c);
}
pub fn pSet(x: i32, y: i32, c: u8) void {
_pSet(x, y, c);
}
pub fn rect(x: i32, y: i32, w: u32, h: u32, c: u8) void {
_rect(x, y, w, h, c);
}
pub fn rectFill(x: i32, y: i32, w: u32, h: u32, c: u8) void {
_rectFill(x, y, w, h, c);
}
pub fn sprite(x: i32, y: i32, id: u8) void {
_sprite(x, y, id);
}
pub const Button = enum(u8) {
Left = 0,
Right = 1,
Up = 2,
Down = 3,
A = 4,
B = 5,
X = 6,
Y = 7,
L = 8,
R = 9,
Start = 10,
Select = 11,
};
pub fn btn(button: Button) bool {
return _btn(@intFromEnum(button));
}
pub fn btnP(button: Button) bool {
return _btnP(@intFromEnum(button));
}
pub fn print(str: []const u8) void {
_printLnDbg(@intFromPtr(str.ptr));
}const wc = @import("wc.zig");
export fn setup() void {
wc.print("Hello from Zig!");
}
export fn update() void {
const w = 24;
const h = 24;
wc.clearScreen(0);
wc.rectFill(12, 12, w, h, 1);
wc.rectFill(24, 24, w, h, 2);
wc.rectFill(36, 36, w, h, 3);
wc.rectFill(48, 48, w, h, 4);
wc.rectFill(60, 60, w, h, 5);
}
Updated
src/wc.zig