Last active
December 26, 2021 12:25
-
-
Save edubart/db77f5c89a8443e3f2be0cf588fdc3d2 to your computer and use it in GitHub Desktop.
WASM4 Nelua template
This file contains hidden or 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
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) |
This file contains hidden or 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
-- 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