2 Commits

Author SHA1 Message Date
add49a1f8b fix #2: Crash when drawing zero sized line 2022-02-27 22:09:54 +01:00
8815a8e02e add full dependencies to file watcher 2022-02-27 21:50:33 +01:00
11 changed files with 200 additions and 85 deletions

2
Cargo.lock generated
View File

@@ -498,7 +498,7 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
[[package]]
name = "curlywas"
version = "0.1.0"
source = "git+https://github.com/exoticorn/curlywas.git?rev=cda3eb868bc1aaa837c4d36898d0e885ee8fce59#cda3eb868bc1aaa837c4d36898d0e885ee8fce59"
source = "git+https://github.com/exoticorn/curlywas.git?rev=89638565#896385654ab2c089200920b6dea4abec641c88d6"
dependencies = [
"anyhow",
"ariadne",

View File

@@ -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 = "cda3eb868bc1aaa837c4d36898d0e885ee8fce59" }
curlywas = { git = "https://github.com/exoticorn/curlywas.git", rev = "89638565" }
wat = "1"
uw8-tool = { path = "uw8-tool" }
same-file = "1"

View File

@@ -9,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;
}

127
platform/Cargo.lock generated
View File

@@ -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"

View File

@@ -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.

View File

@@ -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)?;

View File

@@ -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);
}
//////////

View File

@@ -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,
})
}
}

View File

@@ -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) {
eprintln!("Load error: {}", err);
if !watch_mode {
exit(1);
}
}
let mut first_run = true;
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);
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);
}
}
}
first_run = false;
}
if let Err(err) = runtime.run_frame() {
@@ -134,15 +136,25 @@ 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)?;
dependencies.push(filename.to_path_buf());
cart
}
SourceType::Wat => wat::parse_file(filename)?,
SourceType::CurlyWas => curlywas::compile_file(filename, curlywas::Options::default())?,
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 {
@@ -154,7 +166,7 @@ fn load_cart(filename: &Path, config: &Config) -> Result<Vec<u8>> {
File::create(path)?.write_all(&cart)?;
}
Ok(cart)
Ok((cart, dependencies))
}
enum SourceType {
@@ -193,14 +205,14 @@ impl SourceType {
}
#[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)
}
}
@@ -219,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),
@@ -249,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(())
}