add Nim Wasm template (#2645)
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
# Nim Starter Project Template
|
||||
|
||||
This is a Nim / TIC-80 starter template. To build wasm binary and import it into
|
||||
the 'cart.tic' file, ensure you have a Nim compiler, Wasi-SDK and Tic-80 on your system and run:
|
||||
|
||||
```
|
||||
nimble buildcart
|
||||
```
|
||||
|
||||
Run `nimble tasks` command to see more build options.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Package
|
||||
|
||||
version = "0.1.0"
|
||||
author = "archargelod"
|
||||
description = "tic80 wasm template for Nim language"
|
||||
license = "MIT"
|
||||
srcDir = "src"
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
requires "nim >= 2.0.0"
|
||||
|
||||
# Tasks
|
||||
import std/strformat
|
||||
|
||||
let pwd = getCurrentDir()
|
||||
|
||||
task wasmbuild, "Build wasm binary (debug)":
|
||||
exec("nim c -o:cart.wasm src/cart")
|
||||
|
||||
task wasmrelease, "Build wasm binary (release)":
|
||||
exec("nim c -d:release -o:cart.wasm src/cart")
|
||||
|
||||
task buildcart, "Build optimized wasm binary and import it to tic80 cart":
|
||||
rmFile("cart.tic")
|
||||
exec("nim c -d:release -o:cart.wasm src/cart")
|
||||
exec(&"tic80 --cli --fs=\"{pwd}\" --cmd=\"load src/cart.tic & import binary cart.wasm & save cart.tic & exit\"")
|
||||
|
||||
task runcart, "Build optimized wasm binary and run it with tic80":
|
||||
rmFile("cart.tic")
|
||||
exec("nim c -d:release -o:cart.wasm src/cart")
|
||||
exec(&"tic80 --skip --fs=\"{pwd}\" --cmd=\"load src/cart.tic & import binary cart.wasm & save cart.tic & run\"")
|
||||
|
||||
task debugcart, "Build wasm binary in debug mode and run it with tic80":
|
||||
rmFile("cart.tic")
|
||||
exec("nim c -o:cart.wasm src/cart")
|
||||
exec(&"tic80 --skip --fs=\"{pwd}\" --cmd=\"load src/cart.tic & import binary cart.wasm & save cart.tic & run\"")
|
||||
@@ -0,0 +1,52 @@
|
||||
import std/os
|
||||
|
||||
let wasi = getEnv("WASI_SDK_PATH")
|
||||
if wasi == "" and not defined(nimsuggest):
|
||||
echo ""
|
||||
echo "Error:"
|
||||
echo "Download the WASI SDK (https://github.com/WebAssembly/wasi-sdk) and set the $WASI_SDK_PATH environment variable!"
|
||||
echo ""
|
||||
quit(-1)
|
||||
|
||||
switch("cpu", "wasm32")
|
||||
switch("cc", "clang")
|
||||
switch("threads", "off")
|
||||
|
||||
# ARC is much more embedded-friendly
|
||||
switch("gc", "arc")
|
||||
# Treats defects as errors, results in smaller binary size
|
||||
switch("panics", "on")
|
||||
|
||||
# Use the common ANSI C target
|
||||
switch("os", "any")
|
||||
# Needed for os:any
|
||||
switch("define", "posix")
|
||||
|
||||
# WASM has no signal handlers
|
||||
switch("define", "noSignalHandler")
|
||||
# The only entrypoints are start and update
|
||||
switch("noMain")
|
||||
# Use malloc instead of Nim's memory allocator, makes binary size much smaller
|
||||
switch("define", "useMalloc")
|
||||
|
||||
switch("clang.exe", wasi / "bin" / "clang")
|
||||
switch("clang.linkerexe", wasi / "bin" / "clang")
|
||||
|
||||
switch("passC", "--sysroot=" & (wasi / "share" / "wasi-sysroot"))
|
||||
|
||||
switch("passL", "-Wl,-zstack-size=8192,--no-entry,--import-memory -mexec-model=reactor -Wl,--initial-memory=262144,--max-memory=262144,--global-base=98304")
|
||||
|
||||
when not defined(release):
|
||||
switch("assertions", "off")
|
||||
switch("checks", "off")
|
||||
switch("stackTrace", "off")
|
||||
switch("lineTrace", "off")
|
||||
switch("lineDir", "off")
|
||||
switch("debugger", "native")
|
||||
# This is needed to remove all unused Nim functions that will in turn import
|
||||
# WASI stuff that is not available in WASM-4
|
||||
switch("passL", "-Wl,--gc-sections")
|
||||
else:
|
||||
switch("opt", "size")
|
||||
switch("passC", "-flto")
|
||||
switch("passL", "-Wl,--strip-all,--gc-sections,--lto-O3")
|
||||
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
import std/[random]
|
||||
import ../cart/tic80
|
||||
|
||||
let ToolbarHeight = 6
|
||||
|
||||
type
|
||||
Bunny = object
|
||||
x, y: float32
|
||||
width: int32 = 26
|
||||
height: int32 = 32
|
||||
speedX, speedY: float32
|
||||
sprite: int32
|
||||
FPS = object
|
||||
value, frames: int32
|
||||
lastTime: float32
|
||||
|
||||
proc getValue(f: var FPS): int32 =
|
||||
if time() - f.lastTime <= 1000:
|
||||
inc f.frames
|
||||
else:
|
||||
f.value = f.frames
|
||||
f.frames = 0
|
||||
f.lastTime = time()
|
||||
f.value
|
||||
|
||||
proc newBunny: Bunny =
|
||||
Bunny(
|
||||
x: rand(0 .. Width).float32,
|
||||
y: rand(0 .. Height).float32,
|
||||
width: 26,
|
||||
height: 32,
|
||||
speedX: rand(-100.0 .. 100.0) / 60,
|
||||
speedY: rand(-100.0 .. 100.0) / 60,
|
||||
sprite: 1,
|
||||
)
|
||||
|
||||
proc draw(b: Bunny) =
|
||||
spr(b.sprite, b.x.int32, b.y.int32, transColor=1, w=4, h=4)
|
||||
|
||||
proc update(b: var Bunny) =
|
||||
b.x += b.speedX
|
||||
b.y += b.speedY
|
||||
|
||||
if b.x.int32 + b.width > Width:
|
||||
b.x = float32(Width - b.width)
|
||||
b.speedX *= -1
|
||||
if b.x < 0:
|
||||
b.x = 0
|
||||
b.speedX *= -1
|
||||
|
||||
if b.y.int32 + b.height > Height:
|
||||
b.y = float32(Height - b.height)
|
||||
b.speedY *= -1
|
||||
if b.y < 0:
|
||||
b.y = 0
|
||||
b.speedY *= -1
|
||||
|
||||
randomize(tstamp().int64)
|
||||
|
||||
var fps: FPS
|
||||
var bunnies: seq[Bunny]
|
||||
|
||||
proc TIC {.exportWasm.} =
|
||||
cls(13)
|
||||
|
||||
if btn(P1_Up):
|
||||
for _ in 1..5:
|
||||
bunnies.add newBunny()
|
||||
|
||||
if btn(P1_Down):
|
||||
for _ in 1..5:
|
||||
if bunnies.len > 0:
|
||||
bunnies.del bunnies.high
|
||||
|
||||
for bunny in bunnies.mitems:
|
||||
bunny.update()
|
||||
|
||||
for bunny in bunnies.mitems:
|
||||
bunny.draw()
|
||||
|
||||
rect(0, 0, Width, ToolbarHeight, 0)
|
||||
print("Bunnies: " & $bunnies.len, 1, 0, 11, false, 1, false)
|
||||
print("FPS: " & $fps.getValue(), Width div 2, 0, 11, false, 1, false)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import cart/tic80
|
||||
|
||||
var
|
||||
t = 1
|
||||
x = 96
|
||||
y = 24
|
||||
|
||||
proc TIC {.exportWasm.} =
|
||||
cls(Color13)
|
||||
|
||||
if btn(P1_Up): dec y
|
||||
if btn(P1_Down): inc y
|
||||
if btn(P1_Left): dec x
|
||||
if btn(P1_Right): inc x
|
||||
|
||||
spr(1 + t mod 60 div 30 * 2, x, y, transColor=Color14, scale=3, w=2, h=2)
|
||||
print("Hello from Nim!", 84, 84)
|
||||
Binary file not shown.
@@ -0,0 +1,286 @@
|
||||
const
|
||||
TileSize* = 8
|
||||
Width* = 240
|
||||
Height* = 136
|
||||
WidthTiles* = Width div TileSize
|
||||
HeightTiles* = Height div TileSize
|
||||
Bpp* = 4 ## bits per pixel
|
||||
|
||||
type
|
||||
Key* = enum
|
||||
Key_Null, Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G, Key_H, Key_I, Key_J,
|
||||
Key_K, Key_L, Key_M, Key_N, Key_O, Key_P, Key_Q, Key_R, Key_S, Key_T, Key_U,
|
||||
Key_V, Key_W, Key_X, Key_Y, Key_Z, Key_0, Key_1, Key_2, Key_3, Key_4, Key_5,
|
||||
Key_6, Key_7, Key_8, Key_9, Key_Minus, Key_Equals, Key_Leftbracket,
|
||||
Key_Rightbracket, Key_Backslash, Key_Semicolon, Key_Apostrophe, Key_Grave,
|
||||
Key_Comma, Key_Period, Key_Slash, Key_Space, Key_Tab, Key_Return, Key_Backspace,
|
||||
Key_Delete, Key_Insert, Key_Pageup, Key_Pagedown, Key_Home, Key_End, Key_Up,
|
||||
Key_Down, Key_Left, Key_Right, Key_Capslock, Key_Ctrl, Key_Shift, Key_Alt
|
||||
|
||||
Button* = enum
|
||||
P1_Up, P1_Down, P1_Left, P1_Right, P1_A, P1_B, P1_X, P1_Y,
|
||||
P2_Up, P2_Down, P2_Left, P2_Right, P2_A, P2_B, P2_X, P2_Y,
|
||||
P3_Up, P3_Down, P3_Left, P3_Right, P3_A, P3_B, P3_X, P3_Y,
|
||||
P4_Up, P4_Down, P4_Left, P4_Right, P4_A, P4_B, P4_X, P4_Y
|
||||
|
||||
Color* = enum
|
||||
Null = -1'i8, Color0, Color1, Color2, Color3, Color4, Color5, Color6, Color7,
|
||||
Color8, Color9, Color10, Color11, Color12, Color13, Color14, Color15,
|
||||
|
||||
VRAM* {.bycopy.} = object
|
||||
screen*: array[Width * Height * Bpp div 8, uint8]
|
||||
palette*: array[48, uint8] ## 16 colors.
|
||||
palletteMap*: array[8, uint8] ## 16 indices.
|
||||
borderColorAndOvrTransparency*: uint8 ## Bank 0 is border color, bank 1 is OVR transparency.
|
||||
screenOffsetX*: int8
|
||||
screenOffsetY*: int8
|
||||
mouseCursor*: int8
|
||||
blitSegment*: uint8
|
||||
reserved*: array[3, uint8]
|
||||
|
||||
MousePos* {.bycopy.} = object
|
||||
x*: int16
|
||||
y*: int16
|
||||
scrollx*: int8
|
||||
scrolly*: int8
|
||||
left*: bool
|
||||
middle*: bool
|
||||
right*: bool
|
||||
|
||||
|
||||
## ---------------------------
|
||||
## Pointers
|
||||
## ---------------------------
|
||||
|
||||
const
|
||||
Framebuffer*: ptr Vram = cast[ptr Vram](0)
|
||||
Tiles*: ptr uint8 = cast[ptr uint8](0x04000)
|
||||
Sprites*: ptr uint8 = cast[ptr uint8](0x06000)
|
||||
Map*: ptr uint8 = cast[ptr uint8](0x08000)
|
||||
Gamepads*: ptr uint8 = cast[ptr uint8](0x0ff80)
|
||||
Mouse*: ptr uint8 = cast[ptr uint8](0x0ff84)
|
||||
Keyboard*: ptr uint8 = cast[ptr uint8](0x0ff88)
|
||||
SfxState*: ptr uint8 = cast[ptr uint8](0x0ff8c)
|
||||
SoundRegisters*: ptr uint8 = cast[ptr uint8](0x0ff9c)
|
||||
Waveforms*: ptr uint8 = cast[ptr uint8](0x0ffe4)
|
||||
Sfx*: ptr uint8 = cast[ptr uint8](0x100e4)
|
||||
MusicPatterns*: ptr uint8 = cast[ptr uint8](0x11164)
|
||||
MusicTracks*: ptr uint8 = cast[ptr uint8](0x13e64)
|
||||
SoundState*: ptr uint8 = cast[ptr uint8](0x13ffc)
|
||||
StereoVolume*: ptr uint8 = cast[ptr uint8](0x14000)
|
||||
PersistentMemory*: ptr uint8 = cast[ptr uint8](0x14004)
|
||||
SpriteFlags*: ptr uint8 = cast[ptr uint8](0x14404)
|
||||
SystemFont*: ptr uint8 = cast[ptr uint8](0x14604)
|
||||
WasmFreeRam*: ptr uint8 = cast[ptr uint8](0x18000)
|
||||
|
||||
## 160kb
|
||||
|
||||
|
||||
## ---------------------------
|
||||
## Constants
|
||||
## ---------------------------
|
||||
|
||||
const
|
||||
TilesSize*: uint32 = 0x2000
|
||||
SpritesSize*: uint32 = 0x2000
|
||||
MapSize*: uint32 = 32640
|
||||
GamepadsSize*: uint32 = 4
|
||||
MouseSize*: uint32 = 4
|
||||
KeyboardSize*: uint32 = 4
|
||||
SfxStateSize*: uint32 = 16
|
||||
SoundRegistersSize*: uint32 = 72
|
||||
WaveformsSize*: uint32 = 256
|
||||
SfxSize*: uint32 = 4224
|
||||
MusicPatternsSize*: uint32 = 11520
|
||||
MusicTracksSize*: uint32 = 408
|
||||
SoundStateSize*: uint32 = 4
|
||||
StereoVolumeSize*: uint32 = 4
|
||||
PersistentMemorySize*: uint32 = 1024
|
||||
SpriteFlagsSize*: uint32 = 512
|
||||
SystemFontSize*: uint32 = 2048
|
||||
WasmFreeRamSize*: uint32 = 163840
|
||||
|
||||
## 160kb
|
||||
|
||||
|
||||
{.push importc, codegenDecl: "__attribute__((import_name(\"$2\"))) $1 $2$3".}
|
||||
|
||||
## ---------------------------
|
||||
## Drawing Procedures
|
||||
## ---------------------------
|
||||
|
||||
proc circ*(x, y, radius: int32; color: Color)
|
||||
## Draw a filled circle.
|
||||
|
||||
proc circb*(x, y, radius: int32; color: Color)
|
||||
## Draw a circle border.
|
||||
|
||||
proc elli*(x, y, a, b: int32; color: Color)
|
||||
## Draw a filled ellipse.
|
||||
|
||||
proc ellib*(x, y, a, b: int32; color: Color)
|
||||
## Draw an ellipse border.
|
||||
|
||||
proc clip*(x, y, width, height: int32)
|
||||
## Set the screen clipping region.
|
||||
|
||||
proc cls*(color: Color = Color0)
|
||||
## Clear the screen.
|
||||
|
||||
proc font*(text: cstring; x, y: int32; trans_colors: ptr uint8; trans_count: int8,
|
||||
char_width, char_height: int8; fixed: bool; scale: int8; alt: bool): int8
|
||||
## Print a string using foreground sprite data as the font.
|
||||
|
||||
proc line*(x0, y0, x1, y1: cfloat; color: Color)
|
||||
## Draw a straight line.
|
||||
|
||||
proc map*(x, y, w, h, sx, sy: int32; trans_colors: ptr uint8; colorCount: int8;
|
||||
scale: int8; remap: int32)
|
||||
## Draw a map region.
|
||||
|
||||
proc pix*(x, y: int32; color: Color): uint8 {.discardable.}
|
||||
## Get or set the color of a single pixel.
|
||||
|
||||
proc print*(text: cstring; x, y: int32; color: Color = Color15; fixed = false;
|
||||
scale: int32 = 1; alt = false): int32 {.discardable.}
|
||||
## Print a string using the system font.
|
||||
|
||||
proc rect*(x, y, w, h: int32; color: Color)
|
||||
## Draw a filled rectangle.
|
||||
|
||||
proc rectb*(x, y, w, h: int32; color: Color)
|
||||
## Draw a rectangle border.
|
||||
|
||||
proc spr*(id, x, y: int32; trans_colors: ptr uint8; color_count: int8;
|
||||
scale, flip, rotate, w, h: int32)
|
||||
## Draw a sprite or composite sprite.
|
||||
|
||||
proc tri*(x1, y1, x2, y2, x3, y3: cfloat; color: Color)
|
||||
## Draw a filled triangle.
|
||||
|
||||
proc trib*(x1, y1, x2, y2, x3, y3: cfloat; color: Color)
|
||||
## Draw a triangle border.
|
||||
|
||||
proc ttri*(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3: cfloat; texsrc: int32;
|
||||
trans_colors: ptr uint8; color_count: int8; z1, z2, z3: cfloat; depth: bool)
|
||||
## Draw a triangle filled with texture.
|
||||
|
||||
|
||||
## ---------------------------
|
||||
## Input Functions
|
||||
## ---------------------------
|
||||
|
||||
proc btn*(button: Button): uint32
|
||||
## Get gamepad button state in current frame.
|
||||
|
||||
proc btnp*(button: Button; hold: int32 = -1; period: int32 = -1): uint32
|
||||
## Get gamepad button state according to previous frame.
|
||||
|
||||
proc key*(key: Key): bool
|
||||
## Get keyboard button state in current frame.
|
||||
|
||||
proc keyp*(key: Key; hold: int32 = -1; period: int32 = -1): bool
|
||||
## Get keyboard button state relative to previous frame.
|
||||
|
||||
proc mouse*(mouse_ptr_addy: ptr MousePos)
|
||||
## Get XY and press state of mouse/touch.
|
||||
|
||||
|
||||
## ---------------------------
|
||||
## Sound Functions
|
||||
## ---------------------------
|
||||
|
||||
proc music*(track, frame, row: int32; loop, sustain: bool; tempo, speed: int32)
|
||||
## Play or stop playing music.
|
||||
|
||||
proc sfx*(sfx_id, note, octave, duration, channel, volume_left, volume_right,
|
||||
speed: int32)
|
||||
## Play or stop playing a given sound.
|
||||
|
||||
|
||||
## ---------------------------
|
||||
## Memory Functions
|
||||
## ---------------------------
|
||||
|
||||
proc pmem*(address: int32; value: int64): uint32 {.discardable.}
|
||||
## Access or update the persistent memory.
|
||||
|
||||
proc peek*(address: int32; bits: int8 = 8): int8
|
||||
## Read a byte from an address in RAM.
|
||||
|
||||
proc peek1*(address: int32): int8
|
||||
## Read a single bit from an address in RAM.
|
||||
|
||||
proc peek2*(address: int32): int8
|
||||
## Read two bit value from an address in RAM.
|
||||
|
||||
proc peek4*(address: int32): int8
|
||||
## Read a nibble value from an address.
|
||||
|
||||
proc poke*(address: int32; value: int8; bits: int8 = 8)
|
||||
## Write a byte value to an address in RAM.
|
||||
|
||||
proc poke1*(address: int32; value: int8)
|
||||
## Write a single bit to an address in RAM.
|
||||
|
||||
proc poke2*(address: int32; value: int8)
|
||||
## Write a two bit value to an address in RAM.
|
||||
|
||||
proc poke4*(address: int32; value: int8)
|
||||
## Write a nibble value to an address in RAM.
|
||||
|
||||
proc sync*(mask: int32 = 0; bank: int8 = 0; to_cart = false)
|
||||
## Copy banks of RAM (sprites, map, etc) to and from the cartridge.
|
||||
|
||||
proc vbank*(bank: int8): int8
|
||||
## Switch the 16kb of banked video RAM.
|
||||
|
||||
|
||||
## ---------------------------
|
||||
## Utility Functions
|
||||
## ---------------------------
|
||||
|
||||
proc fget*(sprite_index: int32; flag: int8): bool
|
||||
## Retrieve a sprite flag.
|
||||
|
||||
proc fset*(sprite_index: int32; flag: int8; value: bool): bool {.discardable.}
|
||||
## Update a sprite flag.
|
||||
|
||||
proc mget*(x, y: int32): int32
|
||||
## Retrieve a map tile at given coordinates.
|
||||
|
||||
proc mset*(x, y, value: int32)
|
||||
## Update a map tile at given coordinates.
|
||||
|
||||
|
||||
## ---------------------------
|
||||
## System Functions
|
||||
## ---------------------------
|
||||
|
||||
proc exit*()
|
||||
## Interrupt program and return to console.
|
||||
|
||||
proc tstamp*(): uint32
|
||||
## Returns the current Unix timestamp in seconds.
|
||||
|
||||
proc trace*(text: cstring; color: Color = Color15)
|
||||
## Print a string to the Console.
|
||||
|
||||
{.pop.}
|
||||
|
||||
# suffix fixes "unreachable code executed" error
|
||||
proc time2*(): cfloat {.importc,
|
||||
codegenDecl: "__attribute__((import_name(\"time\"))) $1 $2$3".}
|
||||
## Returns how many milliseconds have passed since game started.
|
||||
|
||||
import std/macros
|
||||
|
||||
macro exportWasm*(def: untyped): untyped =
|
||||
result = def
|
||||
result[^3] = nnkPragma.newTree(
|
||||
ident("exportc"),
|
||||
nnkExprColonExpr.newTree(
|
||||
ident("codegenDecl"),
|
||||
newStrLitNode("__attribute__((export_name(\"$2\"))) $1 $2$3")
|
||||
)
|
||||
)
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
import internal except btn, btnp, trace
|
||||
export internal except btn, btnp, trace
|
||||
|
||||
proc font*(text: cstring, x, y: int32, transColor, char_width, char_height: int8,
|
||||
fixed: bool, scale: int8, alt: bool): int8 {.discardable.} =
|
||||
## Print a string using foreground sprite data as the font.
|
||||
if transColor >= 0:
|
||||
let trans_colors = transColor.uint8
|
||||
internal.font(text, x, y, addr trans_colors, 1, char_width, char_height, fixed,
|
||||
scale, alt)
|
||||
else:
|
||||
internal.font(text, x, y, nil, 0, char_width, char_height, fixed, scale, alt)
|
||||
|
||||
proc map*(x: int32 = 0, y: int32 = 0, w: int32 = 30, h: int32 = 17,
|
||||
sx: int32 = 0, sy: int32 = 0, transColor: Color = Null, scale: int8 = 1,
|
||||
remap: int32 = -1) =
|
||||
## Draw a map region.
|
||||
if transColor.int8 >= 0:
|
||||
let trans_colors = transColor.uint8
|
||||
internal.map(x, y, w, h, sx, sy, addr trans_colors, 1, scale, remap)
|
||||
else:
|
||||
internal.map(x, y, w, h, sx, sy, nil, 0, scale, remap)
|
||||
|
||||
proc spr*(id, x, y: int32, transColor: Color = Null, scale: int32 = 1,
|
||||
flip: int32 = 0, rotate: int32 = 0, w: int32 = 1, h: int32 = 1) =
|
||||
## Draw a sprite or composite sprite.
|
||||
if transColor.int8 >= 0:
|
||||
let trans_colors = transColor.uint8
|
||||
internal.spr(id, x, y, addr trans_colors, 1, scale, flip, rotate, w, h)
|
||||
else:
|
||||
internal.spr(id, x, y, nil, 0, scale, flip, rotate, w, h)
|
||||
|
||||
proc ttri*(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3: cfloat,
|
||||
texsrc: int32 = 0, transColor: Color = Null,
|
||||
z1: cfloat = 0, z2: cfloat = 0, z3: cfloat = 0, depth = false) =
|
||||
## Draw a triangle filled with texture.
|
||||
if transColor.int8 >= 0:
|
||||
let trans_colors = transColor.uint8
|
||||
internal.ttri(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3, texsrc,
|
||||
addr trans_colors, 1, z1, z2, z3, depth)
|
||||
else:
|
||||
internal.ttri(x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3, texsrc,
|
||||
nil, 0, z1, z2, z3, depth)
|
||||
|
||||
proc btn*(index: Button): bool {.inline.} =
|
||||
## Get gamepad button state in current frame.
|
||||
internal.btn(index) > 0
|
||||
|
||||
proc btnp*(index: Button, hold: int32 = -1, period: int32 = -1): bool {.inline.} =
|
||||
## Get gamepad button state according to previous frame.
|
||||
internal.btnp(index, hold, period) > 0
|
||||
|
||||
proc mouse*(): MousePos {.inline.} = internal.mouse(addr result)
|
||||
## Get XY and press state of mouse/touch.
|
||||
|
||||
proc pmemset*(address: int32; value: int64) = pmem(address, value)
|
||||
## Update the persistent memory.
|
||||
proc pmemget*(address: int32): uint32 = pmem(address, -1)
|
||||
## Access the persistent memory.
|
||||
|
||||
proc pixset*(x, y: int32; color: Color) = pix(x, y, color)
|
||||
## Set the color of a single pixel.
|
||||
proc pixget*(x, y: int32): uint8 = pix(x, y, Null)
|
||||
## Get the color of a single pixel.
|
||||
|
||||
proc trace*(items: varargs[cstring, cstring]) =
|
||||
## Print a string to the Console.
|
||||
for item in items: internal.trace(item)
|
||||
|
||||
proc print*(text: string; x, y: int32; color: Color = Color15; fixed = false;
|
||||
scale: int32 = 1; alt = false): int32 {.discardable.} =
|
||||
## Print a string using the system font.
|
||||
print(cstring(text), x, y, color, fixed, scale, alt)
|
||||
|
||||
proc NimMain() {.importc.}
|
||||
|
||||
proc BOOT() {.exportWasm.} =
|
||||
NimMain()
|
||||
Reference in New Issue
Block a user