3 Commits

Author SHA1 Message Date
1a06ebbc95 update zig example 2023-04-08 15:10:09 +02:00
d1b6fa36e8 update frame pacing calculation in native runtime 2023-04-07 18:33:22 +02:00
b3a8512129 update frame pacing calculation in web runtime
fixes carts running too slow in chrome
2023-04-07 17:08:04 +02:00
37 changed files with 3982 additions and 5296 deletions

3640
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "uw8" name = "uw8"
version = "0.4.0" version = "0.2.2"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -11,21 +11,21 @@ native = ["wasmtime", "uw8-window", "cpal", "rubato" ]
browser = ["warp", "tokio", "tokio-stream", "webbrowser"] browser = ["warp", "tokio", "tokio-stream", "webbrowser"]
[dependencies] [dependencies]
wasmtime = { git = "https://github.com/bytecodealliance/wasmtime.git", rev = "0f48f939b9870036562ca02ff21253547a9f1a5c", optional = true } wasmtime = { version = "5.0.0", optional = true }
anyhow = "1" anyhow = "1"
env_logger = "0.11.3" env_logger = "0.10"
log = "0.4" log = "0.4"
uw8-window = { path = "uw8-window", optional = true } uw8-window = { path = "uw8-window", optional = true }
notify-debouncer-mini = { version = "0.4.1", default-features = false } notify-debouncer-mini = { version = "0.2.1", default-features = false }
pico-args = "0.5" pico-args = "0.5"
curlywas = { git = "https://github.com/exoticorn/curlywas.git", rev = "0e7ea50" } curlywas = { git = "https://github.com/exoticorn/curlywas.git", rev = "0e7ea50" }
wat = "1" wat = "1"
uw8-tool = { path = "uw8-tool" } uw8-tool = { path = "uw8-tool" }
same-file = "1" same-file = "1"
warp = { version = "0.3.6", optional = true } warp = { version = "0.3.3", optional = true }
tokio = { version = "1.37.0", features = ["sync", "rt"], optional = true } tokio = { version = "1.24.0", features = ["sync", "rt"], optional = true }
tokio-stream = { version = "0.1.15", features = ["sync"], optional = true } tokio-stream = { version = "0.1.11", features = ["sync"], optional = true }
webbrowser = { version = "0.8.13", optional = true } webbrowser = { version = "0.8.6", optional = true }
ansi_term = "0.12.1" ansi_term = "0.12.1"
cpal = { version = "0.15.3", optional = true } cpal = { version = "0.14.2", optional = true }
rubato = { version = "0.15.0", optional = true } rubato = { version = "0.12.0", optional = true }

View File

@@ -15,9 +15,9 @@ See [here](https://exoticorn.github.io/microw8/) for more information and docs.
## Downloads ## Downloads
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.3.0/microw8-0.4.0-linux.tgz) * [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.3.0/microw8-0.4.0-macos.tgz) * [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.3.0/microw8-0.4.0-windows.zip) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-windows.zip)
The download includes The download includes

View File

@@ -1,14 +0,0 @@
include "../include/microw8-api.cwa"
export fn upd() {
printString(USER_MEM);
}
data USER_MEM {
// clear screen, switch to graphics text mode, text scale 4
i8(12, 5, 30, 4)
// text color, position, print two lines
i8(15, 86, 31, 8, 80) "Hello," i8(8, 8, 8, 8, 8, 10) "MicroW8!"
// print same two lines with different color and slight offset
i8(15, 47, 31, 10, 82) "Hello," i8(8, 8, 8, 8, 8, 10) "MicroW8!" i8(0)
}

View File

@@ -4,13 +4,13 @@ const SPRITE = 0x20000;
export fn upd() { export fn upd() {
cls(0); cls(0);
let t = time() / 2_f; let t = time();
let i: i32; let i: i32;
loop spriteLoop { loop spriteLoop {
let inline x = sin(t * -1.3 + i as f32 * (3.141 / 30_f)) * 180_f + 160_f; let inline x = sin(t * -1.3 + i as f32 / 8_f) * 180_f + 160_f;
let inline y = sin(t * 1.7 + i as f32 * (3.141 / 40_f)) * 140_f + 120_f; let inline y = sin(t * 1.7 + i as f32 / 9_f) * 140_f + 120_f;
blitSprite(SPRITE, 16, x as i32, y as i32, (i & 3) * 0x200 + 0x100); blitSprite(SPRITE, 16, x as i32, y as i32, 0x100);
branch_if (i +:= 1) < 100: spriteLoop; branch_if (i +:= 1) < 200: spriteLoop;
} }
} }

View File

@@ -3,16 +3,14 @@ include "../include/microw8-api.cwa"
export fn upd() { export fn upd() {
let i: i32; let i: i32;
loop pixels { loop pixels {
let inline t = 16!56; let inline t = time() * 63 as f32;
let inline x = (i % 320 - 160) as f32; let lazy x = (i % 320 - 160) as f32;
let inline y = (i #/ 320 - 120) as f32; let lazy y = (i / 320 - 120) as f32;
let inline d = 0xa000 as f32 / sqrt(x * x + y * y); let inline d = 40000 as f32 / sqrt(x * x + y * y);
let inline a = atan2(x, y) * 163_f; // (512 / pi) let inline u = atan2(x, y) * (512.0 / 3.141);
let inline u = i32.trunc_sat_f32_s(a) + t; let inline c = ((i32.trunc_sat_f32_s(d + t * 2 as f32) ^ i32.trunc_sat_f32_s(u + t)) & 255) >> 4;
let inline v = i32.trunc_sat_f32_s(d) + t * 2;
let inline c = ((v ^ u) #/ 16) % 16;
i?FRAMEBUFFER = c; i?FRAMEBUFFER = c;
branch_if (i := i + 1) < 320*240: pixels; branch_if (i := i + 1) < 320*240: pixels;
} }
} }

View File

@@ -5,11 +5,7 @@ pub fn build(b: *std.build.Builder) void {
const lib = b.addSharedLibrary("cart", "main.zig", .unversioned); const lib = b.addSharedLibrary("cart", "main.zig", .unversioned);
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(.{ lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding, .cpu_features_add = std.Target.wasm.featureSet(&.{.nontrapping_fptoint}) });
.cpu_arch = .wasm32,
.os_tag = .freestanding,
.cpu_features_add = std.Target.wasm.featureSet(&.{ .nontrapping_fptoint })
});
lib.import_memory = true; lib.import_memory = true;
lib.initial_memory = 262144; lib.initial_memory = 262144;
lib.max_memory = 262144; lib.max_memory = 262144;
@@ -18,19 +14,13 @@ pub fn build(b: *std.build.Builder) void {
lib.install(); lib.install();
if (lib.install_step) |install_step| { if (lib.install_step) |install_step| {
const run_filter_exports = b.addSystemCommand(&[_][]const u8{ const run_filter_exports = b.addSystemCommand(&[_][]const u8{ "uw8", "filter-exports", "zig-out/lib/cart.wasm", "zig-out/lib/cart-filtered.wasm" });
"uw8", "filter-exports", "zig-out/lib/cart.wasm", "zig-out/lib/cart-filtered.wasm"
});
run_filter_exports.step.dependOn(&install_step.step); run_filter_exports.step.dependOn(&install_step.step);
const run_wasm_opt = b.addSystemCommand(&[_][]const u8{ const run_wasm_opt = b.addSystemCommand(&[_][]const u8{ "wasm-opt", "--enable-nontrapping-float-to-int", "-Oz", "-o", "zig-out/cart.wasm", "zig-out/lib/cart-filtered.wasm" });
"wasm-opt", "-Oz", "-o", "zig-out/cart.wasm", "zig-out/lib/cart-filtered.wasm"
});
run_wasm_opt.step.dependOn(&run_filter_exports.step); run_wasm_opt.step.dependOn(&run_filter_exports.step);
const run_uw8_pack = b.addSystemCommand(&[_][]const u8{ const run_uw8_pack = b.addSystemCommand(&[_][]const u8{ "uw8", "pack", "-l", "9", "zig-out/cart.wasm", "zig-out/cart.uw8" });
"uw8", "pack", "-l", "9", "zig-out/cart.wasm", "zig-out/cart.uw8"
});
run_uw8_pack.step.dependOn(&run_wasm_opt.step); run_uw8_pack.step.dependOn(&run_wasm_opt.step);
const make_opt = b.step("make_opt", "make size optimized cart"); const make_opt = b.step("make_opt", "make size optimized cart");

View File

@@ -1,11 +1,11 @@
extern fn atan2(x: f32, y: f32) f32; extern fn atan2(x: f32, y: f32) f32;
extern fn time() f32; extern fn time() f32;
pub const FRAMEBUFFER: *[320*240]u8 = @intToPtr(*[320*240]u8, 120); pub const FRAMEBUFFER: *[320 * 240]u8 = @intToPtr(*[320 * 240]u8, 120);
export fn upd() void { export fn upd() void {
var i: u32 = 0; var i: u32 = 0;
while(true) { while (true) {
var t = time() * 63.0; var t = time() * 63.0;
var x = @intToFloat(f32, (@intCast(i32, i % 320) - 160)); var x = @intToFloat(f32, (@intCast(i32, i % 320) - 160));
var y = @intToFloat(f32, (@intCast(i32, i / 320) - 120)); var y = @intToFloat(f32, (@intCast(i32, i / 320) - 120));
@@ -13,8 +13,10 @@ export fn upd() void {
var u = atan2(x, y) * 512.0 / 3.141; var u = atan2(x, y) * 512.0 / 3.141;
var c = @intCast(u8, (@floatToInt(i32, d + t * 2.0) ^ @floatToInt(i32, u + t)) & 255) >> 4; var c = @intCast(u8, (@floatToInt(i32, d + t * 2.0) ^ @floatToInt(i32, u + t)) & 255) >> 4;
FRAMEBUFFER[@as(usize, i)] = c; FRAMEBUFFER[i] = c;
i += 1; i += 1;
if(i >= 320*240) { break; } if (i >= 320 * 240) {
break;
}
} }
} }

380
platform/Cargo.lock generated
View File

@@ -19,54 +19,47 @@ dependencies = [
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.11" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [ dependencies = [
"cfg-if", "getrandom",
"once_cell", "once_cell",
"version_check", "version_check",
"zerocopy",
] ]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.81" version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
[[package]] [[package]]
name = "ariadne" name = "ariadne"
version = "0.1.5" version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1cb2a2046bea8ce5e875551f5772024882de0b540c7f93dfc5d6cf1ca8b030c" checksum = "7080ae01b2f0c312065d4914cd0f0de045eb8832e9415b355106a6cff3073cb4"
dependencies = [ dependencies = [
"yansi", "yansi",
] ]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.2.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.15.0" version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.92" version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
[[package]] [[package]]
name = "cdivsufsort" name = "cdivsufsort"
@@ -95,47 +88,54 @@ dependencies = [
[[package]] [[package]]
name = "const-random" name = "const-random"
version = "0.1.18" version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4"
dependencies = [ dependencies = [
"const-random-macro", "const-random-macro",
"proc-macro-hack",
] ]
[[package]] [[package]]
name = "const-random-macro" name = "const-random-macro"
version = "0.1.16" version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"once_cell", "lazy_static",
"proc-macro-hack",
"tiny-keccak", "tiny-keccak",
] ]
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.4.0" version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.12" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [ dependencies = [
"cfg-if",
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.19" version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]] [[package]]
name = "crunchy" name = "crunchy"
@@ -156,80 +156,54 @@ dependencies = [
"wasmparser 0.83.0", "wasmparser 0.83.0",
] ]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]] [[package]]
name = "fallible_collections" name = "fallible_collections"
version = "0.4.9" version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a88c69768c0a15262df21899142bc6df9b9b823546d4b4b9a7bc2d6c448ec6fd" checksum = "3f57ccc32870366ae684be48b32a1a2e196f98a42a9b4361fe77e13fd4a34755"
dependencies = [ dependencies = [
"hashbrown 0.13.2", "hashbrown",
] ]
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.28" version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
] ]
[[package]] [[package]]
name = "getrandom" name = "form_urlencoded"
version = "0.2.14" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
dependencies = [
"percent-encoding",
]
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi", "wasi",
] ]
[[package]]
name = "gimli"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
dependencies = [
"fallible-iterator",
"indexmap 1.9.3",
"stable_deref_trait",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [ dependencies = [
"ahash 0.8.11", "ahash 0.7.6",
] ]
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.3" version = "0.3.3"
@@ -246,25 +220,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]] [[package]]
name = "indexmap" name = "idna"
version = "1.9.3" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
dependencies = [ dependencies = [
"autocfg", "unicode-bidi",
"hashbrown 0.12.3", "unicode-normalization",
] ]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.2.6" version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [ dependencies = [
"equivalent", "autocfg",
"hashbrown 0.14.3", "hashbrown",
] ]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "leb128" name = "leb128"
version = "0.2.5" version = "0.2.5"
@@ -279,15 +259,15 @@ checksum = "478ee9e62aaeaf5b140bd4138753d1f109765488581444218d3ddda43234f3e8"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]] [[package]]
name = "lodepng" name = "lodepng"
version = "3.10.1" version = "3.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a42d298694b14401847de29abd44adf278b42e989e516deac7b72018400002d8" checksum = "f0ad39f75bbaa4b10bb6f2316543632a8046a5bcf9c785488d79720b21f044f8"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"fallible_collections", "fallible_collections",
@@ -298,45 +278,55 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.21" version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.7.2" version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
dependencies = [ dependencies = [
"adler", "adler",
] ]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.18" version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.19.0" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]] [[package]]
name = "pbr" name = "pbr"
version = "1.1.1" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5827dfa0d69b6c92493d6c38e633bbaa5937c153d0d7c28bf12313f8c6d514" checksum = "ff5751d87f7c00ae6403eb1fcbba229b9c76c9a30de8c1cf87182177b168cea2"
dependencies = [ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"libc", "libc",
"time",
"winapi", "winapi",
] ]
[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]] [[package]]
name = "pico-args" name = "pico-args"
version = "0.4.2" version = "0.4.2"
@@ -360,28 +350,34 @@ dependencies = [
] ]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro-hack"
version = "1.0.79" version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [ dependencies = [
"unicode-ident", "unicode-xid",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.35" version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
name = "rgb" name = "rgb"
version = "0.8.37" version = "0.8.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" checksum = "3603b7d71ca82644f79b5a06d1220e9a58ede60bd32255f698cb1af8838b8db3"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
] ]
@@ -395,58 +391,45 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "semver"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-ident", "unicode-xid",
]
[[package]]
name = "syn"
version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
] ]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.58" version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.58" version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn",
]
[[package]]
name = "time"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
dependencies = [
"libc",
"winapi",
] ]
[[package]] [[package]]
@@ -459,16 +442,46 @@ dependencies = [
] ]
[[package]] [[package]]
name = "unicode-ident" name = "tinyvec"
version = "1.0.12" version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "unicode-bidi"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.11.0" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]] [[package]]
name = "upkr" name = "upkr"
@@ -481,6 +494,17 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "url"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]] [[package]]
name = "uw8-tool" name = "uw8-tool"
version = "0.1.0" version = "0.1.0"
@@ -490,30 +514,28 @@ dependencies = [
"pico-args 0.5.0", "pico-args 0.5.0",
"upkr", "upkr",
"walrus", "walrus",
"wasm-encoder 0.201.0", "wasm-encoder 0.22.0",
"wasmparser 0.201.0", "wasmparser 0.99.0",
] ]
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]] [[package]]
name = "walrus" name = "walrus"
version = "0.20.3" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c03529cd0c4400a2449f640d2f27cd1b48c3065226d15e26d98e4429ab0adb7" checksum = "4eb08e48cde54c05f363d984bb54ce374f49e242def9468d2e1b6c2372d291f8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"gimli",
"id-arena", "id-arena",
"leb128", "leb128",
"log", "log",
"walrus-macro", "walrus-macro",
"wasm-encoder 0.29.0", "wasmparser 0.77.0",
"wasmparser 0.80.2",
] ]
[[package]] [[package]]
@@ -525,14 +547,14 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn",
] ]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
@@ -545,27 +567,18 @@ dependencies = [
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.29.0" version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881" checksum = "ef126be0e14bdf355ac1a8b41afc89195289e5c7179f80118e3abddb472f0810"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-encoder"
version = "0.201.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9c7d2731df60006819b013f64ccc2019691deccf6e11a1804bc850cd6748f1a"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.80.2" version = "0.77.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "449167e2832691a1bff24cde28d2804e90e09586a448c8e76984792c44334a6b" checksum = "b35c86d22e720a07d954ebbed772d01180501afe7d03d464f413bb5f8914a8d6"
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
@@ -575,13 +588,12 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a"
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.201.0" version = "0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" checksum = "9ef3b717afc67f848f412d4f02c127dd3e35a0eecd58c684580414df4fde01d3"
dependencies = [ dependencies = [
"bitflags", "indexmap",
"indexmap 2.2.6", "url",
"semver",
] ]
[[package]] [[package]]
@@ -608,26 +620,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "yansi" name = "yansi"
version = "0.5.1" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71"
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.58",
]

Binary file not shown.

Binary file not shown.

View File

@@ -62,6 +62,7 @@ export fn sndGes(t: i32) -> f32 {
let phase = channelState!GesChannelState.Phase; let phase = channelState!GesChannelState.Phase;
let inline pulseWidth = channelReg?1; let inline pulseWidth = channelReg?1;
let phaseShift = (pulseWidth - 128) * 255;
let invPhaseInc = 1 as f32 / phaseInc as f32; let invPhaseInc = 1 as f32 / phaseInc as f32;
i = 0; i = 0;
@@ -130,7 +131,7 @@ export fn sndGes(t: i32) -> f32 {
let phaseInc = (freq * (65536.0 / 44100.0)) as i32; let phaseInc = (freq * (65536.0 / 44100.0)) as i32;
let phase = channelState!GesChannelState.Phase; let phase = channelState!GesChannelState.Phase;
if modSrc < ch { if modSrc > ch {
phase = phase - (phaseInc << 6); phase = phase - (phaseInc << 6);
} }

View File

@@ -62,7 +62,6 @@ export fn cls(col: i32) {
textCursorX = 0; textCursorX = 0;
textCursorY = 0; textCursorY = 0;
outputChannel = 0; outputChannel = 0;
textScale = 1;
memory.fill(120, col, 320*240); memory.fill(120, col, 320*240);
} }
@@ -448,7 +447,6 @@ global mut textCursorY = 0;
global mut textColor = 15; global mut textColor = 15;
global mut bgColor = 0; global mut bgColor = 0;
global mut outputChannel = 0; global mut outputChannel = 0;
global mut textScale = 1;
export fn printChar(char: i32) { export fn printChar(char: i32) {
loop chars { loop chars {
@@ -460,8 +458,6 @@ export fn printChar(char: i32) {
global mut controlCodeLength = 0; global mut controlCodeLength = 0;
fn printSingleChar(char: i32) { fn printSingleChar(char: i32) {
let charSize = 8 * textScale;
if outputChannel >= 2 & (char < 4 | char > 6) { if outputChannel >= 2 & (char < 4 | char > 6) {
logChar(char); logChar(char);
return; return;
@@ -495,9 +491,9 @@ fn printSingleChar(char: i32) {
} }
if char == 8 { if char == 8 {
textCursorX = textCursorX - charSize; textCursorX = textCursorX - 8;
if !outputChannel & textCursorX < 0 { if !outputChannel & textCursorX < 0 {
textCursorX = 320-charSize; textCursorX = 320-8;
printSingleChar(11); printSingleChar(11);
} }
return; return;
@@ -507,34 +503,34 @@ fn printSingleChar(char: i32) {
if !outputChannel & textCursorX >= 320 { if !outputChannel & textCursorX >= 320 {
printChar(0xd0a); printChar(0xd0a);
} }
textCursorX = textCursorX + charSize; textCursorX = textCursorX + 8;
return; return;
} }
if char == 10 { if char == 10 {
textCursorY = textCursorY + charSize; textCursorY = textCursorY + 8;
if !outputChannel & textCursorY >= 240 { if !outputChannel & textCursorY >= 240 {
textCursorY = 240 - charSize; textCursorY = 240 - 8;
let i: i32; let i: i32;
loop scroll_copy { loop scroll_copy {
i!120 = (i + 320 * charSize)!120; i!120 = i!(120 + 320 * 8);
branch_if (i := i + 4) < 320 * (240 - charSize): scroll_copy; branch_if (i := i + 4) < 320 * (240 - 8): scroll_copy;
} }
rectangle(0 as f32, (240 - charSize) as f32, 320 as f32, charSize as f32, bgColor); rectangle(0 as f32, (240 - 8) as f32, 320 as f32, 8 as f32, bgColor);
} }
return; return;
} }
if char == 11 { if char == 11 {
textCursorY = textCursorY - charSize; textCursorY = textCursorY - 8;
if !outputChannel & textCursorY < 0 { if !outputChannel & textCursorY < 0 {
textCursorY = 0; textCursorY = 0;
let i = 320 * (240 - charSize); let i = 320 * (240 - 8);
loop scroll_copy { loop scroll_copy {
(i + 320 * charSize)!116 = i!116; i!(116 + 320 * 8) = i!116;
branch_if (i := i - 4): scroll_copy; branch_if (i := i - 4): scroll_copy;
} }
rectangle(0 as f32, 0 as f32, 320 as f32, charSize as f32, bgColor); rectangle(0 as f32, 0 as f32, 320 as f32, 8 as f32, bgColor);
} }
return; return;
} }
@@ -566,12 +562,6 @@ fn printSingleChar(char: i32) {
return; return;
} }
if char == 30 {
let scale = 0x12d20?1;
textScale = select(scale > 0 & scale <= 16, scale, 1);
return;
}
if char == 31 { if char == 31 {
textCursorX = 0x12d20?1 * (8 - outputChannel * 6); textCursorX = 0x12d20?1 * (8 - outputChannel * 6);
textCursorY = 0x12d20?2 * (8 - outputChannel * 7); textCursorY = 0x12d20?2 * (8 - outputChannel * 7);
@@ -594,7 +584,7 @@ data(0x12d00) {
1, 1, 1, 1, // 16-19, 1, 1, 1, 1, // 16-19,
1, 1, 1, 1, // 20-23, 1, 1, 1, 1, // 20-23,
1, 1, 1, 1, // 24-27, 1, 1, 1, 1, // 24-27,
1, 1, 2, 3 // 28-31 1, 1, 1, 3 // 28-31
) )
} }
@@ -603,28 +593,26 @@ fn drawChar(char: i32) {
printChar(0xd0a); printChar(0xd0a);
} }
let charSize = 8 * textScale;
let y: i32; let y: i32;
loop rows { loop rows {
let bits = (char * 8 + y / textScale)?0x13400; let bits = (char * 8 + y)?0x13400;
let x = 0; let x = 0;
if outputChannel { if outputChannel {
loop pixels { loop pixels {
if (bits << (x / textScale)) & 128 { if (bits := bits << 1) & 256 {
setPixel(textCursorX + x, textCursorY + y, textColor); setPixel(textCursorX + x, textCursorY + y, textColor);
} }
branch_if (x := x + 1) < charSize: pixels; branch_if (x := x + 1) < 8: pixels;
} }
} else { } else {
loop pixels { loop pixels {
setPixel(textCursorX + x, textCursorY + y, select((bits << (x / textScale)) & 128, textColor, bgColor)); setPixel(textCursorX + x, textCursorY + y, select((bits := bits << 1) & 256, textColor, bgColor));
branch_if (x := x + 1) < charSize: pixels; branch_if (x := x + 1) < 8: pixels;
} }
} }
branch_if (y := y + 1) < charSize: rows; branch_if (y := y + 1) < 8: rows;
} }
textCursorX = textCursorX + charSize; textCursorX = textCursorX + 8;
} }
export fn printString(ptr: i32) { export fn printString(ptr: i32) {

View File

@@ -31,20 +31,51 @@ Examplers for older versions:
## Versions ## Versions
### v0.4.0 ### v0.2.2
* [Web runtime](../v0.4.0) * [Web runtime](v0.2.2)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.4.0/microw8-0.4.0-linux.tgz) * [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.4.0/microw8-0.4.0-macos.tgz) * [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.4.0/microw8-0.4.0-windows.zip) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-windows.zip)
Changes: Changes:
* add support for sound on mono- and surround-only devices * call `start` function after loading cart if the cart exports one
* update wasmtime dependency to fix performance regression in 0.3.0 * fix `sndGes` having the wrong name and not being included in the auto imports
* add frame counter since module start at location 72 * fix control codes 4-6 (change text output mode) being invoked when used as parameters in other control sequences
* add 6 and 7 parameter function types to base module * only open browser window once a cart was compiled sucessfully when running with `-b`
### v0.2.1
* [Web runtime](v0.2.1)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.1/microw8-0.2.1-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.1/microw8-0.2.1-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.1/microw8-0.2.1-windows.zip)
Changes:
* new gpu accelerated renderer with (optional) crt filter
* optimized `hline` function, a big speed-up when drawing large filled circles or rectangles
* print fractional size of packed `uw8` cart
### v0.2.0
* [Web runtime](v0.2.0)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-windows.zip)
Changes:
* [add sound support!](docs#sound)
* add support to redirect text output to the console for debugging using control code 6
* update curlywas:
* add support for `else if`
* add support for escape sequences in strings
* add support for char literals
* add support for binop-assignment, eg. `+=`, `^=`, `<<=` etc. (also support for the tee operator: `+:=`)
* "integer constant cast to float" literal syntax in CurlyWas (ex. `1_f` is equivalent to `1 as f32`)
### Older versions ### Older versions
[Find older versions here.](versions) [Find older versions here.](versions)

View File

@@ -5,7 +5,7 @@ description = "Docs"
# Overview # Overview
MicroW8 loads WebAssembly modules with a maximum size of 256kb. Your module needs to export MicroW8 loads WebAssembly modules with a maximum size of 256kb. You module needs to export
a function `fn upd()` which will be called once per frame. a function `fn upd()` which will be called once per frame.
After calling `upd` MicroW8 will display the 320x240 8bpp framebuffer located After calling `upd` MicroW8 will display the 320x240 8bpp framebuffer located
at offset 120 in memory with the 32bpp palette located at 0x13000. at offset 120 in memory with the 32bpp palette located at 0x13000.
@@ -21,7 +21,7 @@ loaded.
00000-00040: user memory 00000-00040: user memory
00040-00044: time since module start in ms 00040-00044: time since module start in ms
00044-0004c: gamepad state 00044-0004c: gamepad state
0004c-00050: number of frames since module start 0004c-00050: reserved
00050-00070: sound data (synced to sound thread) 00050-00070: sound data (synced to sound thread)
00070-00078: reserved 00070-00078: reserved
00078-12c78: frame buffer 00078-12c78: frame buffer
@@ -238,13 +238,6 @@ When printing characters only the foreground pixels are set, the background is "
Moving/printing past any border does not cause any special operation, the cursor just goes off-screen. Moving/printing past any border does not cause any special operation, the cursor just goes off-screen.
### Text scale
An integer text scale factor in the range 1x-16x can be set with control char 30. An attempt to
set a scale outside that range will reset the scale to 1x.
After startup and `cls` the scale is initialized to 1x.
### Control chars ### Control chars
Characters 0-31 are control characters and don't print by default. They take the next 0-2 following characters as parameters. Characters 0-31 are control characters and don't print by default. They take the next 0-2 following characters as parameters.
@@ -269,8 +262,7 @@ Avoid the reserved control chars, they are currently NOPs but their behavior can
| 15 | color | Set the text color | | 15 | color | Set the text color |
| 16-23 | - | Reserved | | 16-23 | - | Reserved |
| 24 | - | Swap text/background colors | | 24 | - | Swap text/background colors |
| 25-29 | - | Reserved | | 25-30 | - | Reserved |
| 30 | scale | Set text scale (1-16) |
| 31 | x, y | Set cursor position (*) | | 31 | x, y | Set cursor position (*) |
(*) In graphics mode, the x coordinate is doubled when using control char 31 to be able to cover the whole screen with one byte. (*) In graphics mode, the x coordinate is doubled when using control char 31 to be able to cover the whole screen with one byte.
@@ -279,7 +271,7 @@ Avoid the reserved control chars, they are currently NOPs but their behavior can
Control code 6 switches all text output (except codes 4 and 5 to switch output back to the screen) to the console. Where exactly this ends Control code 6 switches all text output (except codes 4 and 5 to switch output back to the screen) to the console. Where exactly this ends
up (if at all) is an implementation detail of the runtimes. The native dev-runtime writes the debug output to `stdout`, the web runtime to up (if at all) is an implementation detail of the runtimes. The native dev-runtime writes the debug output to `stdout`, the web runtime to
the debug console using `console.log`. Both implementations buffer the output until they encounter a newline character (10) in the output stream. the debug console using `console.log`. Both implementation buffer the output until they encounter a newline character (10) in the output stream.
There may be future runtimes that ignore the debug output completely. There may be future runtimes that ignore the debug output completely.
@@ -594,7 +586,7 @@ a base module provided by MicroW8.
You can generate this base module yourself using You can generate this base module yourself using
`uw8-tool`. As a quick summary, it provides all function `uw8-tool`. As a quick summary, it provides all function
types with up to 7 parameters (i32 or f32) where the types with up to 5 parameters (i32 or f32) where the
`f32` parameters always preceed the `i32` parameters. `f32` parameters always preceed the `i32` parameters.
Then it includes all imports that MicroW8 provides, Then it includes all imports that MicroW8 provides,
a function section with a single function of type a function section with a single function of type
@@ -634,4 +626,4 @@ Pressing F9 opens a download dialog with a screenshot.
## Devkit mode ## Devkit mode
Append `#devkit` to the web runtime url in order to switch to devkit mode. In devkit mode, standard web assembly modules Append `#devkit` to the web runtime url in order to switch to devkit mode. In devkit mode, standard web assembly modules
are loaded bypassing the loader, removing all size restrictions. At the same time, the memory limit is increased to 1GB. are loaded bypassing the loader, removing all size restrictions. At the same time, the memory limit is increased to 1GB.

View File

@@ -2,64 +2,9 @@
description = "Versions" description = "Versions"
+++ +++
### v0.4.0
* [Web runtime](../v0.4.0)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.4.0/microw8-0.4.0-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.4.0/microw8-0.4.0-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.4.0/microw8-0.4.0-windows.zip)
Changes:
* add support for sound on mono- and surround-only devices
* update wasmtime dependency to fix performance regression in 0.3.0
* add frame counter since module start at location 72
* add 6 and 7 parameter function types to base module
### v0.3.0
* [Web runtime](../v0.3.0)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.3.0/microw8-0.3.0-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.3.0/microw8-0.3.0-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.3.0/microw8-0.3.0-windows.zip)
Changes:
* add blitSprite and grabSprite API calls
* add support for integer scaling up to 16x for printing text
* fix incompatibility with sound devices only offering 16bit audio formats
* add support for br_table instruction in packed carts
### v0.2.2
* [Web runtime](../v0.2.2)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.2/microw8-0.2.2-windows.zip)
Changes:
* call `start` function after loading cart if the cart exports one
* fix `sndGes` having the wrong name and not being included in the auto imports
* fix control codes 4-6 (change text output mode) being invoked when used as parameters in other control sequences
* only open browser window once a cart was compiled sucessfully when running with `-b`
### v0.2.1
* [Web runtime](../v0.2.1)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.1/microw8-0.2.1-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.1/microw8-0.2.1-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.1/microw8-0.2.1-windows.zip)
Changes:
* new gpu accelerated renderer with (optional) crt filter
* optimized `hline` function, a big speed-up when drawing large filled circles or rectangles
* print fractional size of packed `uw8` cart
### v0.2.0 ### v0.2.0
* [Web runtime](../v0.2.0) * [Web runtime](v0.2.0)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-linux.tgz) * [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-macos.tgz) * [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-windows.zip) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0/microw8-0.2.0-windows.zip)
@@ -77,7 +22,7 @@ Changes:
### v0.2.0-rc3 ### v0.2.0-rc3
* [Web runtime](../v0.2.0-rc3) * [Web runtime](v0.2.0-rc3)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc3/microw8-0.2.0-rc3-linux.tgz) * [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc3/microw8-0.2.0-rc3-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc3/microw8-0.2.0-rc3-macos.tgz) * [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc3/microw8-0.2.0-rc3-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc3/microw8-0.2.0-rc3-windows.zip) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc3/microw8-0.2.0-rc3-windows.zip)
@@ -95,7 +40,7 @@ Changes:
### v0.2.0-rc2 ### v0.2.0-rc2
* [Web runtime](../v0.2.0-rc2) * [Web runtime](v0.2.0-rc2)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc2/microw8-0.2.0-rc2-linux.tgz) * [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc2/microw8-0.2.0-rc2-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc2/microw8-0.2.0-rc2-macos.tgz) * [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc2/microw8-0.2.0-rc2-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc2/microw8-0.2.0-rc2-windows.zip) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc2/microw8-0.2.0-rc2-windows.zip)
@@ -106,7 +51,7 @@ Changes:
### v0.2.0-rc1 ### v0.2.0-rc1
* [Web runtime](../v0.2.0-rc1) * [Web runtime](v0.2.0-rc1)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc1/microw8-0.2.0-rc1-linux.tgz) * [Linux](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc1/microw8-0.2.0-rc1-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc1/microw8-0.2.0-rc1-macos.tgz) * [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc1/microw8-0.2.0-rc1-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc1/microw8-0.2.0-rc1-windows.zip) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.2.0-rc1/microw8-0.2.0-rc1-windows.zip)
@@ -122,7 +67,7 @@ Known issues:
### v0.1.2 ### v0.1.2
* [Web runtime](../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) * [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) * [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) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.2/microw8-0.1.2-windows.zip)
@@ -130,13 +75,13 @@ Known issues:
Changes: Changes:
* add option to `uw8 run` to run the cart in the browser using the web runtime * add option to `uw8 run` to run the cart in the browser using the web runtime
*../ CurlyWas: implement `include` support * CurlyWas: implement `include` support
* CurlyWas: implement support for constants * CurlyWas: implement support for constants
* fix crash when trying to draw zero sized line * fix crash when trying to draw zero sized line
### v0.1.1 ### v0.1.1
* [Web runtime](../v0.1.1) * [Web runtime](v0.1.1)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.1.1/microw8-0.1.1-linux.tgz) * [Linux](https://github.com/exoticorn/microw8/releases/download/v0.1.1/microw8-0.1.1-linux.tgz)
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.1.1/microw8-0.1.1-macos.tgz) * [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.1.1/microw8-0.1.1-macos.tgz)
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.1/microw8-0.1.1-windows.zip) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.1/microw8-0.1.1-windows.zip)
@@ -145,16 +90,16 @@ Changes:
* implement more robust file watcher * implement more robust file watcher
* add basic video recording on F10 in web runtime * add basic video recording on F10 in web runtime
*../ add screenshot on F9 * add screenshot on F9
* add watchdog to interrupt hanging update in native runtime * add watchdog to interrupt hanging update in native runtime
* add devkit mode to web runtime * add devkit mode to web runtime
*../ add unpack and compile commands to uw8 * add unpack and compile commands to uw8
* add support for table/element section in pack command * add support for table/element section in pack command
* disable wayland support (caused missing window decorations in gnome) * disable wayland support (caused missing window decorations in gnome)
### v0.1.0 ### v0.1.0
* [Web runtime](../v0.1.0) * [Web runtime](v0.1.0)
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.1.0/microw8-0.1.0-linux.tgz) * [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) * [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) * [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.0/microw8-0.1.0-windows.zip)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@
<section> <section>
<h1 class="text-center heading-text">A WebAssembly based fantasy console</h1> <h1 class="text-center heading-text">A WebAssembly based fantasy console</h1>
</section> </section>
<a href="v0.4.0"> <a href="v0.2.2">
<img class="demonstration-gif" style="width:640px;height:480px;image-rendering:pixelated" src="img/technotunnel.png"></img> <img class="demonstration-gif" style="width:640px;height:480px;image-rendering:pixelated" src="img/technotunnel.png"></img>
</a> </a>
</div> </div>
@@ -15,4 +15,4 @@
{% endblock hero %} {% endblock hero %}
{% block footer %} {% block footer %}
{% endblock footer %} {% endblock footer %}

View File

@@ -16,14 +16,16 @@ pub struct FileWatcher {
impl FileWatcher { impl FileWatcher {
pub fn new() -> Result<FileWatcher> { pub fn new() -> Result<FileWatcher> {
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
let debouncer = new_debouncer(Duration::from_millis(100), move |res| match res { let debouncer = new_debouncer(Duration::from_millis(100), None, move |res| match res {
Ok(events) => { Ok(events) => {
for event in events { for event in events {
let _ = tx.send(event); let _ = tx.send(event);
} }
} }
Err(err) => { Err(errs) => {
eprintln!("Error watching for file changes: {err}"); for err in errs {
eprintln!("Error watching for file changes: {err}");
}
} }
})?; })?;
Ok(FileWatcher { Ok(FileWatcher {

File diff suppressed because one or more lines are too long

View File

@@ -2,12 +2,12 @@ use std::sync::{mpsc, Arc, Mutex};
use std::time::Duration; use std::time::Duration;
use std::{thread, time::Instant}; use std::{thread, time::Instant};
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, Result};
use cpal::traits::*; use cpal::traits::*;
use rubato::Resampler; use rubato::Resampler;
use uw8_window::{Window, WindowConfig}; use uw8_window::{Window, WindowConfig};
use wasmtime::{ use wasmtime::{
Engine, Func, GlobalType, Memory, MemoryType, Module, Mutability, Store, TypedFunc, ValType, Engine, GlobalType, Memory, MemoryType, Module, Mutability, Store, TypedFunc, ValType,
}; };
pub struct MicroW8 { pub struct MicroW8 {
@@ -27,7 +27,6 @@ struct UW8Instance {
end_frame: TypedFunc<(), ()>, end_frame: TypedFunc<(), ()>,
update: Option<TypedFunc<(), ()>>, update: Option<TypedFunc<(), ()>>,
start_time: Instant, start_time: Instant,
frame_counter: u32,
watchdog: Arc<Mutex<UW8WatchDog>>, watchdog: Arc<Mutex<UW8WatchDog>>,
sound_tx: Option<mpsc::SyncSender<RegisterUpdate>>, sound_tx: Option<mpsc::SyncSender<RegisterUpdate>>,
} }
@@ -91,7 +90,7 @@ impl super::Runtime for MicroW8 {
let memory = wasmtime::Memory::new(&mut store, MemoryType::new(4, Some(4)))?; let memory = wasmtime::Memory::new(&mut store, MemoryType::new(4, Some(4)))?;
let mut linker = wasmtime::Linker::new(&self.engine); let mut linker = wasmtime::Linker::new(&self.engine);
linker.define(&store, "env", "memory", memory)?; linker.define("env", "memory", memory)?;
let loader_instance = linker.instantiate(&mut store, &self.loader_module)?; let loader_instance = linker.instantiate(&mut store, &self.loader_module)?;
let load_uw8 = loader_instance.get_typed_func::<i32, i32>(&mut store, "load_uw8")?; let load_uw8 = loader_instance.get_typed_func::<i32, i32>(&mut store, "load_uw8")?;
@@ -160,7 +159,6 @@ impl super::Runtime for MicroW8 {
end_frame, end_frame,
update, update,
start_time: Instant::now(), start_time: Instant::now(),
frame_counter: 0,
watchdog, watchdog,
sound_tx, sound_tx,
}); });
@@ -183,21 +181,20 @@ impl super::Runtime for MicroW8 {
if let Some(mut instance) = self.instance.take() { if let Some(mut instance) = self.instance.take() {
let time = (now - instance.start_time).as_millis() as i32; let time = (now - instance.start_time).as_millis() as i32;
let next_frame = { let next_frame = {
let offset = ((time as u32 as i64 * 6) % 100 - 50) / 6; let frame = (time as u32 as u64 * 6 / 100) as u32;
let max = now + Duration::from_millis(17); let cur_offset = (time as u32).wrapping_sub((frame as u64 * 100 / 6) as u32);
let next_center = now + Duration::from_millis((16 - offset) as u64); let next_time =
next_center.min(max) ((frame as u64 + 1) * 100 / 6 + cur_offset.max(1).min(4) as u64) as u32;
let offset = next_time.wrapping_sub(time as u32);
now + Duration::from_millis(offset as u64)
}; };
{ {
let mem = instance.memory.data_mut(&mut instance.store); let mem = instance.memory.data_mut(&mut instance.store);
mem[64..68].copy_from_slice(&time.to_le_bytes()); mem[64..68].copy_from_slice(&time.to_le_bytes());
mem[68..72].copy_from_slice(&input.gamepads); mem[68..72].copy_from_slice(&input.gamepads);
mem[72..76].copy_from_slice(&instance.frame_counter.to_le_bytes());
} }
instance.frame_counter = instance.frame_counter.wrapping_add(1);
instance.store.set_epoch_deadline(self.timeout as u64); instance.store.set_epoch_deadline(self.timeout as u64);
if let Some(ref update) = instance.update { if let Some(ref update) = instance.update {
if let Err(err) = update.call(&mut instance.store, ()) { if let Err(err) = update.call(&mut instance.store, ()) {
@@ -260,12 +257,15 @@ fn add_native_functions(
} }
})?; })?;
for i in 0..16 { for i in 0..16 {
let global = wasmtime::Global::new( linker.define(
&mut *store, "env",
GlobalType::new(ValType::I32, Mutability::Const), &format!("g_reserved{}", i),
0.into(), wasmtime::Global::new(
&mut *store,
GlobalType::new(ValType::I32, Mutability::Const),
0.into(),
)?,
)?; )?;
linker.define(&store, "env", &format!("g_reserved{}", i), global)?;
} }
Ok(()) Ok(())
@@ -278,18 +278,14 @@ fn instantiate_platform(
) -> Result<wasmtime::Instance> { ) -> Result<wasmtime::Instance> {
let platform_instance = linker.instantiate(&mut *store, &platform_module)?; let platform_instance = linker.instantiate(&mut *store, &platform_module)?;
let exports: Vec<(String, Func)> = platform_instance for export in platform_instance.exports(&mut *store) {
.exports(&mut *store) linker.define(
.map(|e| { "env",
( export.name(),
e.name().to_owned(), export
e.into_func() .into_func()
.expect("platform surely only exports functions"), .expect("platform surely only exports functions"),
) )?;
})
.collect();
for (name, func) in exports {
linker.define(&store, "env", &name, func)?;
} }
Ok(platform_instance) Ok(platform_instance)
@@ -316,7 +312,7 @@ fn init_sound(
let memory = wasmtime::Memory::new(&mut store, MemoryType::new(4, Some(4)))?; let memory = wasmtime::Memory::new(&mut store, MemoryType::new(4, Some(4)))?;
let mut linker = wasmtime::Linker::new(engine); let mut linker = wasmtime::Linker::new(engine);
linker.define(&store, "env", "memory", memory)?; linker.define("env", "memory", memory)?;
add_native_functions(&mut linker, &mut store)?; add_native_functions(&mut linker, &mut store)?;
let platform_instance = instantiate_platform(&mut linker, &mut store, platform_module)?; let platform_instance = instantiate_platform(&mut linker, &mut store, platform_module)?;
@@ -333,37 +329,23 @@ fn init_sound(
let mut configs: Vec<_> = device let mut configs: Vec<_> = device
.supported_output_configs()? .supported_output_configs()?
.filter(|config| { .filter(|config| {
config.sample_format() == cpal::SampleFormat::F32 config.channels() == 2 && config.sample_format() == cpal::SampleFormat::F32
|| config.sample_format() == cpal::SampleFormat::I16
}) })
.collect(); .collect();
if configs.is_empty() {
eprintln!(
"No suitable audio output config found on device \"{}\", available configs:",
device.name()?
);
for config in device.supported_output_configs()? {
eprintln!(" {}ch {}", config.channels(), config.sample_format());
}
bail!("Failed to configure audio out");
}
configs.sort_by_key(|config| { configs.sort_by_key(|config| {
let rate = 44100 let rate = 44100
.max(config.min_sample_rate().0) .max(config.min_sample_rate().0)
.min(config.max_sample_rate().0); .min(config.max_sample_rate().0);
let rate_prio = if rate >= 44100 { if rate >= 44100 {
rate - 44100 rate - 44100
} else { } else {
(44100 - rate) * 1000 (44100 - rate) * 1000
}; }
let format_prio = (config.sample_format() == cpal::SampleFormat::I16) as u32;
let channels_prio = (config.channels() != 2) as u32 * 16777216;
rate_prio + format_prio + channels_prio
}); });
let config = configs.into_iter().next().unwrap(); let config = configs
.into_iter()
.next()
.ok_or_else(|| anyhow!("Could not find float output config"))?;
let sample_rate = cpal::SampleRate(44100) let sample_rate = cpal::SampleRate(44100)
.max(config.min_sample_rate()) .max(config.min_sample_rate())
.min(config.max_sample_rate()); .min(config.max_sample_rate());
@@ -374,8 +356,6 @@ fn init_sound(
cpal::BufferSize::Fixed(256.max(min).min(max)) cpal::BufferSize::Fixed(256.max(min).min(max))
} }
}; };
let sample_format = config.sample_format();
let num_channels = config.channels();
let config = cpal::StreamConfig { let config = cpal::StreamConfig {
buffer_size, buffer_size,
..config.config() ..config.config()
@@ -395,8 +375,8 @@ fn init_sound(
None None
} else { } else {
let rs = rubato::FftFixedIn::new(44100, sample_rate, 128, 1, 2)?; let rs = rubato::FftFixedIn::new(44100, sample_rate, 128, 1, 2)?;
let input_buffers = rs.input_buffer_allocate(true); let input_buffers = rs.input_buffer_allocate();
let output_buffers = rs.output_buffer_allocate(true); let output_buffers = rs.output_buffer_allocate();
Some(Resampler { Some(Resampler {
resampler: rs, resampler: rs,
input_buffers, input_buffers,
@@ -408,220 +388,96 @@ fn init_sound(
let mut sample_index = 0; let mut sample_index = 0;
let mut pending_updates: Vec<RegisterUpdate> = Vec::with_capacity(30); let mut pending_updates: Vec<RegisterUpdate> = Vec::with_capacity(30);
let mut current_time = 0; let mut current_time = 0;
let stream = device.build_output_stream(
let mut callback = move |mut outer_buffer: &mut [f32]| { &config,
let mut first_update = true; move |mut outer_buffer: &mut [f32], _| {
while let Ok(update) = rx.try_recv() { let mut first_update = true;
if first_update { while let Ok(update) = rx.try_recv() {
current_time += update.time.wrapping_sub(current_time) / 8; if first_update {
first_update = false; current_time += update.time.wrapping_sub(current_time) / 8;
} first_update = false;
pending_updates.push(update);
}
while !outer_buffer.is_empty() {
store.set_epoch_deadline(30);
while pending_updates
.first()
.into_iter()
.any(|u| u.time.wrapping_sub(current_time) <= 0)
{
let update = pending_updates.remove(0);
memory.write(&mut store, 80, &update.data).unwrap();
}
let duration = if let Some(update) = pending_updates.first() {
((update.time.wrapping_sub(current_time) as usize) * sample_rate + 999) / 1000
} else {
outer_buffer.len()
};
let step_size = (duration.max(64) * 2).min(outer_buffer.len());
let mut buffer = &mut outer_buffer[..step_size];
{
let mem = memory.data_mut(&mut store);
mem[64..68].copy_from_slice(&current_time.to_le_bytes());
}
fn clamp_sample(s: f32) -> f32 {
if s.is_nan() {
0.0
} else {
s.max(-1.0).min(1.0)
} }
pending_updates.push(update);
} }
if let Some(ref mut resampler) = resampler { while !outer_buffer.is_empty() {
while !buffer.is_empty() { store.set_epoch_deadline(30);
let copy_size = resampler.output_buffers[0] while pending_updates
.len() .first()
.saturating_sub(resampler.output_index) .into_iter()
.min(buffer.len() / 2); .any(|u| u.time.wrapping_sub(current_time) <= 0)
if copy_size == 0 { {
resampler.input_buffers[0].clear(); let update = pending_updates.remove(0);
resampler.input_buffers[1].clear(); memory.write(&mut store, 80, &update.data).unwrap();
for _ in 0..resampler.resampler.input_frames_next() { }
resampler.input_buffers[0].push(clamp_sample(
snd.call(&mut store, (sample_index,)).unwrap_or(0.0),
));
resampler.input_buffers[1].push(clamp_sample(
snd.call(&mut store, (sample_index + 1,)).unwrap_or(0.0),
));
sample_index = sample_index.wrapping_add(2);
}
resampler let duration = if let Some(update) = pending_updates.first() {
.resampler ((update.time.wrapping_sub(current_time) as usize) * sample_rate + 999) / 1000
.process_into_buffer( } else {
&resampler.input_buffers, outer_buffer.len()
&mut resampler.output_buffers, };
None, let step_size = (duration.max(64) * 2).min(outer_buffer.len());
)
.unwrap(); let mut buffer = &mut outer_buffer[..step_size];
resampler.output_index = 0;
} else { {
for i in 0..copy_size { let mem = memory.data_mut(&mut store);
buffer[i * 2] = resampler.output_buffers[0][resampler.output_index + i]; mem[64..68].copy_from_slice(&current_time.to_le_bytes());
buffer[i * 2 + 1] = }
resampler.output_buffers[1][resampler.output_index + i];
if let Some(ref mut resampler) = resampler {
while !buffer.is_empty() {
let copy_size = resampler.output_buffers[0]
.len()
.saturating_sub(resampler.output_index)
.min(buffer.len() / 2);
if copy_size == 0 {
resampler.input_buffers[0].clear();
resampler.input_buffers[1].clear();
for _ in 0..resampler.resampler.input_frames_next() {
resampler.input_buffers[0]
.push(snd.call(&mut store, (sample_index,)).unwrap_or(0.0));
resampler.input_buffers[1]
.push(snd.call(&mut store, (sample_index + 1,)).unwrap_or(0.0));
sample_index = sample_index.wrapping_add(2);
}
resampler
.resampler
.process_into_buffer(
&resampler.input_buffers,
&mut resampler.output_buffers,
None,
)
.unwrap();
resampler.output_index = 0;
} else {
for i in 0..copy_size {
buffer[i * 2] =
resampler.output_buffers[0][resampler.output_index + i];
buffer[i * 2 + 1] =
resampler.output_buffers[1][resampler.output_index + i];
}
resampler.output_index += copy_size;
buffer = &mut buffer[copy_size * 2..];
} }
resampler.output_index += copy_size; }
buffer = &mut buffer[copy_size * 2..]; } else {
for v in buffer {
*v = snd.call(&mut store, (sample_index,)).unwrap_or(0.0);
sample_index = sample_index.wrapping_add(1);
} }
} }
} else {
for v in buffer { outer_buffer = &mut outer_buffer[step_size..];
*v = clamp_sample(snd.call(&mut store, (sample_index,)).unwrap_or(0.0)); current_time =
sample_index = sample_index.wrapping_add(1); current_time.wrapping_add((step_size * 500 / sample_rate).max(1) as i32);
}
} }
},
outer_buffer = &mut outer_buffer[step_size..]; move |err| {
current_time = current_time.wrapping_add((step_size * 500 / sample_rate).max(1) as i32); dbg!(err);
} },
}; )?;
fn f32_to_i16<F>(mut buffer: &mut [i16], callback: &mut F)
where
F: FnMut(&mut [f32]),
{
let mut float_buffer = [0f32; 256];
while !buffer.is_empty() {
let step_size = buffer.len().min(float_buffer.len());
let step_buffer = &mut float_buffer[..step_size];
callback(step_buffer);
for (dest, src) in buffer.iter_mut().take(step_size).zip(step_buffer.iter()) {
*dest = (src.max(-1.0).min(1.0) * 32767.0) as i16;
}
buffer = &mut buffer[step_size..];
}
}
fn stereo_to_mono<F>(mut buffer: &mut [f32], callback: &mut F)
where
F: FnMut(&mut [f32]),
{
let mut in_buffer = [0f32; 256];
while !buffer.is_empty() {
let step_size = buffer.len().min(in_buffer.len() / 2);
let step_buffer = &mut in_buffer[..step_size * 2];
callback(step_buffer);
for (index, dest) in buffer.iter_mut().take(step_size).enumerate() {
*dest = (step_buffer[index * 2] + step_buffer[index * 2 + 1]) * 0.5;
}
buffer = &mut buffer[step_size..];
}
}
fn stereo_to_surround<F>(mut buffer: &mut [f32], num_channels: usize, callback: &mut F)
where
F: FnMut(&mut [f32]),
{
let mut in_buffer = [0f32; 256];
buffer.fill(0.);
while !buffer.is_empty() {
let step_size = (buffer.len() / num_channels).min(in_buffer.len() / 2);
let step_buffer = &mut in_buffer[..step_size * 2];
callback(step_buffer);
for index in 0..step_size {
buffer[index * num_channels + 0] = step_buffer[index * 2 + 0];
buffer[index * num_channels + 1] = step_buffer[index * 2 + 1];
}
buffer = &mut buffer[step_size * num_channels..];
}
}
let stream = if sample_format == cpal::SampleFormat::F32 {
if num_channels == 2 {
device.build_output_stream(
&config,
move |buffer: &mut [f32], _| callback(buffer),
move |err| {
dbg!(err);
},
None,
)?
} else if num_channels == 1 {
device.build_output_stream(
&config,
move |buffer: &mut [f32], _| stereo_to_mono(buffer, &mut callback),
move |err| {
dbg!(err);
},
None,
)?
} else {
device.build_output_stream(
&config,
move |buffer: &mut [f32], _| {
stereo_to_surround(buffer, num_channels as usize, &mut callback)
},
move |err| {
dbg!(err);
},
None,
)?
}
} else {
if num_channels == 2 {
device.build_output_stream(
&config,
move |buffer: &mut [i16], _| f32_to_i16(buffer, &mut callback),
move |err| {
dbg!(err);
},
None,
)?
} else if num_channels == 1 {
device.build_output_stream(
&config,
move |buffer: &mut [i16], _| {
f32_to_i16(buffer, &mut |b| stereo_to_mono(b, &mut callback))
},
move |err| {
dbg!(err);
},
None,
)?
} else {
device.build_output_stream(
&config,
move |buffer: &mut [i16], _| {
f32_to_i16(buffer, &mut |b| {
stereo_to_surround(b, num_channels as usize, &mut callback)
})
},
move |err| {
dbg!(err);
},
None,
)?
}
};
Ok(Uw8Sound { stream, tx }) Ok(Uw8Sound { stream, tx })
} }

View File

@@ -1 +0,0 @@
* add support for 16bit sound (not just float)

274
uw8-tool/Cargo.lock generated
View File

@@ -4,27 +4,21 @@ version = 3
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.81" version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.2.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.92" version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
[[package]] [[package]]
name = "cdivsufsort" name = "cdivsufsort"
@@ -37,41 +31,38 @@ dependencies = [
] ]
[[package]] [[package]]
name = "crossbeam-channel" name = "cfg-if"
version = "0.5.12" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [ dependencies = [
"cfg-if",
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.19" version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "gimli"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
dependencies = [ dependencies = [
"fallible-iterator", "cfg-if",
"indexmap 1.9.3", "lazy_static",
"stable_deref_trait", ]
[[package]]
name = "form_urlencoded"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
dependencies = [
"percent-encoding",
] ]
[[package]] [[package]]
@@ -80,12 +71,6 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.3" version = "0.3.3"
@@ -102,25 +87,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]] [[package]]
name = "indexmap" name = "idna"
version = "1.9.3" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
dependencies = [ dependencies = [
"autocfg", "unicode-bidi",
"hashbrown 0.12.3", "unicode-normalization",
] ]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.2.6" version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [ dependencies = [
"equivalent", "autocfg",
"hashbrown 0.14.3", "hashbrown",
] ]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "leb128" name = "leb128"
version = "0.2.5" version = "0.2.5"
@@ -135,36 +126,46 @@ checksum = "478ee9e62aaeaf5b140bd4138753d1f109765488581444218d3ddda43234f3e8"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.21" version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.18" version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
[[package]] [[package]]
name = "pbr" name = "pbr"
version = "1.1.1" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5827dfa0d69b6c92493d6c38e633bbaa5937c153d0d7c28bf12313f8c6d514" checksum = "ff5751d87f7c00ae6403eb1fcbba229b9c76c9a30de8c1cf87182177b168cea2"
dependencies = [ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"libc", "libc",
"time",
"winapi", "winapi",
] ]
[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]] [[package]]
name = "pico-args" name = "pico-args"
version = "0.5.0" version = "0.5.0"
@@ -173,18 +174,18 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.79" version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [ dependencies = [
"unicode-ident", "unicode-xid",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.35" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@@ -198,71 +199,89 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "semver"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.84"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-ident", "unicode-xid",
]
[[package]]
name = "syn"
version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
] ]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.58" version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.58" version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.58", "syn",
] ]
[[package]] [[package]]
name = "unicode-ident" name = "time"
version = "1.0.12" version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "unicode-bidi"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.11.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]] [[package]]
name = "upkr" name = "upkr"
@@ -275,6 +294,17 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "url"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]] [[package]]
name = "uw8-tool" name = "uw8-tool"
version = "0.1.0" version = "0.1.0"
@@ -284,24 +314,22 @@ dependencies = [
"pico-args", "pico-args",
"upkr", "upkr",
"walrus", "walrus",
"wasm-encoder 0.201.0", "wasm-encoder",
"wasmparser 0.201.0", "wasmparser 0.99.0",
] ]
[[package]] [[package]]
name = "walrus" name = "walrus"
version = "0.20.3" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c03529cd0c4400a2449f640d2f27cd1b48c3065226d15e26d98e4429ab0adb7" checksum = "4eb08e48cde54c05f363d984bb54ce374f49e242def9468d2e1b6c2372d291f8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"gimli",
"id-arena", "id-arena",
"leb128", "leb128",
"log", "log",
"walrus-macro", "walrus-macro",
"wasm-encoder 0.29.0", "wasmparser 0.77.0",
"wasmparser 0.80.2",
] ]
[[package]] [[package]]
@@ -313,42 +341,38 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn",
] ]
[[package]] [[package]]
name = "wasm-encoder" name = "wasi"
version = "0.29.0" version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
dependencies = [
"leb128",
]
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.201.0" version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9c7d2731df60006819b013f64ccc2019691deccf6e11a1804bc850cd6748f1a" checksum = "ef126be0e14bdf355ac1a8b41afc89195289e5c7179f80118e3abddb472f0810"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.80.2" version = "0.77.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "449167e2832691a1bff24cde28d2804e90e09586a448c8e76984792c44334a6b" checksum = "b35c86d22e720a07d954ebbed772d01180501afe7d03d464f413bb5f8914a8d6"
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.201.0" version = "0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" checksum = "9ef3b717afc67f848f412d4f02c127dd3e35a0eecd58c684580414df4fde01d3"
dependencies = [ dependencies = [
"bitflags", "indexmap",
"indexmap 2.2.6", "url",
"semver",
] ]
[[package]] [[package]]

View File

@@ -6,10 +6,10 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
wasmparser = "0.201" wasmparser = "0.99"
wasm-encoder = "0.201" wasm-encoder = "0.22"
walrus = { version = "0.20.3", default-features = false } walrus = "0.19"
anyhow = "1" anyhow = "1"
pico-args = "0.5" pico-args = "0.5"
upkr = { git = "https://github.com/exoticorn/upkr.git", rev = "080db40d0088bbee2bdf3c5c75288ac7853d6b7a" } upkr = { git = "https://github.com/exoticorn/upkr.git", rev = "080db40d0088bbee2bdf3c5c75288ac7853d6b7a" }
pbr = "1" pbr = "1"

View File

@@ -37,7 +37,7 @@ impl BaseModule {
let mut types = vec![]; let mut types = vec![];
let mut type_map = HashMap::new(); let mut type_map = HashMap::new();
for num_params in 0..8 { for num_params in 0..6 {
for num_f32 in 0..=num_params { for num_f32 in 0..=num_params {
for &result in &[None, Some(ValType::I32), Some(ValType::F32)] { for &result in &[None, Some(ValType::I32), Some(ValType::F32)] {
let mut params = vec![]; let mut params = vec![];

View File

@@ -1,17 +1,13 @@
use anyhow::Result;
use std::path::Path; use std::path::Path;
use anyhow::Result;
pub fn filter_exports(in_path: &Path, out_path: &Path) -> Result<()> { pub fn filter_exports(in_path: &Path, out_path: &Path) -> Result<()> {
let mut module = walrus::Module::from_file(in_path)?; let mut module = walrus::Module::from_file(in_path)?;
let exports_to_delete: Vec<_> = module let exports_to_delete: Vec<_> = module.exports.iter().filter_map(|export| match export.name.as_str() {
.exports "upd" => None,
.iter() _ => Some(export.id())
.filter_map(|export| match export.name.as_str() { }).collect();
"start" | "upd" | "snd" => None,
_ => Some(export.id()),
})
.collect();
for id in exports_to_delete { for id in exports_to_delete {
module.exports.delete(id); module.exports.delete(id);
@@ -22,4 +18,4 @@ pub fn filter_exports(in_path: &Path, out_path: &Path) -> Result<()> {
module.emit_wasm_file(out_path)?; module.emit_wasm_file(out_path)?;
Ok(()) Ok(())
} }

View File

@@ -143,7 +143,6 @@ fn to_val_type(type_: &wasmparser::ValType) -> Result<ValType> {
I64 => ValType::I64, I64 => ValType::I64,
F32 => ValType::F32, F32 => ValType::F32,
F64 => ValType::F64, F64 => ValType::F64,
V128 => ValType::V128,
_ => bail!("Type {:?} isn't a value type", type_), _ => bail!("Type {:?} isn't a value type", type_),
}) })
} }
@@ -491,6 +490,7 @@ impl<'a> ParsedModule<'a> {
element_section.active( element_section.active(
None, None,
&wasm_encoder::ConstExpr::i32_const(element.start_index as i32), &wasm_encoder::ConstExpr::i32_const(element.start_index as i32),
ValType::FuncRef,
wasm_encoder::Elements::Functions(&functions), wasm_encoder::Elements::Functions(&functions),
); );
} }
@@ -536,18 +536,15 @@ fn copy_section(module: &mut wasm_encoder::Module, data: &[u8]) -> Result<()> {
fn read_type_section(reader: TypeSectionReader) -> Result<Vec<base_module::FunctionType>> { fn read_type_section(reader: TypeSectionReader) -> Result<Vec<base_module::FunctionType>> {
let mut function_types = vec![]; let mut function_types = vec![];
for rec_group in reader { for type_def in reader {
for sub_type in rec_group?.into_types() { match type_def? {
match sub_type.composite_type { wasmparser::Type::Func(fnc) => {
wasmparser::CompositeType::Func(fnc) => { if fnc.results().len() > 1 {
if fnc.results().len() > 1 { bail!("Multi-value not supported");
bail!("Multi-value not supported");
}
let params = to_val_type_vec(fnc.params())?;
let result = to_val_type_vec(fnc.results())?.into_iter().next();
function_types.push(FunctionType { params, result });
} }
_ => bail!("Only function types are supported"), let params = to_val_type_vec(fnc.params())?;
let result = to_val_type_vec(fnc.results())?.into_iter().next();
function_types.push(FunctionType { params, result });
} }
} }
} }
@@ -560,8 +557,8 @@ fn validate_table_section(reader: TableSectionReader) -> Result<()> {
bail!("Only up to one table supported"); bail!("Only up to one table supported");
} }
let table = reader.into_iter().next().unwrap()?; let type_ = reader.into_iter().next().unwrap()?;
if !table.ty.element_type.is_func_ref() { if type_.element_type != wasmparser::ValType::FuncRef {
bail!("Only one funcref table is supported"); bail!("Only one funcref table is supported");
} }
@@ -650,12 +647,9 @@ impl Element {
wasmparser::ElementItems::Functions(funcs_reader) => { wasmparser::ElementItems::Functions(funcs_reader) => {
let start_index = if let wasmparser::ElementKind::Active { let start_index = if let wasmparser::ElementKind::Active {
offset_expr, offset_expr,
table_index, table_index: 0,
} = element.kind } = element.kind
{ {
if table_index.map(|i| i > 0).unwrap_or(false) {
bail!("Only function table with index 0 is supported");
}
let mut init_reader = offset_expr.get_operators_reader(); let mut init_reader = offset_expr.get_operators_reader();
if let wasmparser::Operator::I32Const { value: start_index } = if let wasmparser::Operator::I32Const { value: start_index } =
init_reader.read()? init_reader.read()?
@@ -973,244 +967,6 @@ fn remap_function(
De::I64TruncSatF64U => En::I64TruncSatF64U, De::I64TruncSatF64U => En::I64TruncSatF64U,
De::MemoryCopy { src_mem, dst_mem } => En::MemoryCopy { src_mem, dst_mem }, De::MemoryCopy { src_mem, dst_mem } => En::MemoryCopy { src_mem, dst_mem },
De::MemoryFill { mem } => En::MemoryFill(mem), De::MemoryFill { mem } => En::MemoryFill(mem),
De::V128Const { value } => En::V128Const(value.i128()),
De::V128Load { memarg } => En::V128Load(mem(memarg)),
De::V128Store { memarg } => En::V128Store(mem(memarg)),
De::V128Load8x8S { memarg } => En::V128Load8x8S(mem(memarg)),
De::V128Load8x8U { memarg } => En::V128Load8x8U(mem(memarg)),
De::V128Load16x4S { memarg } => En::V128Load16x4S(mem(memarg)),
De::V128Load16x4U { memarg } => En::V128Load16x4U(mem(memarg)),
De::V128Load32x2S { memarg } => En::V128Load32x2S(mem(memarg)),
De::V128Load32x2U { memarg } => En::V128Load32x2U(mem(memarg)),
De::V128Load8Splat { memarg } => En::V128Load8Splat(mem(memarg)),
De::V128Load16Splat { memarg } => En::V128Load16Splat(mem(memarg)),
De::V128Load32Splat { memarg } => En::V128Load32Splat(mem(memarg)),
De::V128Load64Splat { memarg } => En::V128Load64Splat(mem(memarg)),
De::V128Load32Zero { memarg } => En::V128Load32Zero(mem(memarg)),
De::V128Load64Zero { memarg } => En::V128Load64Zero(mem(memarg)),
De::V128Load8Lane { memarg, lane } => En::V128Load8Lane { memarg: mem(memarg), lane },
De::V128Load16Lane { memarg, lane } => En::V128Load16Lane { memarg: mem(memarg), lane },
De::V128Load32Lane { memarg, lane } => En::V128Load32Lane { memarg: mem(memarg), lane },
De::V128Load64Lane { memarg, lane } => En::V128Load64Lane { memarg: mem(memarg), lane },
De::V128Store8Lane { memarg, lane } => En::V128Store8Lane { memarg: mem(memarg), lane },
De::V128Store16Lane { memarg, lane } => En::V128Store16Lane { memarg: mem(memarg), lane },
De::V128Store32Lane { memarg, lane } => En::V128Store32Lane { memarg: mem(memarg), lane },
De::V128Store64Lane { memarg, lane } => En::V128Store64Lane { memarg: mem(memarg), lane },
De::I8x16ExtractLaneS { lane } => En::I8x16ExtractLaneS(lane),
De::I8x16ExtractLaneU { lane } => En::I8x16ExtractLaneU(lane),
De::I8x16ReplaceLane { lane } => En::I8x16ReplaceLane(lane),
De::I16x8ExtractLaneS { lane } => En::I16x8ExtractLaneS(lane),
De::I16x8ExtractLaneU { lane } => En::I16x8ExtractLaneU(lane),
De::I16x8ReplaceLane { lane } => En::I16x8ReplaceLane(lane),
De::I32x4ExtractLane { lane } => En::I32x4ExtractLane(lane),
De::I32x4ReplaceLane { lane } => En::I32x4ReplaceLane(lane),
De::I64x2ExtractLane { lane } => En::I64x2ExtractLane(lane),
De::I64x2ReplaceLane { lane } => En::I64x2ReplaceLane(lane),
De::F32x4ExtractLane { lane } => En::F32x4ExtractLane(lane),
De::F32x4ReplaceLane { lane } => En::F32x4ReplaceLane(lane),
De::F64x2ExtractLane { lane } => En::F64x2ExtractLane(lane),
De::F64x2ReplaceLane { lane } => En::F64x2ReplaceLane(lane),
De::I8x16Splat => En::I8x16Splat,
De::I16x8Splat => En::I16x8Splat,
De::I32x4Splat => En::I32x4Splat,
De::I64x2Splat => En::I64x2Splat,
De::F32x4Splat => En::F32x4Splat,
De::F64x2Splat => En::F64x2Splat,
De::I8x16Swizzle => En::I8x16Swizzle,
De::I8x16Add => En::I8x16Add,
De::I16x8Add => En::I16x8Add,
De::I32x4Add => En::I32x4Add,
De::I64x2Add => En::I64x2Add,
De::F32x4Add => En::F32x4Add,
De::F64x2Add => En::F64x2Add,
De::I8x16Sub => En::I8x16Sub,
De::I16x8Sub => En::I16x8Sub,
De::I32x4Sub => En::I32x4Sub,
De::I64x2Sub => En::I64x2Sub,
De::F32x4Sub => En::F32x4Sub,
De::F64x2Sub => En::F64x2Sub,
De::I16x8Mul => En::I16x8Mul,
De::I32x4Mul => En::I32x4Mul,
De::I64x2Mul => En::I64x2Mul,
De::F32x4Mul => En::F32x4Mul,
De::F64x2Mul => En::F64x2Mul,
De::I32x4DotI16x8S => En::I32x4DotI16x8S,
De::I8x16Neg => En::I8x16Neg,
De::I16x8Neg => En::I16x8Neg,
De::I32x4Neg => En::I32x4Neg,
De::I64x2Neg => En::I64x2Neg,
De::F32x4Neg => En::F32x4Neg,
De::F64x2Neg => En::F64x2Neg,
De::I16x8ExtMulLowI8x16S => En::I16x8ExtMulLowI8x16S,
De::I16x8ExtMulHighI8x16S => En::I16x8ExtMulHighI8x16S,
De::I16x8ExtMulLowI8x16U => En::I16x8ExtMulLowI8x16U,
De::I16x8ExtMulHighI8x16U => En::I16x8ExtMulHighI8x16U,
De::I32x4ExtMulLowI16x8S => En::I32x4ExtMulLowI16x8S,
De::I32x4ExtMulHighI16x8S => En::I32x4ExtMulHighI16x8S,
De::I32x4ExtMulLowI16x8U => En::I32x4ExtMulLowI16x8U,
De::I32x4ExtMulHighI16x8U => En::I32x4ExtMulHighI16x8U,
De::I64x2ExtMulLowI32x4S => En::I64x2ExtMulLowI32x4S,
De::I64x2ExtMulHighI32x4S => En::I64x2ExtMulHighI32x4S,
De::I64x2ExtMulLowI32x4U => En::I64x2ExtMulLowI32x4U,
De::I64x2ExtMulHighI32x4U => En::I64x2ExtMulHighI32x4U,
De::I16x8ExtAddPairwiseI8x16S => En::I16x8ExtAddPairwiseI8x16S,
De::I16x8ExtAddPairwiseI8x16U => En::I16x8ExtAddPairwiseI8x16U,
De::I32x4ExtAddPairwiseI16x8S => En::I32x4ExtAddPairwiseI16x8S,
De::I32x4ExtAddPairwiseI16x8U => En::I32x4ExtAddPairwiseI16x8U,
De::I8x16AddSatS => En::I8x16AddSatS,
De::I8x16AddSatU => En::I8x16AddSatU,
De::I16x8AddSatS => En::I16x8AddSatS,
De::I16x8AddSatU => En::I16x8AddSatU,
De::I8x16SubSatS => En::I8x16SubSatS,
De::I8x16SubSatU => En::I8x16SubSatU,
De::I16x8SubSatS => En::I16x8SubSatS,
De::I16x8SubSatU => En::I16x8SubSatU,
De::I16x8Q15MulrSatS => En::I16x8Q15MulrSatS,
De::I8x16MinS => En::I8x16MinS,
De::I8x16MinU => En::I8x16MinU,
De::I16x8MinS => En::I16x8MinS,
De::I16x8MinU => En::I16x8MinU,
De::I32x4MinS => En::I32x4MinS,
De::I32x4MinU => En::I32x4MinU,
De::F32x4Min => En::F32x4Min,
De::F64x2Min => En::F64x2Min,
De::F32x4PMin => En::F32x4PMin,
De::F64x2PMin => En::F64x2PMin,
De::I8x16MaxS => En::I8x16MaxS,
De::I8x16MaxU => En::I8x16MaxU,
De::I16x8MaxS => En::I16x8MaxS,
De::I16x8MaxU => En::I16x8MaxU,
De::I32x4MaxS => En::I32x4MaxS,
De::I32x4MaxU => En::I32x4MaxU,
De::F32x4Max => En::F32x4Max,
De::F64x2Max => En::F64x2Max,
De::F32x4PMax => En::F32x4PMax,
De::F64x2PMax => En::F64x2PMax,
De::I8x16AvgrU => En::I8x16AvgrU,
De::I16x8AvgrU => En::I16x8AvgrU,
De::I8x16Abs => En::I8x16Abs,
De::I16x8Abs => En::I16x8Abs,
De::I32x4Abs => En::I32x4Abs,
De::I64x2Abs => En::I64x2Abs,
De::F32x4Abs => En::F32x4Abs,
De::F64x2Abs => En::F64x2Abs,
De::I8x16Shl => En::I8x16Shl,
De::I16x8Shl => En::I16x8Shl,
De::I32x4Shl => En::I32x4Shl,
De::I64x2Shl => En::I64x2Shl,
De::I8x16ShrS => En::I8x16ShrS,
De::I8x16ShrU => En::I8x16ShrU,
De::I16x8ShrS => En::I16x8ShrS,
De::I16x8ShrU => En::I16x8ShrU,
De::I32x4ShrS => En::I32x4ShrS,
De::I32x4ShrU => En::I32x4ShrU,
De::I64x2ShrS => En::I64x2ShrS,
De::I64x2ShrU => En::I64x2ShrU,
De::V128And => En::V128And,
De::V128Or => En::V128Or,
De::V128Xor => En::V128Xor,
De::V128Not => En::V128Not,
De::V128AndNot => En::V128AndNot,
De::V128Bitselect => En::V128Bitselect,
De::I8x16Popcnt => En::I8x16Popcnt,
De::V128AnyTrue => En::V128AnyTrue,
De::I8x16AllTrue => En::I8x16AllTrue,
De::I16x8AllTrue => En::I16x8AllTrue,
De::I32x4AllTrue => En::I32x4AllTrue,
De::I64x2AllTrue => En::I64x2AllTrue,
De::I8x16Bitmask => En::I8x16Bitmask,
De::I16x8Bitmask => En::I16x8Bitmask,
De::I32x4Bitmask => En::I32x4Bitmask,
De::I64x2Bitmask => En::I64x2Bitmask,
De::I8x16Eq => En::I8x16Eq,
De::I16x8Eq => En::I16x8Eq,
De::I32x4Eq => En::I32x4Eq,
De::I64x2Eq => En::I64x2Eq,
De::F32x4Eq => En::F32x4Eq,
De::F64x2Eq => En::F64x2Eq,
De::I8x16Ne => En::I8x16Ne,
De::I16x8Ne => En::I16x8Ne,
De::I32x4Ne => En::I32x4Ne,
De::I64x2Ne => En::I64x2Ne,
De::F32x4Ne => En::F32x4Ne,
De::F64x2Ne => En::F64x2Ne,
De::I8x16LtS => En::I8x16LtS,
De::I8x16LtU => En::I8x16LtU,
De::I16x8LtS => En::I16x8LtS,
De::I16x8LtU => En::I16x8LtU,
De::I32x4LtS => En::I32x4LtS,
De::I32x4LtU => En::I32x4LtU,
De::F32x4Lt => En::F32x4Lt,
De::F64x2Lt => En::F64x2Lt,
De::I8x16LeS => En::I8x16LeS,
De::I8x16LeU => En::I8x16LeU,
De::I16x8LeS => En::I16x8LeS,
De::I16x8LeU => En::I16x8LeU,
De::I32x4LeS => En::I32x4LeS,
De::I32x4LeU => En::I32x4LeU,
De::F32x4Le => En::F32x4Le,
De::F64x2Le => En::F64x2Le,
De::I8x16GtS => En::I8x16GtS,
De::I8x16GtU => En::I8x16GtU,
De::I16x8GtS => En::I16x8GtS,
De::I16x8GtU => En::I16x8GtU,
De::I32x4GtS => En::I32x4GtS,
De::I32x4GtU => En::I32x4GtU,
De::F32x4Gt => En::F32x4Gt,
De::F64x2Gt => En::F64x2Gt,
De::I8x16GeS => En::I8x16GeS,
De::I8x16GeU => En::I8x16GeU,
De::I16x8GeS => En::I16x8GeS,
De::I16x8GeU => En::I16x8GeU,
De::I32x4GeS => En::I32x4GeS,
De::I32x4GeU => En::I32x4GeU,
De::F32x4Ge => En::F32x4Ge,
De::F64x2Ge => En::F64x2Ge,
De::F32x4Div => En::F32x4Div,
De::F64x2Div => En::F64x2Div,
De::F32x4Sqrt => En::F32x4Sqrt,
De::F64x2Sqrt => En::F64x2Sqrt,
De::F32x4Ceil => En::F32x4Ceil,
De::F64x2Ceil => En::F64x2Ceil,
De::F32x4Floor => En::F32x4Floor,
De::F64x2Floor => En::F64x2Floor,
De::F32x4Trunc => En::F32x4Trunc,
De::F64x2Trunc => En::F64x2Trunc,
De::F32x4Nearest => En::F32x4Nearest,
De::F64x2Nearest => En::F64x2Nearest,
De::F32x4ConvertI32x4S => En::F32x4ConvertI32x4S,
De::F32x4ConvertI32x4U => En::F32x4ConvertI32x4U,
De::F64x2ConvertLowI32x4S => En::F64x2ConvertLowI32x4S,
De::F64x2ConvertLowI32x4U => En::F64x2ConvertLowI32x4U,
De::I32x4TruncSatF32x4S => En::I32x4TruncSatF32x4S,
De::I32x4TruncSatF32x4U => En::I32x4TruncSatF32x4U,
De::I32x4TruncSatF64x2SZero => En::I32x4TruncSatF64x2SZero,
De::I32x4TruncSatF64x2UZero => En::I32x4TruncSatF64x2UZero,
De::F32x4DemoteF64x2Zero => En::F32x4DemoteF64x2Zero,
De::F64x2PromoteLowF32x4 => En::F64x2PromoteLowF32x4,
De::I8x16NarrowI16x8S => En::I8x16NarrowI16x8S,
De::I8x16NarrowI16x8U => En::I8x16NarrowI16x8U,
De::I16x8NarrowI32x4S => En::I16x8NarrowI32x4S,
De::I16x8NarrowI32x4U => En::I16x8NarrowI32x4U,
De::I16x8ExtendLowI8x16S => En::I16x8ExtendLowI8x16S,
De::I16x8ExtendHighI8x16S => En::I16x8ExtendHighI8x16S,
De::I16x8ExtendLowI8x16U => En::I16x8ExtendLowI8x16U,
De::I16x8ExtendHighI8x16U => En::I16x8ExtendHighI8x16U,
De::I32x4ExtendLowI16x8S => En::I32x4ExtendLowI16x8S,
De::I32x4ExtendHighI16x8S => En::I32x4ExtendHighI16x8S,
De::I32x4ExtendLowI16x8U => En::I32x4ExtendLowI16x8U,
De::I32x4ExtendHighI16x8U => En::I32x4ExtendHighI16x8U,
De::I64x2ExtendLowI32x4S => En::I64x2ExtendLowI32x4S,
De::I64x2ExtendHighI32x4S => En::I64x2ExtendHighI32x4S,
De::I64x2ExtendLowI32x4U => En::I64x2ExtendLowI32x4U,
De::I64x2ExtendHighI32x4U => En::I64x2ExtendHighI32x4U,
De::I8x16Shuffle { lanes } => En::I8x16Shuffle(lanes),
other => bail!("Unsupported instruction {:?}", other), other => bail!("Unsupported instruction {:?}", other),
}); });
} }

2005
uw8-window/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,13 +6,13 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
winit = "0.29.15" winit = "0.27.5"
env_logger = "0.11.3" env_logger = "0.10"
log = "0.4" log = "0.4"
pico-args = "0.5" pico-args = "0.5"
wgpu = "0.19.3" wgpu = "0.15"
pollster = "0.3.0" pollster = "0.2.5"
bytemuck = { version = "1.15", features = [ "derive" ] } bytemuck = { version = "1.13", features = [ "derive" ] }
anyhow = "1" anyhow = "1"
minifb = { version = "0.25.0", default-features = false, features = ["x11"] } minifb = { version = "0.23.0", default-features = false, features = ["x11"] }
winapi = { version = "0.3.9", features = [ "timeapi" ] } winapi = { version = "0.3.9", features = [ "timeapi" ] }

View File

@@ -30,8 +30,8 @@ fn row_factor(offset: f32) -> f32 {
} }
fn col_factor(offset: f32) -> f32 { fn col_factor(offset: f32) -> f32 {
let o = max(0.0, abs(offset) - 0.4); let offset = max(0.0, abs(offset) - 0.4);
return 1.0 / (1.0 + o * o * 16.0); return 1.0 / (1.0 + offset * offset * 16.0);
} }
fn sample_screen(tex_coords: vec2<f32>) -> vec4<f32> { fn sample_screen(tex_coords: vec2<f32>) -> vec4<f32> {

View File

@@ -1,16 +1,16 @@
use crate::{Input, WindowConfig, WindowImpl}; use crate::{Input, WindowConfig, WindowImpl};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use std::{sync::Arc, time::Instant}; use std::{num::NonZeroU32, time::Instant};
use winit::{ use winit::{
dpi::PhysicalSize, dpi::PhysicalSize,
event::{Event, WindowEvent}, event::{Event, VirtualKeyCode, WindowEvent},
event_loop::{ControlFlow, EventLoop}, event_loop::{ControlFlow, EventLoop},
keyboard::{Key, KeyCode, NamedKey, PhysicalKey},
platform::pump_events::{EventLoopExtPumpEvents, PumpStatus},
window::{Fullscreen, WindowBuilder}, window::{Fullscreen, WindowBuilder},
}; };
use winit::platform::run_return::EventLoopExtRunReturn;
mod crt; mod crt;
mod fast_crt; mod fast_crt;
mod square; mod square;
@@ -21,7 +21,7 @@ use square::SquareFilter;
pub struct Window { pub struct Window {
_instance: wgpu::Instance, _instance: wgpu::Instance,
surface: wgpu::Surface<'static>, surface: wgpu::Surface,
_adapter: wgpu::Adapter, _adapter: wgpu::Adapter,
device: wgpu::Device, device: wgpu::Device,
queue: wgpu::Queue, queue: wgpu::Queue,
@@ -29,7 +29,7 @@ pub struct Window {
surface_config: wgpu::SurfaceConfiguration, surface_config: wgpu::SurfaceConfiguration,
filter: Box<dyn Filter>, filter: Box<dyn Filter>,
event_loop: EventLoop<()>, event_loop: EventLoop<()>,
window: Arc<winit::window::Window>, window: winit::window::Window,
gamepads: [u8; 4], gamepads: [u8; 4],
next_frame: Instant, next_frame: Instant,
is_fullscreen: bool, is_fullscreen: bool,
@@ -39,12 +39,9 @@ pub struct Window {
impl Window { impl Window {
pub fn new(window_config: WindowConfig) -> Result<Window> { pub fn new(window_config: WindowConfig) -> Result<Window> {
async fn create(window_config: WindowConfig) -> Result<Window> { async fn create(window_config: WindowConfig) -> Result<Window> {
let event_loop = EventLoop::new()?; let event_loop = EventLoop::new();
let window = WindowBuilder::new() let window = WindowBuilder::new()
.with_inner_size(PhysicalSize::new( .with_inner_size(PhysicalSize::new(640u32, 480))
(320. * window_config.scale).round() as u32,
(240. * window_config.scale).round() as u32,
))
.with_min_inner_size(PhysicalSize::new(320u32, 240)) .with_min_inner_size(PhysicalSize::new(320u32, 240))
.with_title("MicroW8") .with_title("MicroW8")
.with_fullscreen(if window_config.fullscreen { .with_fullscreen(if window_config.fullscreen {
@@ -56,10 +53,8 @@ impl Window {
window.set_cursor_visible(false); window.set_cursor_visible(false);
let window = Arc::new(window);
let instance = wgpu::Instance::new(Default::default()); let instance = wgpu::Instance::new(Default::default());
let surface = instance.create_surface(window.clone())?; let surface = unsafe { instance.create_surface(&window) }?;
let adapter = instance let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions { .request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::LowPower, power_preference: wgpu::PowerPreference::LowPower,
@@ -77,13 +72,7 @@ impl Window {
let surface_config = wgpu::SurfaceConfiguration { let surface_config = wgpu::SurfaceConfiguration {
present_mode: wgpu::PresentMode::AutoNoVsync, present_mode: wgpu::PresentMode::AutoNoVsync,
..surface ..surface.get_default_config(&adapter, window.inner_size().width, window.inner_size().height).expect("Surface incompatible with adapter")
.get_default_config(
&adapter,
window.inner_size().width,
window.inner_size().height,
)
.expect("Surface incompatible with adapter")
}; };
let filter: Box<dyn Filter> = create_filter( let filter: Box<dyn Filter> = create_filter(
@@ -121,93 +110,88 @@ impl Window {
impl WindowImpl for Window { impl WindowImpl for Window {
fn begin_frame(&mut self) -> Input { fn begin_frame(&mut self) -> Input {
let mut reset = false; let mut reset = false;
self.event_loop self.event_loop.run_return(|event, _, control_flow| {
.set_control_flow(ControlFlow::WaitUntil(self.next_frame)); *control_flow = ControlFlow::WaitUntil(self.next_frame);
while self.is_open { let mut new_filter = None;
let timeout = self.next_frame.saturating_duration_since(Instant::now()); match event {
let status = self.event_loop.pump_events(Some(timeout), |event, elwt| { Event::WindowEvent { event, .. } => match event {
let mut new_filter = None; WindowEvent::Resized(new_size) => {
match event { self.surface_config.width = new_size.width;
Event::WindowEvent { event, .. } => match event { self.surface_config.height = new_size.height;
WindowEvent::Resized(new_size) => { self.surface.configure(&self.device, &self.surface_config);
self.surface_config.width = new_size.width; self.filter.resize(&self.queue, new_size);
self.surface_config.height = new_size.height; }
self.surface.configure(&self.device, &self.surface_config); WindowEvent::CloseRequested => {
self.filter.resize(&self.queue, new_size); self.is_open = false;
} *control_flow = ControlFlow::Exit;
WindowEvent::CloseRequested => { }
elwt.exit(); WindowEvent::KeyboardInput { input, .. } => {
} fn gamepad_button(input: &winit::event::KeyboardInput) -> u8 {
WindowEvent::KeyboardInput { event, .. } => { match input.scancode {
fn gamepad_button(input: &winit::event::KeyEvent) -> u8 { 44 => 16,
match input.physical_key { 45 => 32,
PhysicalKey::Code(KeyCode::KeyZ) => 16, 30 => 64,
PhysicalKey::Code(KeyCode::KeyX) => 32, 31 => 128,
PhysicalKey::Code(KeyCode::KeyA) => 64, _ => match input.virtual_keycode {
PhysicalKey::Code(KeyCode::KeyS) => 128, Some(VirtualKeyCode::Up) => 1,
_ => match input.logical_key { Some(VirtualKeyCode::Down) => 2,
Key::Named(NamedKey::ArrowUp) => 1, Some(VirtualKeyCode::Left) => 4,
Key::Named(NamedKey::ArrowDown) => 2, Some(VirtualKeyCode::Right) => 8,
Key::Named(NamedKey::ArrowLeft) => 4, _ => 0,
Key::Named(NamedKey::ArrowRight) => 8, },
_ => 0,
},
}
} }
if event.state == winit::event::ElementState::Pressed { }
match event.logical_key { if input.state == winit::event::ElementState::Pressed {
Key::Named(NamedKey::Escape) => { match input.virtual_keycode {
elwt.exit(); Some(VirtualKeyCode::Escape) => {
} self.is_open = false;
Key::Character(ref c) => match c.as_str() { *control_flow = ControlFlow::Exit;
"f" => {
let fullscreen = if self.window.fullscreen().is_some() {
None
} else {
Some(Fullscreen::Borderless(None))
};
self.is_fullscreen = fullscreen.is_some();
self.window.set_fullscreen(fullscreen);
}
"r" => reset = true,
"1" => new_filter = Some(1),
"2" => new_filter = Some(2),
"3" => new_filter = Some(3),
"4" => new_filter = Some(4),
"5" => new_filter = Some(5),
_ => (),
},
_ => (),
} }
Some(VirtualKeyCode::F) => {
let fullscreen = if self.window.fullscreen().is_some() {
None
} else {
Some(Fullscreen::Borderless(None))
};
self.is_fullscreen = fullscreen.is_some();
self.window.set_fullscreen(fullscreen);
}
Some(VirtualKeyCode::R) => reset = true,
Some(VirtualKeyCode::Key1) => new_filter = Some(1),
Some(VirtualKeyCode::Key2) => new_filter = Some(2),
Some(VirtualKeyCode::Key3) => new_filter = Some(3),
Some(VirtualKeyCode::Key4) => new_filter = Some(4),
Some(VirtualKeyCode::Key5) => new_filter = Some(5),
_ => (),
}
self.gamepads[0] |= gamepad_button(&event); self.gamepads[0] |= gamepad_button(&input);
} else { } else {
self.gamepads[0] &= !gamepad_button(&event); self.gamepads[0] &= !gamepad_button(&input);
}
} }
_ => (), }
},
_ => (), _ => (),
},
Event::RedrawEventsCleared => {
if Instant::now() >= self.next_frame
// workaround needed on Wayland until the next winit release
&& self.window.fullscreen().is_some() == self.is_fullscreen
{
*control_flow = ControlFlow::Exit
}
} }
if let Some(new_filter) = new_filter {
self.filter = create_filter(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
new_filter,
);
}
});
match status {
PumpStatus::Exit(_) => self.is_open = false,
_ => (), _ => (),
} }
if let Some(new_filter) = new_filter {
if Instant::now() >= self.next_frame { self.filter = create_filter(
break; &self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
new_filter,
);
} }
} });
Input { Input {
gamepads: self.gamepads, gamepads: self.gamepads,
reset, reset,
@@ -243,12 +227,10 @@ impl WindowImpl for Window {
b: 0.0, b: 0.0,
a: 1.0, a: 1.0,
}), }),
store: wgpu::StoreOp::Store, store: true,
}, },
})], })],
depth_stencil_attachment: None, depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
}); });
self.filter.render(&mut render_pass); self.filter.render(&mut render_pass);
@@ -372,7 +354,7 @@ impl PaletteScreenMode {
format: wgpu::TextureFormat::R8Uint, format: wgpu::TextureFormat::R8Uint,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
label: None, label: None,
view_formats: &[], view_formats: &[]
}); });
let palette_texture = device.create_texture(&wgpu::TextureDescriptor { let palette_texture = device.create_texture(&wgpu::TextureDescriptor {
@@ -387,7 +369,7 @@ impl PaletteScreenMode {
format: wgpu::TextureFormat::Rgba8UnormSrgb, format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
label: None, label: None,
view_formats: &[], view_formats: &[]
}); });
let screen_texture = device.create_texture(&wgpu::TextureDescriptor { let screen_texture = device.create_texture(&wgpu::TextureDescriptor {
@@ -402,7 +384,7 @@ impl PaletteScreenMode {
format: wgpu::TextureFormat::Rgba8UnormSrgb, format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT, usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
label: None, label: None,
view_formats: &[], view_formats: &[]
}); });
let framebuffer_texture_view = let framebuffer_texture_view =
@@ -509,7 +491,7 @@ impl PaletteScreenMode {
&bytemuck::cast_slice(pixels), &bytemuck::cast_slice(pixels),
wgpu::ImageDataLayout { wgpu::ImageDataLayout {
offset: 0, offset: 0,
bytes_per_row: Some(320), bytes_per_row: NonZeroU32::new(320),
rows_per_image: None, rows_per_image: None,
}, },
wgpu::Extent3d { wgpu::Extent3d {
@@ -531,7 +513,7 @@ impl PaletteScreenMode {
&bytemuck::cast_slice(palette), &bytemuck::cast_slice(palette),
wgpu::ImageDataLayout { wgpu::ImageDataLayout {
offset: 0, offset: 0,
bytes_per_row: Some(256 * 4), bytes_per_row: NonZeroU32::new(256 * 4),
rows_per_image: None, rows_per_image: None,
}, },
wgpu::Extent3d { wgpu::Extent3d {
@@ -550,12 +532,10 @@ impl PaletteScreenMode {
resolve_target: None, resolve_target: None,
ops: wgpu::Operations { ops: wgpu::Operations {
load: wgpu::LoadOp::Load, load: wgpu::LoadOp::Load,
store: wgpu::StoreOp::Store, store: true,
}, },
})], })],
depth_stencil_attachment: None, depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
}); });
render_pass.set_pipeline(&self.pipeline); render_pass.set_pipeline(&self.pipeline);

View File

@@ -15,7 +15,7 @@ struct FpsCounter {
} }
impl Window { impl Window {
pub fn new(mut config: WindowConfig) -> Result<Window> { pub fn new(config: WindowConfig) -> Result<Window> {
let fps_counter = if config.fps_counter { let fps_counter = if config.fps_counter {
Some(FpsCounter { Some(FpsCounter {
start: Instant::now(), start: Instant::now(),
@@ -24,7 +24,6 @@ impl Window {
} else { } else {
None None
}; };
config.scale = config.scale.max(1.).min(20.);
if config.enable_gpu { if config.enable_gpu {
match gpu::Window::new(config) { match gpu::Window::new(config) {
Ok(window) => { Ok(window) => {
@@ -72,7 +71,6 @@ pub struct WindowConfig {
filter: u32, filter: u32,
fullscreen: bool, fullscreen: bool,
fps_counter: bool, fps_counter: bool,
scale: f32,
} }
impl Default for WindowConfig { impl Default for WindowConfig {
@@ -82,7 +80,6 @@ impl Default for WindowConfig {
filter: 5, filter: 5,
fullscreen: false, fullscreen: false,
fps_counter: false, fps_counter: false,
scale: 2.,
} }
} }
} }
@@ -105,10 +102,6 @@ impl WindowConfig {
} }
self.fullscreen = args.contains("--fullscreen"); self.fullscreen = args.contains("--fullscreen");
self.fps_counter = args.contains("--fps"); self.fps_counter = args.contains("--fps");
self.scale = args
.opt_value_from_str("--scale")
.unwrap()
.unwrap_or(self.scale);
} }
} }

View File

@@ -4,6 +4,5 @@
"@parcel/optimizer-data-url": "^2.0.0", "@parcel/optimizer-data-url": "^2.0.0",
"@parcel/transformer-inline-string": "^2.0.0", "@parcel/transformer-inline-string": "^2.0.0",
"parcel": "^2.0.0" "parcel": "^2.0.0"
}, }
"dependencies": {}
} }

View File

@@ -10,7 +10,7 @@
</head> </head>
<body> <body>
<div id="uw8"> <div id="uw8">
<a href="https://exoticorn.github.io/microw8">MicroW8</a> 0.4.0 <a href="https://exoticorn.github.io/microw8">MicroW8</a> 0.2.2
</div> </div>
<div id="centered"> <div id="centered">
<canvas class="screen" id="screen" width="320" height="240"> <canvas class="screen" id="screen" width="320" height="240">
@@ -27,4 +27,4 @@
<script type="module"> <script type="module">
import "./main.js"; import "./main.js";
</script> </script>
</html> </html>

View File

@@ -240,7 +240,6 @@ export default function MicroW8(screen, config = {}) {
await audioReadyPromise; await audioReadyPromise;
let startTime = Date.now(); let startTime = Date.now();
let frameCounter = 0;
const timePerFrame = 1000 / 60; const timePerFrame = 1000 / 60;
@@ -275,7 +274,7 @@ export default function MicroW8(screen, config = {}) {
try { try {
let restart = false; let restart = false;
let thisFrame; let nextFrame = 0;
if (!isPaused) { if (!isPaused) {
let gamepads = navigator.getGamepads(); let gamepads = navigator.getGamepads();
let gamepad = 0; let gamepad = 0;
@@ -307,7 +306,6 @@ export default function MicroW8(screen, config = {}) {
let time = Date.now() - startTime; let time = Date.now() - startTime;
u32Mem[16] = time; u32Mem[16] = time;
u32Mem[17] = pad | gamepad; u32Mem[17] = pad | gamepad;
u32Mem[18] = frameCounter++;
if(instance.exports.upd) { if(instance.exports.upd) {
instance.exports.upd(); instance.exports.upd();
} }
@@ -323,13 +321,12 @@ export default function MicroW8(screen, config = {}) {
} }
canvasCtx.putImageData(imageData, 0, 0); canvasCtx.putImageData(imageData, 0, 0);
let timeOffset = ((time * 6) % 100 - 50) / 6; let thisFrame = Math.floor(time * 6 / 100);
thisFrame = startTime + time - timeOffset / 8; let timeOffset = time - thisFrame * 100 / 6;
} else { nextFrame = Math.ceil(startTime + (thisFrame + 1) * 100 / 6 + Math.min(4, timeOffset));
thisFrame = Date.now();
} }
let now = Date.now(); let now = Date.now();
let nextFrame = Math.max(thisFrame + timePerFrame, now); nextFrame = Math.max(nextFrame, now);
if (restart) { if (restart) {
runModule(currentData); runModule(currentData);

File diff suppressed because it is too large Load Diff