Skip to content

Instantly share code, notes, and snippets.

@edubart
Last active December 26, 2021 12:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edubart/db77f5c89a8443e3f2be0cf588fdc3d2 to your computer and use it in GitHub Desktop.
Save edubart/db77f5c89a8443e3f2be0cf588fdc3d2 to your computer and use it in GitHub Desktop.
WASM4 Nelua template
require "wasm4"
local smiley: []uint8 = {
0b11000011,
0b10000001,
0b00100100,
0b00100100,
0b00000000,
0b00100100,
0b10011001,
0b11000011,
};
local function update(): void
$DRAW_COLORS = 2
text("Hello from Nelua!", 10, 10)
local gamepad = $GAMEPAD1
if gamepad & BUTTON_1 ~= 0 then
$DRAW_COLORS = 4
end
blit(&smiley, 76, 76, 8, 8, BLIT_1BPP)
text("Press X! to blink", 16, 90)
end
## setup_wasm4_callbacks(update)
-- WASM-4: https://wasm4.org/docs
-- Configure compiler.
-- NOTE: This must come first because it changes some compiler settings!
##[[
ldflags "-Wl,-zstack-size=2048,--no-entry,--import-memory -mexec-model=reactor"
ldflags "-Wl,--initial-memory=65536,--max-memory=65536,--global-base=6560,--export-dynamic"
if DEBUG then
-- We should use at least 01 optimization, otherwise the application may use too much stack space.
cflags "-O1 -g"
ldflags "-Wl,--export-all,--no-gc-sections"
else
-- Optimization for the making the application small as possible.
cflags "-Oz -g0 -flto"
ldflags "-Wl,--strip-all,--gc-sections,--lto-O3"
end
-- Generates an illegal instruction on aborts/panics
context.rootpragmas.abort = "trap"
-- We will not write to stdout, instead any write to it will be hooked.
context.rootpragmas.writestderr = "hooked"
-- We don't need to emit `main()` entry point, we will hook this ourselves.
context.rootpragmas.nogcentry = true
-- Bundle `snprintf` (used by `string.format`).
context.rootpragmas.usenanoprintf = true
]]
-- ┌───────────────────────────────────────────────────────────────────────────┐
-- │ │
-- │ Platform Constants │
-- │ │
-- └───────────────────────────────────────────────────────────────────────────┘
global SCREEN_SIZE <comptime> = 160
-- ┌───────────────────────────────────────────────────────────────────────────┐
-- │ │
-- │ Memory Addresses │
-- │ │
-- └───────────────────────────────────────────────────────────────────────────┘
global PALETTE = (@*[4]uint32)(0x04)
global DRAW_COLORS <comptime> = (@*uint16)(0x14)
global GAMEPAD1 <comptime> = (@*uint8)(0x16)
global GAMEPAD2 <comptime> = (@*uint8)(0x17)
global GAMEPAD3 <comptime> = (@*uint8)(0x18)
global GAMEPAD4 <comptime> = (@*uint8)(0x19)
global MOUSE_X <comptime> = (@*int16)(0x1a)
global MOUSE_Y <comptime> = (@*int16)(0x1c)
global MOUSE_BUTTONS <comptime> = (@*uint8)(0x1e)
global SYSTEM_FLAGS <comptime> = (@*uint8)(0x1f)
global FRAMEBUFFER = (@*[6400]uint8)(0xa0)
global BUTTON_1 <comptime> = 1
global BUTTON_2 <comptime> = 2
global BUTTON_LEFT <comptime> = 16
global BUTTON_RIGHT <comptime> = 32
global BUTTON_UP <comptime> = 64
global BUTTON_DOWN <comptime> = 128
global MOUSE_LEFT <comptime> = 1
global MOUSE_RIGHT <comptime> = 2
global MOUSE_MIDDLE <comptime> = 4
global SYSTEM_PRESERVE_FRAMEBUFFER <comptime> = 1
global SYSTEM_HIDE_GAMEPAD_OVERLAY <comptime> = 2
-- ┌───────────────────────────────────────────────────────────────────────────┐
-- │ │
-- │ Drawing Functions │
-- │ │
-- └───────────────────────────────────────────────────────────────────────────┘
-- Copies pixels to the framebuffer.
global function blit(data: *uint8 <const> , x: int32, y: int32, width: uint32, height: uint32, flags: uint32): void <cimport,cattribute'import_name("blit")'> end
-- Copies a subregion within a larger sprite atlas to the framebuffer.
global function blitSub(data: *uint8 <const>, x: int32, y: int32, width: uint32, height: uint32, srcX: uint32, srcY: uint32, stride: uint32, flags: uint32): void <cimport,cattribute'import_name("blitSub")'> end
global BLIT_2BPP <comptime> = 1
global BLIT_1BPP <comptime> = 0
global BLIT_FLIP_X <comptime> = 2
global BLIT_FLIP_Y <comptime> = 4
global BLIT_ROTATE <comptime> = 8
-- Draws a line between two points.
global function line(x: int32, y: int32, width: uint32, height: uint32): void <cimport,cattribute'import_name("line")'> end
-- Draws a horizontal line.
global function hline(x: int32, y: int32, len: uint32): void <cimport,cattribute'import_name("hline")'> end
-- Draws a vertical line.
global function vline(x: int32, y: int32, len: uint32): void <cimport,cattribute'import_name("vline")'> end
-- Draws an oval (or circle).
global function oval(x: int32, y: int32, width: uint32, height: uint32): void <cimport,cattribute'import_name("oval")'> end
-- Draws a rectangle.
global function rect(x: int32, y: int32, width: uint32, height: uint32): void <cimport,cattribute'import_name("rect")'> end
-- Draws text using the built-in system font.
global function text(str: cstring <const>, x: int32, y: int32): void <cimport,cattribute'import_name("text")'> end
-- ┌───────────────────────────────────────────────────────────────────────────┐
-- │ │
-- │ Sound Functions │
-- │ │
-- └───────────────────────────────────────────────────────────────────────────┘
-- Plays a sound tone.
global function tone(frequency: uint32, duration: uint32, volume: uint32, flags: uint32): void <cimport,cattribute'import_name("tone")'> end
global TONE_PULSE1 <comptime> = 0
global TONE_PULSE2 <comptime> = 1
global TONE_TRIANGLE <comptime> = 2
global TONE_NOISE <comptime> = 3
global TONE_MODE1 <comptime> = 0
global TONE_MODE2 <comptime> = 4
global TONE_MODE3 <comptime> = 8
global TONE_MODE4 <comptime> = 12
-- ┌───────────────────────────────────────────────────────────────────────────┐
-- │ │
-- │ Storage Functions │
-- │ │
-- └───────────────────────────────────────────────────────────────────────────┘
-- Reads up to `size` bytes from persistent storage into the pointer `dest`.
global function diskr(dest: *void, size: uint32): uint32 <cimport,cattribute'import_name("diskr")'> end
-- Writes up to `size` bytes from the pointer `src` into persistent storage.
global function diskw(src: *void <const>, size: uint32): uint32 <cimport,cattribute'import_name("diskw")'> end
-- ┌───────────────────────────────────────────────────────────────────────────┐
-- │ │
-- │ Trace functions │
-- │ │
-- └───────────────────────────────────────────────────────────────────────────┘
-- Prints a message to the debug console.
global function trace(str: cstring <const>): void <cimport,cattribute'import_name("trace")'> end
-- Prints a message to the debug console (C style printf).
global function tracef(format: cstring, ...: cvarargs): void <cimport,cattribute'import_name("tracef"),__format__ (__printf__, 1, 2)'> end
-- ┌───────────────────────────────────────────────────────────────────────────┐
-- │ │
-- │ Nelua hooks and compiler configuration │
-- │ │
-- └───────────────────────────────────────────────────────────────────────────┘
## if not pragmas.nogc then
require 'allocators.gc'
## end
require "stringbuilder" -- for `print()`
-- Hook runtime errors to write using `trace()` instead of writing to C `stderr`.
local function write_stderr(msg: cstring, len: usize, flush: boolean): void <codename "nelua_write_stderr">
trace(msg)
end
-- Replace global print function to write using `trace()` instead of writing to C `stdout`.
global function print(...: varargs)
local sb: stringbuilder <close>
## for i=1,select('#', ...) do
## if i > 1 then
sb:write('\t')
## end
sb:write(#[select(i, ...)]#)
## end
trace(sb:view())
end
-- Macro used to install `update` and `_start` WASM4 callbacks.
## function setup_wasm4_callbacks(update)
## static_assert(update, 'please declare update function!')
local function _update(): void <cexport,codename'update'>
#[update]#()
## if not pragmas.nogc then
-- We must always manually call garbage collection in the end of every frame.
-- This is the only safe point to do so, because in WASM we cannot scan the function stack.
gc:step()
## end
end
-- Hook application entry point.
local function _start(): void <cexport,entrypoint>
## if not pragmas.nogc then
-- The GC should be initialized as the first thing.
gc:init(nilptr)
## end
local function nelua_main(argc: cint, argv: *cstring): cint <cimport,nodecl> end
-- This will all code in top scopes.
nelua_main(0,nilptr)
end
## end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment