mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-20 11:16:42 +01:00
Compare commits
8 Commits
browser-ru
...
v0.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 00d21b4745 | |||
| d11b46576a | |||
| add49a1f8b | |||
| 8815a8e02e | |||
| eb7c33d412 | |||
| 47ad3b4f30 | |||
| 0f668fb6e9 | |||
| f876f59e80 |
29
Cargo.lock
generated
29
Cargo.lock
generated
@@ -238,9 +238,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chumsky"
|
||||
version = "0.5.0"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2d3efff85e8572b1c3fa0127706af58c4fff8458f8d9436d54b1e97573c7a3f"
|
||||
checksum = "8d02796e4586c6c41aeb68eae9bfb4558a522c35f1430c14b40136c3706e09e4"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
@@ -498,14 +498,14 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
||||
[[package]]
|
||||
name = "curlywas"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/exoticorn/curlywas.git?rev=196719b#196719b35ef377cb7e001554b27ac5de013dcf2b"
|
||||
source = "git+https://github.com/exoticorn/curlywas.git?rev=89638565#896385654ab2c089200920b6dea4abec641c88d6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ariadne",
|
||||
"chumsky",
|
||||
"pico-args",
|
||||
"wasm-encoder",
|
||||
"wasmparser 0.81.0",
|
||||
"wasm-encoder 0.10.0",
|
||||
"wasmparser 0.83.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2312,7 +2312,7 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "uw8"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"curlywas",
|
||||
@@ -2338,7 +2338,7 @@ dependencies = [
|
||||
"pico-args",
|
||||
"upkr",
|
||||
"walrus",
|
||||
"wasm-encoder",
|
||||
"wasm-encoder 0.8.0",
|
||||
"wasmparser 0.81.0",
|
||||
]
|
||||
|
||||
@@ -2506,6 +2506,15 @@ dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa9d9bf45fc46f71c407837c9b30b1e874197f2dc357588430b21e5017d290ab"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.77.0"
|
||||
@@ -2524,6 +2533,12 @@ version = "0.81.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98930446519f63d00a836efdc22f67766ceae8dbcc1571379f2bcabc6b2b9abc"
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.83.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a"
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime"
|
||||
version = "0.30.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "uw8"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@@ -16,7 +16,7 @@ anyhow = "1"
|
||||
minifb = { version = "0.20", default-features = false, features = ["x11"] }
|
||||
notify = "4"
|
||||
pico-args = "0.4"
|
||||
curlywas = { git = "https://github.com/exoticorn/curlywas.git", rev = "196719b" }
|
||||
curlywas = { git = "https://github.com/exoticorn/curlywas.git", rev = "89638565" }
|
||||
wat = "1"
|
||||
uw8-tool = { path = "uw8-tool" }
|
||||
same-file = "1"
|
||||
|
||||
@@ -15,9 +15,9 @@ See [here](https://exoticorn.github.io/microw8/) for more information and docs.
|
||||
|
||||
## Downloads
|
||||
|
||||
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.1.0/microw8-0.1.0-linux.tgz)
|
||||
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.1.0/microw8-0.1.0-macos.tgz)
|
||||
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.0/microw8-0.1.0-windows.zip)
|
||||
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.1.2/microw8-0.1.2-linux.tgz)
|
||||
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.1.2/microw8-0.1.2-macos.tgz)
|
||||
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.2/microw8-0.1.2-windows.zip)
|
||||
|
||||
The download includes
|
||||
|
||||
@@ -35,6 +35,7 @@ Runs <file> which can be a binary WebAssembly module, an `.uw8` cart, a wat (Web
|
||||
|
||||
Options:
|
||||
|
||||
-b, --browser : Run in browser instead of using native runtime
|
||||
-t, --timeout FRAMES : Sets the timeout in frames (1/60s)
|
||||
-w, --watch : Reloads the given file every time it changes on disk.
|
||||
-p, --pack : Pack the file into an .uw8 cart before running it and print the resulting size.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import "env.memory" memory(4);
|
||||
import "env.printString" fn printString(i32);
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
export fn upd() {
|
||||
printString(0x20000);
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import "env.time" fn time() -> f32;
|
||||
import "env.circle" fn circle(f32, f32, f32, i32);
|
||||
import "env.cls" fn cls(i32);
|
||||
import "env.randomSeed" fn seed(i32);
|
||||
import "env.randomf" fn randomf() -> f32;
|
||||
import "env.sin" fn sin(f32) -> f32;
|
||||
import "env.cos" fn cos(f32) -> f32;
|
||||
import "env.fmod" fn fmod(f32, f32) -> f32;
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
export fn upd() {
|
||||
cls(0);
|
||||
@@ -15,10 +8,10 @@ export fn upd() {
|
||||
let inline rocket = i #>> 9;
|
||||
let lazy local_time = fmod(time() + rocket as f32 / 5 as f32, 2 as f32);
|
||||
let lazy rocket = rocket + nearest(time() - local_time) as i32 * 10;
|
||||
seed(rocket);
|
||||
randomSeed(rocket);
|
||||
let inline x = randomf() * 645 as f32;
|
||||
let y = randomf() * 133 as f32;
|
||||
let lazy angle = { seed(i); randomf() } * 44 as f32;
|
||||
let lazy angle = { randomSeed(i); randomf() } * 44 as f32;
|
||||
let inline dx = sin(angle);
|
||||
let inline dy = cos(angle);
|
||||
let lazy dist = local_time * (randomf() * 44 as f32);
|
||||
|
||||
@@ -1,38 +1,30 @@
|
||||
import "env.memory" memory(4);
|
||||
|
||||
import "env.cls" fn cls(i32);
|
||||
import "env.printString" fn printString(i32);
|
||||
import "env.printChar" fn printChar(i32);
|
||||
import "env.setCursorPosition" fn setCursor(i32, i32);
|
||||
import "env.setTextColor" fn setTextColor(i32);
|
||||
import "env.line" fn line(f32, f32, f32, f32, i32);
|
||||
import "env.isButtonTriggered" fn triggered(i32) -> i32;
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
global mut mode: i32 = 0;
|
||||
|
||||
export fn upd() {
|
||||
cls(0);
|
||||
|
||||
if triggered(4) {
|
||||
if isButtonTriggered(BUTTON_A) {
|
||||
mode = !mode;
|
||||
}
|
||||
|
||||
setTextColor(15);
|
||||
printString(mode * 0x20000);
|
||||
printString(mode * USER_MEM);
|
||||
|
||||
let y: i32;
|
||||
loop y {
|
||||
line(0 as f32, (y * 9 + 39) as f32, (14+16*9) as f32, (y * 9 + 39) as f32, 1);
|
||||
line((y * 9 + 15) as f32, 24 as f32, (y * 9 + 15) as f32, (38+16*9) as f32, 1);
|
||||
setTextColor(15);
|
||||
setCursor(y * 9 + 16, 24);
|
||||
setCursorPosition(y * 9 + 16, 24);
|
||||
let lazy hexChar = select(y < 10, y + 48, y + 87);
|
||||
printChar(hexChar);
|
||||
setCursor(0, y * 9 + 24+16);
|
||||
setCursorPosition(0, y * 9 + 24+16);
|
||||
printChar(hexChar);
|
||||
let x = 0;
|
||||
loop x {
|
||||
setCursor(x * 9 + 16, y * 9 + 24+16);
|
||||
setCursorPosition(x * 9 + 16, y * 9 + 24+16);
|
||||
setTextColor(select(mode, x + y * 16, -9));
|
||||
if y >= 2 | mode {
|
||||
printChar(select(mode, 0xa4, x + y * 16));
|
||||
@@ -47,6 +39,6 @@ data 0 {
|
||||
"Default font: (press " i8(0xcc) " for palette)" i8(5, 0)
|
||||
}
|
||||
|
||||
data 0x20000 {
|
||||
data USER_MEM {
|
||||
"Default palette: (press " i8(0xcc) " for font)" i8(5, 0)
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
import "env.memory" memory(4);
|
||||
|
||||
import "env.cls" fn cls(i32);
|
||||
import "env.time" fn time() -> f32;
|
||||
import "env.line" fn line(f32, f32, f32, f32, i32);
|
||||
import "env.sin" fn sin(f32) -> f32;
|
||||
import "env.cos" fn cos(f32) -> f32;
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
export fn upd() {
|
||||
cls(0);
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
import "env.memory" memory(4);
|
||||
|
||||
import "env.rectangle" fn rect(f32, f32, f32, f32, i32);
|
||||
import "env.circle" fn circle(f32, f32, f32, i32);
|
||||
import "env.isButtonPressed" fn btn(i32) -> i32;
|
||||
import "env.random" fn random() -> i32;
|
||||
import "env.randomSeed" fn randomSeed(i32);
|
||||
import "env.cls" fn cls(i32);
|
||||
import "env.printInt" fn printInt(i32);
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
global mut pz: i32 = 4;
|
||||
global mut px: f32 = 2.0;
|
||||
@@ -19,7 +11,7 @@ export fn upd() {
|
||||
let inline zero = 0.0;
|
||||
|
||||
let lazy control_speed = 0.03125;
|
||||
s = s + 0.1875 - (f + control_speed) * btn(4 <| cls(4)) as f32;
|
||||
s = s + 0.1875 - (f + control_speed) * isButtonPressed(4 <| cls(4)) as f32;
|
||||
f = f * 0.5625;
|
||||
|
||||
printInt(pz);
|
||||
@@ -33,8 +25,8 @@ export fn upd() {
|
||||
|
||||
let inline c = (z & 1) * -2;
|
||||
let inline yf = y as f32;
|
||||
rect(rx, yf, rw, yf / 6 as f32, c + 1);
|
||||
rect(rx, yf, rw, 1 as f32, c - 4);
|
||||
rectangle(rx, yf, rw, yf / 6 as f32, c + 1);
|
||||
rectangle(rx, yf, rw, 1 as f32, c - 4);
|
||||
|
||||
if y == 180 & py > zero {
|
||||
if x > w | x < zero {
|
||||
@@ -51,7 +43,7 @@ export fn upd() {
|
||||
circle(160 as f32, 160 as f32 + py, 22 as f32, -28);
|
||||
circle((160 - 6) as f32, (160 - 6) as f32 + py, 6 as f32, -26);
|
||||
|
||||
px = px + (btn(3) - btn(2)) as f32 * control_speed;
|
||||
px = px + (isButtonPressed(3) - isButtonPressed(2)) as f32 * control_speed;
|
||||
py = py + s;
|
||||
pz = pz + 1;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import "env.memory" memory(4);
|
||||
import "env.sin" fn sin(f32) -> f32;
|
||||
import "env.time" fn time() -> f32;
|
||||
import "env.setPixel" fn setPixel(i32, i32, i32);
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
export fn upd() {
|
||||
let x: i32;
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import "env.memory" memory(2);
|
||||
|
||||
import "env.fmod" fn fmod(f32, f32) -> f32;
|
||||
import "env.time" fn time() -> f32;
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
export fn upd() {
|
||||
let i: i32;
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import "env.memory" memory(4);
|
||||
|
||||
import "env.atan2" fn atan2(f32, f32) -> f32;
|
||||
import "env.time" fn time() -> f32;
|
||||
include "../include/microw8-api.cwa"
|
||||
|
||||
export fn upd() {
|
||||
let i: i32;
|
||||
@@ -12,7 +9,7 @@ export fn upd() {
|
||||
let inline d = 40000 as f32 / sqrt(x * x + y * y);
|
||||
let inline u = atan2(x, y) * (512.0 / 3.141);
|
||||
let inline c = ((i32.trunc_sat_f32_s(d + t * 2 as f32) ^ i32.trunc_sat_f32_s(u + t)) & 255) >> 4;
|
||||
i?120 = c;
|
||||
i?FRAMEBUFFER = c;
|
||||
|
||||
branch_if (i := i + 1) < 320*240: pixels;
|
||||
}
|
||||
|
||||
50
examples/include/microw8-api.cwa
Normal file
50
examples/include/microw8-api.cwa
Normal file
@@ -0,0 +1,50 @@
|
||||
// MicroW8 APIs, to be `include`d in CurlyWas sources
|
||||
import "env.memory" memory(4);
|
||||
|
||||
import "env.sin" fn sin(f32) -> f32;
|
||||
import "env.cos" fn cos(f32) -> f32;
|
||||
import "env.tan" fn tan(f32) -> f32;
|
||||
import "env.asin" fn asin(f32) -> f32;
|
||||
import "env.acos" fn acos(f32) -> f32;
|
||||
import "env.atan" fn atan(f32) -> f32;
|
||||
import "env.atan2" fn atan2(f32, f32) -> f32;
|
||||
import "env.pow" fn pow(f32, f32) -> f32;
|
||||
import "env.log" fn log(f32) -> f32;
|
||||
import "env.fmod" fn fmod(f32, f32) -> f32;
|
||||
import "env.random" fn random() -> i32;
|
||||
import "env.randomf" fn randomf() -> f32;
|
||||
import "env.randomSeed" fn randomSeed(i32);
|
||||
import "env.cls" fn cls(i32);
|
||||
import "env.setPixel" fn setPixel(i32, i32, i32);
|
||||
import "env.getPixel" fn getPixel(i32, i32) -> i32;
|
||||
import "env.hline" fn hline(i32, i32, i32, i32);
|
||||
import "env.rectangle" fn rectangle(f32, f32, f32, f32, i32);
|
||||
import "env.circle" fn circle(f32, f32, f32, i32);
|
||||
import "env.line" fn line(f32, f32, f32, f32, i32);
|
||||
import "env.time" fn time() -> f32;
|
||||
import "env.isButtonPressed" fn isButtonPressed(i32) -> i32;
|
||||
import "env.isButtonTriggered" fn isButtonTriggered(i32) -> i32;
|
||||
import "env.printChar" fn printChar(i32);
|
||||
import "env.printString" fn printString(i32);
|
||||
import "env.printInt" fn printInt(i32);
|
||||
import "env.setTextColor" fn setTextColor(i32);
|
||||
import "env.setBackgroundColor" fn setBackgroundColor(i32);
|
||||
import "env.setCursorPosition" fn setCursorPosition(i32, i32);
|
||||
import "env.rectangle_outline" fn rectangle_outline(f32, f32, f32, f32, i32);
|
||||
import "env.circle_outline" fn circle_outline(f32, f32, f32, i32);
|
||||
import "env.exp" fn exp(f32) -> f32;
|
||||
|
||||
const TIME_MS = 0x40;
|
||||
const GAMEPAD = 0x44;
|
||||
const FRAMEBUFFER = 0x78;
|
||||
const PALETTE = 0x13000;
|
||||
const FONT = 0x13400;
|
||||
const USER_MEM = 0x14000;
|
||||
const BUTTON_UP = 0x0;
|
||||
const BUTTON_DOWN = 0x1;
|
||||
const BUTTON_LEFT = 0x2;
|
||||
const BUTTON_RIGHT = 0x3;
|
||||
const BUTTON_A = 0x4;
|
||||
const BUTTON_B = 0x5;
|
||||
const BUTTON_X = 0x6;
|
||||
const BUTTON_Y = 0x7;
|
||||
52
examples/include/microw8-api.wat
Normal file
52
examples/include/microw8-api.wat
Normal file
@@ -0,0 +1,52 @@
|
||||
;; MicroW8 APIs, in WAT (Wasm Text) format
|
||||
(import "env" "memory" (memory 4))
|
||||
|
||||
(import "env" "sin" (func $sin (param f32) (result f32)))
|
||||
(import "env" "cos" (func $cos (param f32) (result f32)))
|
||||
(import "env" "tan" (func $tan (param f32) (result f32)))
|
||||
(import "env" "asin" (func $asin (param f32) (result f32)))
|
||||
(import "env" "acos" (func $acos (param f32) (result f32)))
|
||||
(import "env" "atan" (func $atan (param f32) (result f32)))
|
||||
(import "env" "atan2" (func $atan2 (param f32) (param f32) (result f32)))
|
||||
(import "env" "pow" (func $pow (param f32) (param f32) (result f32)))
|
||||
(import "env" "log" (func $log (param f32) (result f32)))
|
||||
(import "env" "fmod" (func $fmod (param f32) (param f32) (result f32)))
|
||||
(import "env" "random" (func $random (result i32)))
|
||||
(import "env" "randomf" (func $randomf (result f32)))
|
||||
(import "env" "randomSeed" (func $randomSeed (param i32)))
|
||||
(import "env" "cls" (func $cls (param i32)))
|
||||
(import "env" "setPixel" (func $setPixel (param i32) (param i32) (param i32)))
|
||||
(import "env" "getPixel" (func $getPixel (param i32) (param i32) (result i32)))
|
||||
(import "env" "hline" (func $hline (param i32) (param i32) (param i32) (param i32)))
|
||||
(import "env" "rectangle" (func $rectangle (param f32) (param f32) (param f32) (param f32) (param i32)))
|
||||
(import "env" "circle" (func $circle (param f32) (param f32) (param f32) (param i32)))
|
||||
(import "env" "line" (func $line (param f32) (param f32) (param f32) (param f32) (param i32)))
|
||||
(import "env" "time" (func $time (result f32)))
|
||||
(import "env" "isButtonPressed" (func $isButtonPressed (param i32) (result i32)))
|
||||
(import "env" "isButtonTriggered" (func $isButtonTriggered (param i32) (result i32)))
|
||||
(import "env" "printChar" (func $printChar (param i32)))
|
||||
(import "env" "printString" (func $printString (param i32)))
|
||||
(import "env" "printInt" (func $printInt (param i32)))
|
||||
(import "env" "setTextColor" (func $setTextColor (param i32)))
|
||||
(import "env" "setBackgroundColor" (func $setBackgroundColor (param i32)))
|
||||
(import "env" "setCursorPosition" (func $setCursorPosition (param i32) (param i32)))
|
||||
(import "env" "rectangle_outline" (func $rectangle_outline (param f32) (param f32) (param f32) (param f32) (param i32)))
|
||||
(import "env" "circle_outline" (func $circle_outline (param f32) (param f32) (param f32) (param i32)))
|
||||
(import "env" "exp" (func $exp (param f32) (result f32)))
|
||||
|
||||
;; to use defines, include this file with a preprocessor
|
||||
;; like gpp (https://logological.org/gpp).
|
||||
#define TIME_MS 0x40;
|
||||
#define GAMEPAD 0x44;
|
||||
#define FRAMEBUFFER 0x78;
|
||||
#define PALETTE 0x13000;
|
||||
#define FONT 0x13400;
|
||||
#define USER_MEM 0x14000;
|
||||
#define BUTTON_UP 0x0;
|
||||
#define BUTTON_DOWN 0x1;
|
||||
#define BUTTON_LEFT 0x2;
|
||||
#define BUTTON_RIGHT 0x3;
|
||||
#define BUTTON_A 0x4;
|
||||
#define BUTTON_B 0x5;
|
||||
#define BUTTON_X 0x6;
|
||||
#define BUTTON_Y 0x7;
|
||||
127
platform/Cargo.lock
generated
127
platform/Cargo.lock
generated
@@ -79,9 +79,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chumsky"
|
||||
version = "0.5.0"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2d3efff85e8572b1c3fa0127706af58c4fff8458f8d9436d54b1e97573c7a3f"
|
||||
checksum = "8d02796e4586c6c41aeb68eae9bfb4558a522c35f1430c14b40136c3706e09e4"
|
||||
dependencies = [
|
||||
"ahash 0.3.8",
|
||||
]
|
||||
@@ -146,14 +146,14 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
[[package]]
|
||||
name = "curlywas"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/exoticorn/curlywas.git?rev=196719b#196719b35ef377cb7e001554b27ac5de013dcf2b"
|
||||
source = "git+https://github.com/exoticorn/curlywas.git?rev=89638565#896385654ab2c089200920b6dea4abec641c88d6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ariadne",
|
||||
"chumsky",
|
||||
"pico-args",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
"wasm-encoder 0.10.0",
|
||||
"wasmparser 0.83.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -197,6 +197,21 @@ dependencies = [
|
||||
"ahash 0.7.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "id-arena"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@@ -227,6 +242,15 @@ dependencies = [
|
||||
"rgb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
@@ -286,6 +310,24 @@ version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.31"
|
||||
@@ -304,6 +346,17 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.43"
|
||||
@@ -323,6 +376,18 @@ dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "upkr"
|
||||
version = "0.1.0"
|
||||
@@ -342,8 +407,9 @@ dependencies = [
|
||||
"pbr",
|
||||
"pico-args",
|
||||
"upkr",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
"walrus",
|
||||
"wasm-encoder 0.8.0",
|
||||
"wasmparser 0.81.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -352,6 +418,32 @@ version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "walrus"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eb08e48cde54c05f363d984bb54ce374f49e242def9468d2e1b6c2372d291f8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
"leb128",
|
||||
"log",
|
||||
"walrus-macro",
|
||||
"wasmparser 0.77.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walrus-macro"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e5bd22c71e77d60140b0bd5be56155a37e5bd14e24f5f87298040d0cc40d7"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
@@ -367,12 +459,33 @@ dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa9d9bf45fc46f71c407837c9b30b1e874197f2dc357588430b21e5017d290ab"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.77.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b35c86d22e720a07d954ebbed772d01180501afe7d03d464f413bb5f8914a8d6"
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.81.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98930446519f63d00a836efdc22f67766ceae8dbcc1571379f2bcabc6b2b9abc"
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.83.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
||||
@@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
curlywas = { git="https://github.com/exoticorn/curlywas.git", rev="196719b" }
|
||||
curlywas = { git="https://github.com/exoticorn/curlywas.git", rev="89638565" }
|
||||
uw8-tool = { path="../uw8-tool" }
|
||||
anyhow = "1"
|
||||
lodepng = "3.4"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
@@ -12,15 +12,15 @@ fn main() -> Result<()> {
|
||||
|
||||
println!("Compiling loader module");
|
||||
let loader = curlywas::compile_file("src/loader.cwa", curlywas::Options::default())?;
|
||||
File::create("bin/loader.wasm")?.write_all(&loader)?;
|
||||
File::create("bin/loader.wasm")?.write_all(&loader.wasm)?;
|
||||
|
||||
println!("Loader (including base module): {} bytes", loader.len());
|
||||
println!("Loader (including base module): {} bytes", loader.wasm.len());
|
||||
|
||||
println!("Compiling platform module");
|
||||
let platform = curlywas::compile_file("src/platform.cwa", curlywas::Options::default())?;
|
||||
println!("Compressing platform module");
|
||||
let platform = uw8_tool::pack(
|
||||
&platform,
|
||||
&platform.wasm,
|
||||
&uw8_tool::PackConfig::default().with_compression_level(4),
|
||||
)?;
|
||||
File::create("bin/platform.uw8")?.write_all(&platform)?;
|
||||
|
||||
@@ -256,6 +256,11 @@ export fn line(x1: f32, y1: f32, x2: f32, y2: f32, col: i32) {
|
||||
p = y1;
|
||||
}
|
||||
|
||||
if max_axis == 0 as f32 {
|
||||
setPixel(x1 as i32, y1 as i32, col);
|
||||
return;
|
||||
}
|
||||
|
||||
let steps = floor(p + max_axis) as i32 - floor(p) as i32;
|
||||
p = floor(p) + 0.5 - p;
|
||||
if max_axis < 0 as f32 {
|
||||
@@ -267,7 +272,7 @@ export fn line(x1: f32, y1: f32, x2: f32, y2: f32, col: i32) {
|
||||
dy = dy / max_axis;
|
||||
|
||||
let f = min(max_axis, max(0 as f32, p));
|
||||
setPixel((x1 + f * dx) as i32, (y1 + f * dy) as i32, col);
|
||||
setPixel(i32.trunc_sat_f32_s(x1 + f * dx), i32.trunc_sat_f32_s(y1 + f * dy), col);
|
||||
|
||||
if !steps {
|
||||
return;
|
||||
@@ -280,7 +285,7 @@ export fn line(x1: f32, y1: f32, x2: f32, y2: f32, col: i32) {
|
||||
|
||||
loop pixels {
|
||||
if steps := steps - 1 {
|
||||
setPixel(x1 as i32, y1 as i32, col);
|
||||
setPixel(i32.trunc_sat_f32_s(x1), i32.trunc_sat_f32_s(y1), col);
|
||||
x1 = x1 + dx;
|
||||
y1 = y1 + dy;
|
||||
branch pixels;
|
||||
@@ -288,7 +293,7 @@ export fn line(x1: f32, y1: f32, x2: f32, y2: f32, col: i32) {
|
||||
}
|
||||
|
||||
f = min(max_axis, p) - p;
|
||||
setPixel((x1 + f * dx) as i32, (y1 + f * dy) as i32, col);
|
||||
setPixel(i32.trunc_sat_f32_s(x1 + f * dx), i32.trunc_sat_f32_s(y1 + f * dy), col);
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
@@ -36,6 +36,8 @@ for dir in build/*; do
|
||||
cp $example $dir/examples
|
||||
done
|
||||
|
||||
cp -r ../examples/include $dir/include
|
||||
|
||||
mkdir $dir/carts
|
||||
for example in $dir/examples/*; do
|
||||
build/microw8-linux/uw8 pack -l 9 $example $dir/carts/$(basename ${example%.*}).uw8
|
||||
|
||||
@@ -15,11 +15,11 @@ The initial motivation behind MicroW8 was to explore whether there was a way to
|
||||
* Gamepad input (D-Pad + 4 Buttons)
|
||||
|
||||
## Examples
|
||||
* [Fireworks](v0.1.1#AgwvgP+M59snqjl4CMKw5sqm1Zw9yJCbSviMjeLUdHus2a3yl/a99+uiBeqZgP/2jqSjrLjRk73COMM6OSLpsxK8ugT1kuk/q4hQUqqPpGozHoa0laulzGGcahzdfdJsYaK1sIdeIYS9M5PnJx/Wk9H+PvWEPy2Zvv7I6IW7Fg==) (127 bytes): Some fireworks to welcome 2022.
|
||||
* [Skip Ahead](v0.1.1#AgyfpZ80wkW28kiUZ9VIK4v+RPnVxqjK1dz2BcDoNyQPsS2g4OgEzkTe6jyoAfFOmqKrS8SM2aRljBal9mjNn8i4fP9eBK+RehQKxxGtJa9FqftvqEnh3ez1YaYxqj7jgTdzJ/WAYVmKMovBT1myrX3FamqKSOgMsNedLhVTLAhQup3sNcYEjGNo8b0HZ5+AgMgCwYRGCe//XQOMAaAAzqDILgmpEZ/43RKHcQpHEQwbURfNQJpadJe2sz3q5FlQnTGXQ9oSMokidhlC+aR/IpNHieuBGLhFZ2GfnwVQ0geBbQpTPA==) (229 bytes): A port of my [TIC-80 256byte game](http://tic80.com/play?cart=1735) from LoveByte'21
|
||||
* [OhNoAnotherTunnel](v0.1.1#AgPP1oEFvPzY/rBZwTumtYn37zeMFgpir1Bkn91jsNcp26VzoUpkAOOJTtnzVBfW+/dGnnIdbq/irBUJztY5wuua80DORTYZndgdwZHcSk15ajc4nyO0g1A6kGWyW56oZk0iPYJA9WtUmoj0Plvy1CGwIZrMe57X7QZcdqc3u6zjTA41Tpiqi9vnO3xbhi8o594Vx0XPXwVzpYq1ZCTYenfAGaXKkDmAFJqiVIsiCg==) (175 bytes): A port of my [entry](http://tic80.com/play?cart=1871) in the Outline'21 bytebattle final
|
||||
* [Technotunnel](v0.1.1#AhPXpq894LaUhp5+HQf39f39/Jc8g5zUrBSc0uyKh36ivskczhY84h55zL8gWpkdvKuRQI+KIt80isKzh8jkM8nILcx0RUvyk8yjE8TgNsgkcORVI0RY5k3qE4ySjaycxa2DVZH61UWZuLsCouuwT7I80TbmmetQSbMywJ/avrrCZIAH0UzQfvOiCJNG48NI0FFY1vjB7a7dcp8Uqg==) (157 bytes): A port of my [entry](https://tic80.com/play?cart=1873) in the Outline'21 bytebattle quater final
|
||||
* [Font & Palette](v0.1.1#At/p39+IBnj6ry1TRe7jzVy2A4tXgBvmoW2itzoyF2aM28pGy5QDiKxqrk8l9sbWZLtnAb+jgOfU+9QhpuyCAkhN6gPOU481IUL/df96vNe3h288Dqwhd3sfFpothIVFsMwRK72kW2hiR7zWsaXyy5pNmjR6BJk4piWx9ApT1ZwoUajhk6/zij6itq/FD1U3jj/J3MOwqZ2ef8Bv6ZPQlJIYVf62icGa69wS6SI1qBpIFiF14F8PcztRVbKIxLpT4ArCS6nz6FPnyUkqATGSBNPJ): Just a simple viewer for the default font and palette.
|
||||
* [Fireworks](v0.1.2#AgwvgP+M59snqjl4CMKw5sqm1Zw9yJCbSviMjeLUdHus2a3yl/a99+uiBeqZgP/2jqSjrLjRk73COMM6OSLpsxK8ugT1kuk/q4hQUqqPpGozHoa0laulzGGcahzdfdJsYaK1sIdeIYS9M5PnJx/Wk9H+PvWEPy2Zvv7I6IW7Fg==) (127 bytes): Some fireworks to welcome 2022.
|
||||
* [Skip Ahead](v0.1.2#AgyfpZ80wkW28kiUZ9VIK4v+RPnVxqjK1dz2BcDoNyQPsS2g4OgEzkTe6jyoAfFOmqKrS8SM2aRljBal9mjNn8i4fP9eBK+RehQKxxGtJa9FqftvqEnh3ez1YaYxqj7jgTdzJ/WAYVmKMovBT1myrX3FamqKSOgMsNedLhVTLAhQup3sNcYEjGNo8b0HZ5+AgMgCwYRGCe//XQOMAaAAzqDILgmpEZ/43RKHcQpHEQwbURfNQJpadJe2sz3q5FlQnTGXQ9oSMokidhlC+aR/IpNHieuBGLhFZ2GfnwVQ0geBbQpTPA==) (229 bytes): A port of my [TIC-80 256byte game](http://tic80.com/play?cart=1735) from LoveByte'21
|
||||
* [OhNoAnotherTunnel](v0.1.2#AgPP1oEFvPzY/rBZwTumtYn37zeMFgpir1Bkn91jsNcp26VzoUpkAOOJTtnzVBfW+/dGnnIdbq/irBUJztY5wuua80DORTYZndgdwZHcSk15ajc4nyO0g1A6kGWyW56oZk0iPYJA9WtUmoj0Plvy1CGwIZrMe57X7QZcdqc3u6zjTA41Tpiqi9vnO3xbhi8o594Vx0XPXwVzpYq1ZCTYenfAGaXKkDmAFJqiVIsiCg==) (175 bytes): A port of my [entry](http://tic80.com/play?cart=1871) in the Outline'21 bytebattle final
|
||||
* [Technotunnel](v0.1.2#AhPXpq894LaUhp5+HQf39f39/Jc8g5zUrBSc0uyKh36ivskczhY84h55zL8gWpkdvKuRQI+KIt80isKzh8jkM8nILcx0RUvyk8yjE8TgNsgkcORVI0RY5k3qE4ySjaycxa2DVZH61UWZuLsCouuwT7I80TbmmetQSbMywJ/avrrCZIAH0UzQfvOiCJNG48NI0FFY1vjB7a7dcp8Uqg==) (157 bytes): A port of my [entry](https://tic80.com/play?cart=1873) in the Outline'21 bytebattle quater final
|
||||
* [Font & Palette](v0.1.2#At/p39+IBnj6ry1TRe7jzVy2A4tXgBvmoW2itzoyF2aM28pGy5QDiKxqrk8l9sbWZLtnAb+jgOfU+9QhpuyCAkhN6gPOU481IUL/df96vNe3h288Dqwhd3sfFpothIVFsMwRK72kW2hiR7zWsaXyy5pNmjR6BJk4piWx9ApT1ZwoUajhk6/zij6itq/FD1U3jj/J3MOwqZ2ef8Bv6ZPQlJIYVf62icGa69wS6SI1qBpIFiF14F8PcztRVbKIxLpT4ArCS6nz6FPnyUkqATGSBNPJ): Just a simple viewer for the default font and palette.
|
||||
|
||||
Examplers for older versions:
|
||||
|
||||
@@ -29,6 +29,20 @@ Examplers for older versions:
|
||||
|
||||
## Versions
|
||||
|
||||
### v0.1.2
|
||||
|
||||
* [Web runtime](v0.1.2)
|
||||
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.1.2/microw8-0.1.2-linux.tgz)
|
||||
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.1.2/microw8-0.1.2-macos.tgz)
|
||||
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.2/microw8-0.1.2-windows.zip)
|
||||
|
||||
Changes:
|
||||
|
||||
* add option to `uw8 run` to run the cart in the browser using the web runtime
|
||||
* CurlyWas: implement `include` support
|
||||
* CurlyWas: implement support for constants
|
||||
* fix crash when trying to draw zero sized line
|
||||
|
||||
### v0.1.1
|
||||
|
||||
* [Web runtime](v0.1.1)
|
||||
|
||||
@@ -47,7 +47,7 @@ Returns the arccosine of `x`.
|
||||
|
||||
Returns the arctangent of `x`.
|
||||
|
||||
### fn atan2(y: f32, y: f32) -> f32
|
||||
### fn atan2(y: f32, x: f32) -> f32
|
||||
|
||||
Returns the angle between the point `(x, y)` and the positive x-axis.
|
||||
|
||||
@@ -284,6 +284,7 @@ Runs `<file>` which can be a binary WebAssembly module, an `.uw8` cart, a wat (W
|
||||
|
||||
Options:
|
||||
|
||||
* `-b`, `--browser`: Run in browser instead of using native runtime
|
||||
* `-t FRAMES`, `--timeout FRAMES`: Sets the timeout in frames (1/60s). If the start or update function runs longer than this it is forcibly interupted
|
||||
and execution of the cart is stopped. Defaults to 30 (0.5s)
|
||||
* `-w`, `--watch`: Reloads the given file every time it changes on disk.
|
||||
|
||||
1
site/static/v0.1.2/index.html
Normal file
1
site/static/v0.1.2/index.html
Normal file
File diff suppressed because one or more lines are too long
@@ -1,23 +1,38 @@
|
||||
use anyhow::{bail, Result};
|
||||
use notify::{DebouncedEvent, Watcher, RecommendedWatcher};
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
path::{Path, PathBuf},
|
||||
sync::mpsc,
|
||||
time::Duration,
|
||||
};
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use notify::{DebouncedEvent, RecommendedWatcher, Watcher};
|
||||
use std::{collections::BTreeSet, path::PathBuf, sync::mpsc, time::Duration};
|
||||
|
||||
pub struct FileWatcher {
|
||||
_watcher: RecommendedWatcher,
|
||||
watcher: RecommendedWatcher,
|
||||
watched_files: BTreeSet<PathBuf>,
|
||||
directories: BTreeSet<PathBuf>,
|
||||
rx: mpsc::Receiver<DebouncedEvent>,
|
||||
}
|
||||
|
||||
pub struct FileWatcherBuilder(BTreeSet<PathBuf>);
|
||||
|
||||
impl FileWatcher {
|
||||
pub fn builder() -> FileWatcherBuilder {
|
||||
FileWatcherBuilder(BTreeSet::new())
|
||||
pub fn new() -> Result<FileWatcher> {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let watcher = notify::watcher(tx, Duration::from_millis(100))?;
|
||||
Ok(FileWatcher {
|
||||
watcher,
|
||||
watched_files: BTreeSet::new(),
|
||||
directories: BTreeSet::new(),
|
||||
rx,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_file<P: Into<PathBuf>>(&mut self, path: P) -> Result<()> {
|
||||
let path = path.into();
|
||||
let parent = path.parent().ok_or_else(|| anyhow!("File has no parent"))?;
|
||||
|
||||
if !self.directories.contains(parent) {
|
||||
self.watcher
|
||||
.watch(parent, notify::RecursiveMode::NonRecursive)?;
|
||||
self.directories.insert(parent.to_path_buf());
|
||||
}
|
||||
|
||||
self.watched_files.insert(path);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn poll_changed_file(&self) -> Result<Option<PathBuf>> {
|
||||
@@ -38,33 +53,3 @@ impl FileWatcher {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileWatcherBuilder {
|
||||
pub fn add_file<P: Into<PathBuf>>(&mut self, path: P) -> &mut Self {
|
||||
self.0.insert(path.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<FileWatcher> {
|
||||
let mut directories: BTreeSet<&Path> = BTreeSet::new();
|
||||
|
||||
for file in &self.0 {
|
||||
if let Some(directory) = file.parent() {
|
||||
directories.insert(directory);
|
||||
}
|
||||
}
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let mut watcher = notify::watcher(tx, Duration::from_millis(100))?;
|
||||
|
||||
for directory in directories {
|
||||
watcher.watch(directory, notify::RecursiveMode::NonRecursive)?;
|
||||
}
|
||||
|
||||
Ok(FileWatcher {
|
||||
_watcher: watcher,
|
||||
watched_files: self.0,
|
||||
rx,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
101
src/main.rs
101
src/main.rs
@@ -77,13 +77,7 @@ fn run(mut args: Arguments) -> Result<()> {
|
||||
|
||||
let filename = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
|
||||
let mut watcher = uw8::FileWatcher::builder();
|
||||
|
||||
if watch_mode {
|
||||
watcher.add_file(&filename);
|
||||
}
|
||||
|
||||
let watcher = watcher.build()?;
|
||||
let mut watcher = uw8::FileWatcher::new()?;
|
||||
|
||||
use std::process::exit;
|
||||
|
||||
@@ -103,18 +97,26 @@ fn run(mut args: Arguments) -> Result<()> {
|
||||
runtime.set_timeout(timeout);
|
||||
}
|
||||
|
||||
if let Err(err) = start_cart(&filename, &mut *runtime, &config) {
|
||||
let mut first_run = true;
|
||||
|
||||
while runtime.is_open() {
|
||||
if first_run || watcher.poll_changed_file()?.is_some() {
|
||||
match start_cart(&filename, &mut *runtime, &config) {
|
||||
Ok(dependencies) => {
|
||||
if watch_mode {
|
||||
for dep in dependencies {
|
||||
watcher.add_file(dep)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Load error: {}", err);
|
||||
if !watch_mode {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
while runtime.is_open() {
|
||||
if watcher.poll_changed_file()?.is_some() {
|
||||
if let Err(err) = start_cart(&filename, &mut *runtime, &config) {
|
||||
eprintln!("Load error: {}", err);
|
||||
}
|
||||
first_run = false;
|
||||
}
|
||||
|
||||
if let Err(err) = runtime.run_frame() {
|
||||
@@ -134,18 +136,26 @@ struct Config {
|
||||
output_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
fn load_cart(filename: &Path, config: &Config) -> Result<Vec<u8>> {
|
||||
fn load_cart(filename: &Path, config: &Config) -> Result<(Vec<u8>, Vec<PathBuf>)> {
|
||||
let mut dependencies = Vec::new();
|
||||
let mut cart = match SourceType::of_file(filename)? {
|
||||
SourceType::Binary => {
|
||||
let mut cart = vec![];
|
||||
File::open(filename)?.read_to_end(&mut cart)?;
|
||||
|
||||
if cart[0] >= 10 {
|
||||
let src = String::from_utf8(cart)?;
|
||||
cart = if src.chars().find(|c| !c.is_whitespace()) == Some('(') {
|
||||
wat::parse_str(src)?
|
||||
} else {
|
||||
curlywas::compile_str(&src, filename, curlywas::Options::default())?
|
||||
};
|
||||
dependencies.push(filename.to_path_buf());
|
||||
cart
|
||||
}
|
||||
SourceType::Wat => {
|
||||
let cart = wat::parse_file(filename)?;
|
||||
dependencies.push(filename.to_path_buf());
|
||||
cart
|
||||
}
|
||||
SourceType::CurlyWas => {
|
||||
let module = curlywas::compile_file(filename, curlywas::Options::default())?;
|
||||
dependencies = module.dependencies;
|
||||
module.wasm
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(ref pack_config) = config.pack {
|
||||
cart = uw8_tool::pack(&cart, pack_config)?;
|
||||
@@ -156,18 +166,53 @@ fn load_cart(filename: &Path, config: &Config) -> Result<Vec<u8>> {
|
||||
File::create(path)?.write_all(&cart)?;
|
||||
}
|
||||
|
||||
Ok(cart)
|
||||
Ok((cart, dependencies))
|
||||
}
|
||||
|
||||
enum SourceType {
|
||||
Binary,
|
||||
Wat,
|
||||
CurlyWas,
|
||||
}
|
||||
|
||||
impl SourceType {
|
||||
fn of_file(filename: &Path) -> Result<SourceType> {
|
||||
if let Some(extension) = filename.extension() {
|
||||
if extension == "uw8" || extension == "wasm" {
|
||||
return Ok(SourceType::Binary);
|
||||
} else if extension == "wat" || extension == "wast" {
|
||||
return Ok(SourceType::Wat);
|
||||
} else if extension == "cwa" {
|
||||
return Ok(SourceType::CurlyWas);
|
||||
}
|
||||
}
|
||||
|
||||
let mut cart = vec![];
|
||||
File::open(filename)?.read_to_end(&mut cart)?;
|
||||
|
||||
let ty = if cart[0] < 10 {
|
||||
SourceType::Binary
|
||||
} else {
|
||||
let src = String::from_utf8(cart)?;
|
||||
if src.chars().find(|&c| !c.is_whitespace() && c != ';') == Some('(') {
|
||||
SourceType::Wat
|
||||
} else {
|
||||
SourceType::CurlyWas
|
||||
}
|
||||
};
|
||||
Ok(ty)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "native", feature = "browser"))]
|
||||
fn start_cart(filename: &Path, runtime: &mut dyn Runtime, config: &Config) -> Result<()> {
|
||||
fn start_cart(filename: &Path, runtime: &mut dyn Runtime, config: &Config) -> Result<Vec<PathBuf>> {
|
||||
let cart = load_cart(filename, config)?;
|
||||
|
||||
if let Err(err) = runtime.load(&cart) {
|
||||
if let Err(err) = runtime.load(&cart.0) {
|
||||
eprintln!("Load error: {}", err);
|
||||
Err(err)
|
||||
} else {
|
||||
Ok(())
|
||||
Ok(cart.1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +231,7 @@ fn pack(mut args: Arguments) -> Result<()> {
|
||||
|
||||
let out_file = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
|
||||
let cart = load_cart(
|
||||
let (cart, _) = load_cart(
|
||||
&in_file,
|
||||
&Config {
|
||||
pack: Some(pack_config),
|
||||
@@ -216,7 +261,7 @@ fn compile(mut args: Arguments) -> Result<()> {
|
||||
let out_file = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
|
||||
let module = curlywas::compile_file(in_file, options)?;
|
||||
File::create(out_file)?.write_all(&module)?;
|
||||
File::create(out_file)?.write_all(&module.wasm)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,26 +71,100 @@ impl BaseModule {
|
||||
add_function(&mut functions, &type_map, "randomSeed", &[I32], None);
|
||||
|
||||
add_function(&mut functions, &type_map, "cls", &[I32], None);
|
||||
add_function(&mut functions, &type_map, "setPixel", &[I32, I32, I32], None);
|
||||
add_function(&mut functions, &type_map, "getPixel", &[I32, I32], Some(I32));
|
||||
add_function(&mut functions, &type_map, "hline", &[I32, I32, I32, I32], None);
|
||||
add_function(&mut functions, &type_map, "rectangle", &[F32, F32, F32, F32, I32], None);
|
||||
add_function(&mut functions, &type_map, "circle", &[F32, F32, F32, I32], None);
|
||||
add_function(&mut functions, &type_map, "line", &[F32, F32, F32, F32, I32], None);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"setPixel",
|
||||
&[I32, I32, I32],
|
||||
None,
|
||||
);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"getPixel",
|
||||
&[I32, I32],
|
||||
Some(I32),
|
||||
);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"hline",
|
||||
&[I32, I32, I32, I32],
|
||||
None,
|
||||
);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"rectangle",
|
||||
&[F32, F32, F32, F32, I32],
|
||||
None,
|
||||
);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"circle",
|
||||
&[F32, F32, F32, I32],
|
||||
None,
|
||||
);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"line",
|
||||
&[F32, F32, F32, F32, I32],
|
||||
None,
|
||||
);
|
||||
|
||||
add_function(&mut functions, &type_map, "time", &[], Some(F32));
|
||||
add_function(&mut functions, &type_map, "isButtonPressed", &[I32], Some(I32));
|
||||
add_function(&mut functions, &type_map, "isButtonTriggered", &[I32], Some(I32));
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"isButtonPressed",
|
||||
&[I32],
|
||||
Some(I32),
|
||||
);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"isButtonTriggered",
|
||||
&[I32],
|
||||
Some(I32),
|
||||
);
|
||||
|
||||
add_function(&mut functions, &type_map, "printChar", &[I32], None);
|
||||
add_function(&mut functions, &type_map, "printString", &[I32], None);
|
||||
add_function(&mut functions, &type_map, "printInt", &[I32], None);
|
||||
add_function(&mut functions, &type_map, "setTextColor", &[I32], None);
|
||||
add_function(&mut functions, &type_map, "setBackgroundColor", &[I32], None);
|
||||
add_function(&mut functions, &type_map, "setCursorPosition", &[I32, I32], None);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"setBackgroundColor",
|
||||
&[I32],
|
||||
None,
|
||||
);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"setCursorPosition",
|
||||
&[I32, I32],
|
||||
None,
|
||||
);
|
||||
|
||||
add_function(&mut functions, &type_map, "rectangle_outline", &[F32, F32, F32, F32, I32], None);
|
||||
add_function(&mut functions, &type_map, "circle_outline", &[F32, F32, F32, I32], None);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"rectangle_outline",
|
||||
&[F32, F32, F32, F32, I32],
|
||||
None,
|
||||
);
|
||||
add_function(
|
||||
&mut functions,
|
||||
&type_map,
|
||||
"circle_outline",
|
||||
&[F32, F32, F32, I32],
|
||||
None,
|
||||
);
|
||||
|
||||
add_function(&mut functions, &type_map, "exp", &[F32], Some(F32));
|
||||
|
||||
for i in functions.len()..64 {
|
||||
add_function(
|
||||
@@ -214,6 +288,68 @@ impl BaseModule {
|
||||
File::create(path)?.write_all(&data)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_as_cwa<P: AsRef<Path>>(&self, path: P) -> Result<()> {
|
||||
fn inner(mut file: File, base: &BaseModule) -> Result<()> {
|
||||
writeln!(file, "// MicroW8 APIs, to be `include`d in CurlyWas sources")?;
|
||||
writeln!(file, "import \"env.memory\" memory({});", base.memory)?;
|
||||
writeln!(file)?;
|
||||
for &(module, ref name, type_id) in &base.function_imports {
|
||||
if !name.contains("reserved") {
|
||||
let ty = &base.types[type_id as usize];
|
||||
let params: Vec<&str> = ty.params.iter().copied().map(type_to_str).collect();
|
||||
write!(
|
||||
file,
|
||||
"import \"{}.{}\" fn {}({})",
|
||||
module,
|
||||
name,
|
||||
name,
|
||||
params.join(", ")
|
||||
)?;
|
||||
if let Some(result) = ty.result {
|
||||
write!(file, " -> {}", type_to_str(result))?;
|
||||
}
|
||||
writeln!(file, ";")?;
|
||||
}
|
||||
}
|
||||
|
||||
writeln!(file)?;
|
||||
for &(name, value) in CONSTANTS {
|
||||
writeln!(file, "const {} = 0x{:x};", name, value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
inner(File::create(path)?, self)
|
||||
}
|
||||
|
||||
pub fn write_as_wat<P: AsRef<Path>>(&self, path: P) -> Result<()> {
|
||||
fn inner(mut file: File, base: &BaseModule) -> Result<()> {
|
||||
writeln!(file, ";; MicroW8 APIs, in WAT (Wasm Text) format")?;
|
||||
writeln!(file, "(import \"env\" \"memory\" (memory {}))", base.memory)?;
|
||||
writeln!(file)?;
|
||||
for &(module, ref name, type_id) in &base.function_imports {
|
||||
if !name.contains("reserved") {
|
||||
let ty = &base.types[type_id as usize];
|
||||
write!(file, "(import \"{}\" \"{}\" (func ${}", module, name, name)?;
|
||||
for ¶m in &ty.params {
|
||||
write!(file, " (param {})", type_to_str(param))?;
|
||||
}
|
||||
if let Some(result) = ty.result {
|
||||
write!(file, " (result {})", type_to_str(result))?;
|
||||
}
|
||||
writeln!(file, "))")?;
|
||||
}
|
||||
}
|
||||
|
||||
writeln!(file)?;
|
||||
writeln!(file, ";; to use defines, include this file with a preprocessor\n;; like gpp (https://logological.org/gpp).")?;
|
||||
for &(name, value) in CONSTANTS {
|
||||
writeln!(file, "#define {} 0x{:x};", name, value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
inner(File::create(path)?, self)
|
||||
}
|
||||
}
|
||||
|
||||
fn add_function(
|
||||
@@ -241,3 +377,30 @@ fn lookup_type(
|
||||
};
|
||||
*type_map.get(&key).unwrap()
|
||||
}
|
||||
|
||||
fn type_to_str(ty: ValType) -> &'static str {
|
||||
match ty {
|
||||
ValType::I32 => "i32",
|
||||
ValType::I64 => "i64",
|
||||
ValType::F32 => "f32",
|
||||
ValType::F64 => "f64",
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
const CONSTANTS: &[(&str, u32)] = &[
|
||||
("TIME_MS", 0x40),
|
||||
("GAMEPAD", 0x44),
|
||||
("FRAMEBUFFER", 0x78),
|
||||
("PALETTE", 0x13000),
|
||||
("FONT", 0x13400),
|
||||
("USER_MEM", 0x14000),
|
||||
("BUTTON_UP", 0),
|
||||
("BUTTON_DOWN", 1),
|
||||
("BUTTON_LEFT", 2),
|
||||
("BUTTON_RIGHT", 3),
|
||||
("BUTTON_A", 4),
|
||||
("BUTTON_B", 5),
|
||||
("BUTTON_X", 6),
|
||||
("BUTTON_Y", 7)
|
||||
];
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use uw8_tool::BaseModule;
|
||||
use pico_args::Arguments;
|
||||
use uw8_tool::BaseModule;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut args = Arguments::from_env();
|
||||
@@ -32,6 +32,14 @@ fn main() -> Result<()> {
|
||||
let dest: PathBuf = args.free_from_str()?;
|
||||
uw8_tool::filter_exports(&source, &dest)?;
|
||||
}
|
||||
"base-cwa" => {
|
||||
let path: PathBuf = args.free_from_str()?;
|
||||
BaseModule::for_format_version(1)?.write_as_cwa(path)?;
|
||||
}
|
||||
"base-wat" => {
|
||||
let path: PathBuf = args.free_from_str()?;
|
||||
BaseModule::for_format_version(1)?.write_as_wat(path)?;
|
||||
}
|
||||
_ => {
|
||||
eprintln!("Unknown subcommand '{}'", cmd);
|
||||
print_help();
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="uw8">
|
||||
<a href="https://exoticorn.github.io/microw8">MicroW8</a> 0.1.1
|
||||
<a href="https://exoticorn.github.io/microw8">MicroW8</a> 0.1.2
|
||||
</div>
|
||||
<div id="centered">
|
||||
<canvas id="screen" width="320" height="240">
|
||||
|
||||
Reference in New Issue
Block a user