mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-20 19:26:43 +01:00
Compare commits
10 Commits
v0.1.0
...
5d41733142
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d41733142 | |||
| c25a52b61b | |||
| 619ea903ba | |||
| 9b900a49e4 | |||
| f21497dd2e | |||
| 381eaf970f | |||
| 9632adb57f | |||
| 33e08e9b73 | |||
| cacde9136c | |||
| 81a38c2d75 |
295
Cargo.lock
generated
295
Cargo.lock
generated
@@ -55,9 +55,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.52"
|
||||
version = "1.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
|
||||
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
|
||||
|
||||
[[package]]
|
||||
name = "ariadne"
|
||||
@@ -140,9 +140,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
@@ -155,9 +155,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
version = "3.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
@@ -184,7 +184,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||
dependencies = [
|
||||
"nom 5.1.2",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -236,9 +236,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.46"
|
||||
version = "0.1.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089"
|
||||
checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
@@ -375,18 +375,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.0"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
|
||||
checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||
checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
@@ -405,9 +405,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.5"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
|
||||
checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
@@ -418,9 +418,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.5"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"lazy_static",
|
||||
@@ -481,12 +481,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
@@ -626,9 +620,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
@@ -636,9 +630,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
@@ -715,9 +709,9 @@ checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
|
||||
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
@@ -773,9 +767,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.55"
|
||||
version = "0.3.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -810,15 +804,15 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.112"
|
||||
version = "0.2.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||
checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52"
|
||||
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"winapi 0.3.9",
|
||||
@@ -859,29 +853,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "minifb"
|
||||
version = "0.19.3"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b6e41119d1667465608d36488fa5dcd228057a26c156e25f17f492f38435124"
|
||||
checksum = "f669be3941549a8291969021bf155ffb7bb337d4d2832d24ad7ab91c426c51a7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"orbclient",
|
||||
"raw-window-handle 0.3.4",
|
||||
"tempfile",
|
||||
"wayland-client",
|
||||
"wayland-cursor",
|
||||
"wayland-protocols",
|
||||
"winapi 0.3.9",
|
||||
"x11-dl",
|
||||
"xkb",
|
||||
"xkbcommon-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
@@ -952,19 +936,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5e06129fb611568ef4e868c14b326274959aa70ff7776e9d55323531c374945"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.2"
|
||||
@@ -975,17 +946,6 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "4.0.17"
|
||||
@@ -1043,12 +1003,6 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
@@ -1108,9 +1062,9 @@ checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
@@ -1144,9 +1098,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.12"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22849d5b648cf354b3d9aa83fc555f3496061bfd3b34e01824c40a621a260aa1"
|
||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -1294,15 +1248,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.21"
|
||||
@@ -1369,18 +1314,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.132"
|
||||
version = "1.0.135"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008"
|
||||
checksum = "2cf9235533494ea2ddcdb794665461814781c53f19d87b76e571a1c35acbad2b"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.132"
|
||||
version = "1.0.135"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276"
|
||||
checksum = "8dcde03d87d4c973c04be249e7d8f0b35db1c848c487bd43032808e59dd8328d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1389,9 +1334,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.8"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa"
|
||||
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -1414,9 +1359,9 @@ checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
@@ -1432,9 +1377,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.84"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
|
||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1458,20 +1403,6 @@ version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9bffcddbc2458fa3e6058414599e3c838a022abae82e5c67b4f7f80298d5bff"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"rand",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
@@ -1586,13 +1517,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uw8"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"curlywas",
|
||||
"minifb",
|
||||
"notify",
|
||||
"pico-args",
|
||||
"same-file",
|
||||
"uw8-tool",
|
||||
"wasmtime",
|
||||
"wat",
|
||||
@@ -1625,9 +1557,9 @@ checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
@@ -1674,9 +1606,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
@@ -1684,9 +1616,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@@ -1699,9 +1631,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -1709,9 +1641,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1722,9 +1654,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
@@ -1925,97 +1857,29 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wast"
|
||||
version = "38.0.1"
|
||||
version = "39.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae0d7b256bef26c898fa7344a2d627e8499f5a749432ce0a05eae1a64ff0c271"
|
||||
checksum = "e9bbbd53432b267421186feee3e52436531fa69a7cfee9403f5204352df3dd05"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
"memchr",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wat"
|
||||
version = "1.0.40"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adcfaeb27e2578d2c6271a45609f4a055e6d7ba3a12eff35b1fd5ba147bdf046"
|
||||
checksum = "ab98ed25494f97c69f28758617f27c3e92e5336040b5c3a14634f2dd3fe61830"
|
||||
dependencies = [
|
||||
"wast",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.28.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3ab332350e502f159382201394a78e3cc12d0f04db863429260164ea40e0355"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"downcast-rs",
|
||||
"libc",
|
||||
"nix",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-commons"
|
||||
version = "0.28.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21817947c7011bbd0a27e11b17b337bfd022e8544b071a2641232047966fbda"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"once_cell",
|
||||
"smallvec",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-cursor"
|
||||
version = "0.28.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be610084edd1586d45e7bdd275fe345c7c1873598caa464c4fb835dee70fa65a"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"wayland-client",
|
||||
"xcursor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols"
|
||||
version = "0.28.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "286620ea4d803bacf61fa087a4242ee316693099ee5a140796aaba02b29f861f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"wayland-client",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.28.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce923eb2deb61de332d1f356ec7b6bf37094dc5573952e1c8936db03b54c03f1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-sys"
|
||||
version = "0.28.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d841fca9aed7febf9bed2e9796c49bf58d4152ceda8ac949ebe00868d8f0feb8"
|
||||
dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.55"
|
||||
version = "0.3.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@@ -2103,15 +1967,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xcursor"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
|
||||
dependencies = [
|
||||
"nom 7.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xkb"
|
||||
version = "0.2.1"
|
||||
@@ -2134,12 +1989,6 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "0.5.0"
|
||||
@@ -2148,18 +1997,18 @@ checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71"
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.9.1+zstd.1.5.1"
|
||||
version = "0.9.2+zstd.1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "538b8347df9257b7fbce37677ef7535c00a3c7bf1f81023cc328ed7fe4b41de8"
|
||||
checksum = "2390ea1bf6c038c39674f22d95f0564725fc06034a47129179810b2fc58caa54"
|
||||
dependencies = [
|
||||
"zstd-safe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-safe"
|
||||
version = "4.1.2+zstd.1.5.1"
|
||||
version = "4.1.3+zstd.1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb4cfe2f6e6d35c5d27ecd9d256c4b6f7933c4895654917460ec56c29336cc1"
|
||||
checksum = "e99d81b99fb3c2c2c794e3fe56c305c63d5173a16a46b5850b07c935ffc7db79"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"zstd-sys",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "uw8"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@@ -8,9 +8,10 @@ edition = "2021"
|
||||
[dependencies]
|
||||
wasmtime = "0.30"
|
||||
anyhow = "1"
|
||||
minifb = "0.19"
|
||||
minifb = { version = "0.20", default-features = false, features = ["x11"] }
|
||||
notify = "4"
|
||||
pico-args = "0.4"
|
||||
curlywas = { git = "https://github.com/exoticorn/curlywas.git", rev = "196719b" }
|
||||
wat = "1"
|
||||
uw8-tool = { path = "uw8-tool" }
|
||||
uw8-tool = { path = "uw8-tool" }
|
||||
same-file = "1"
|
||||
22
README.md
22
README.md
@@ -13,7 +13,11 @@ See [here](https://exoticorn.github.io/microw8/) for more information and docs.
|
||||
* Memory: 256KB
|
||||
* Gamepad input (D-Pad + 4 Buttons)
|
||||
|
||||
## Download
|
||||
## Downloads
|
||||
|
||||
* [Linux](https://github.com/exoticorn/microw8/releases/download/v0.1.0/microw8-0.1.0-linux.tgz)
|
||||
* [MacOS](https://github.com/exoticorn/microw8/releases/download/v0.1.0/microw8-0.1.0-macos.tgz)
|
||||
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.0/microw8-0.1.0-windows.zip)
|
||||
|
||||
The download includes
|
||||
|
||||
@@ -31,6 +35,7 @@ Runs <file> which can be a binary WebAssembly module, an `.uw8` cart, a wat (Web
|
||||
|
||||
Options:
|
||||
|
||||
-t, --timeout FRAMES : Sets the timeout in frames (1/60s)
|
||||
-w, --watch : Reloads the given file every time it changes on disk.
|
||||
-p, --pack : Pack the file into an .uw8 cart before running it and print the resulting size.
|
||||
-u, --uncompressed : Use the uncompressed uw8 format for packing.
|
||||
@@ -48,6 +53,21 @@ Options:
|
||||
-l LEVEL, --level LEVEL : Compression level (0-9). Higher compression levels are really slow.
|
||||
|
||||
|
||||
uw8 unpack <infile> <outfile>
|
||||
|
||||
Unpacks a MicroW8 module into a standard WebAssembly module.
|
||||
|
||||
|
||||
uw8 compile [<options>] <infile> <outfile>
|
||||
|
||||
Compiles a CurlyWas source file to a standard WebAssembly module. Most useful together with
|
||||
the --debug option to get a module that works well in the Chrome debugger.
|
||||
|
||||
Options:
|
||||
|
||||
-d, --debug : Generate a name section to help debugging
|
||||
|
||||
|
||||
uw8 filter-exports <infile> <outfile>
|
||||
|
||||
Reads a binary WebAssembly module, removes all exports not used by the MicroW8 platform + everything that is unreachable without those exports and writes the resulting module to <outfile>.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
clang -O2 -Wno-incompatible-library-redeclaration --no-standard-libraries -ffast-math -Xclang -target-feature -Xclang +nontrapping-fptoint -Wl,--no-entry -Wl,--export-all -Wl,--import-memory -Wl,--initial-memory=262144 -Wl,-zstack-size=90000 -o cart.wasm cart.c --target=wasm32 && \
|
||||
clang -O2 -Wno-incompatible-library-redeclaration --no-standard-libraries -ffast-math -Xclang -target-feature -Xclang +nontrapping-fptoint -Wl,--no-entry,--export-all,--import-memory,--initial-memory=262144,--global-base=81920,-zstack-size=4096 -o cart.wasm cart.c --target=wasm32 && \
|
||||
uw8 filter-exports cart.wasm cart.wasm && \
|
||||
wasm-opt -Oz --fast-math --strip-producers -o cart.wasm cart.wasm && \
|
||||
uw8 pack -l 9 cart.wasm cart.uw8
|
||||
@@ -1,102 +1,21 @@
|
||||
import "env.memory" memory(4);
|
||||
|
||||
import "env.cls" fn cls(i32);
|
||||
import "env.setPixel" fn setPixel(i32, i32, i32);
|
||||
import "env.time" fn time() -> f32;
|
||||
import "env.line" fn line(f32, f32, f32, f32, i32);
|
||||
import "env.sin" fn sin(f32) -> f32;
|
||||
import "env.cos" fn cos(f32) -> f32;
|
||||
|
||||
fn line(x1: f32, y1: f32, x2: f32, y2: f32, col: i32) {
|
||||
let swapTmp: f32;
|
||||
if x1 > x2 {
|
||||
swapTmp = x1;
|
||||
x1 = x2;
|
||||
x2 = swapTmp;
|
||||
swapTmp = y1;
|
||||
y1 = y2;
|
||||
y2 = swapTmp;
|
||||
}
|
||||
if x1 < 0 as f32 & x2 >= 0 as f32 {
|
||||
y1 = y1 + (y2 - y1) * -x1 / (x2 - x1);
|
||||
x1 = 0 as f32;
|
||||
}
|
||||
if x1 < 320 as f32 & x2 >= 320 as f32 {
|
||||
y2 = y2 + (y2 - y1) * (320 as f32 - x2) / (x2 - x1);
|
||||
x2 = 320 as f32;
|
||||
}
|
||||
|
||||
if y1 > y2 {
|
||||
swapTmp = x1;
|
||||
x1 = x2;
|
||||
x2 = swapTmp;
|
||||
swapTmp = y1;
|
||||
y1 = y2;
|
||||
y2 = swapTmp;
|
||||
}
|
||||
if y1 < 0 as f32 & y2 >= 0 as f32 {
|
||||
x1 = x1 + (x2 - x1) * -y1 / (y2 - y1);
|
||||
y1 = 0 as f32;
|
||||
}
|
||||
if y1 < 240 as f32 & y2 >= 240 as f32 {
|
||||
x2 = x2 + (x2 - x1) * (240 as f32 - y2) / (y2 - y1);
|
||||
y2 = 240 as f32;
|
||||
}
|
||||
|
||||
let lazy dx = x2 - x1;
|
||||
let lazy dy = y2 - y1;
|
||||
let max_axis: f32;
|
||||
let p: f32;
|
||||
if abs(dx) >= dy {
|
||||
max_axis = dx;
|
||||
p = x1;
|
||||
} else {
|
||||
max_axis = dy;
|
||||
p = y1;
|
||||
}
|
||||
|
||||
let steps = floor(p + max_axis) as i32 - floor(p) as i32;
|
||||
p = floor(p) + 0.5 - p;
|
||||
if max_axis < 0 as f32 {
|
||||
steps = -steps;
|
||||
p = -p;
|
||||
max_axis = -max_axis;
|
||||
}
|
||||
dx = dx / max_axis;
|
||||
dy = dy / max_axis;
|
||||
|
||||
let f = min(max_axis, max(0 as f32, p));
|
||||
setPixel((x1 + f * dx) as i32, (y1 + f * dy) as i32, col);
|
||||
|
||||
if !steps {
|
||||
return;
|
||||
}
|
||||
|
||||
x1 = x1 + (1 as f32 + p) * dx;
|
||||
y1 = y1 + (1 as f32 + p) * dy;
|
||||
|
||||
p = p + steps as f32;
|
||||
|
||||
loop pixels {
|
||||
if steps := steps - 1 {
|
||||
setPixel(x1 as i32, y1 as i32, col);
|
||||
x1 = x1 + dx;
|
||||
y1 = y1 + dy;
|
||||
branch pixels;
|
||||
}
|
||||
}
|
||||
|
||||
f = min(max_axis, p) - p;
|
||||
setPixel((x1 + f * dx) as i32, (y1 + f * dy) as i32, col);
|
||||
}
|
||||
|
||||
export fn upd() {
|
||||
cls(0);
|
||||
// line(0.0, 4.0, 7.0, -2.0, 15);
|
||||
// return;
|
||||
let i: i32;
|
||||
loop lines {
|
||||
let angle = i as f32 * (3.1415 / 25.0) + time() * 0.1;
|
||||
line(160.0, 120.0, 160.0 + sin(angle) * 100.0, 120.0 + cos(angle) * 100.0, 47);
|
||||
let angle = i as f32 * (3.1415 / 25.0) + time() * 0.125;
|
||||
line(
|
||||
160 as f32, 120 as f32,
|
||||
160 as f32 + sin(angle) * 100 as f32,
|
||||
120 as f32 + cos(angle) * 100 as f32,
|
||||
47);
|
||||
branch_if (i := i + 1) < 50: lines;
|
||||
}
|
||||
}
|
||||
|
||||
65
logo.svg
Normal file
65
logo.svg
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="120"
|
||||
height="120"
|
||||
viewBox="0 0 120 120"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.6041667"
|
||||
inkscape:cx="21.780347"
|
||||
inkscape:cy="63.260116"
|
||||
inkscape:window-width="1916"
|
||||
inkscape:window-height="1041"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="18"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#85a6b2;fill-rule:evenodd;fill-opacity:1"
|
||||
id="rect31"
|
||||
width="112.05161"
|
||||
height="109.64198"
|
||||
x="3.9731982"
|
||||
y="6.3613" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:117.333px;line-height:1.25;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Bold';fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
x="-6.2686396"
|
||||
y="117.70291"
|
||||
id="text2691"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2689"
|
||||
x="-6.2686396"
|
||||
y="117.70291">W8</tspan></text>
|
||||
<circle
|
||||
style="fill:#ffffff;stroke-width:1.32327"
|
||||
id="path121"
|
||||
cx="60.962471"
|
||||
cy="6.7644148"
|
||||
r="14.855442" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -18,7 +18,7 @@ highlight_theme = "ascetic-white"
|
||||
[extra]
|
||||
# Put all your custom variables here
|
||||
juice_logo_name = "MicroW8"
|
||||
juice_logo_path = "microw8.svg"
|
||||
juice_logo_path = "img/microw8.svg"
|
||||
juice_extra_menu = [
|
||||
{ title = "Github", link = "https://github.com/exoticorn/microw8" }
|
||||
]
|
||||
@@ -15,19 +15,41 @@ The initial motivation behind MicroW8 was to explore whether there was a way to
|
||||
* Gamepad input (D-Pad + 4 Buttons)
|
||||
|
||||
## Examples
|
||||
* [Fireworks](v0.1pre5#AgwvgP+M59snqjl4CMKw5sqm1Zw9yJCbSviMjeLUdHus2a3yl/a99+uiBeqZgP/2jqSjrLjRk73COMM6OSLpsxK8ugT1kuk/q4hQUqqPpGozHoa0laulzGGcahzdfdJsYaK1sIdeIYS9M5PnJx/Wk9H+PvWEPy2Zvv7I6IW7Fg==) (127 bytes): Some fireworks to welcome 2022.
|
||||
* [Skip Ahead](v0.1pre5#AgyfpZ80wkW28kiUZ9VIK4v+RPnVxqjK1dz2BcDoNyQPsS2g4OgEzkTe6jyoAfFOmqKrS8SM2aRljBal9mjNn8i4fP9eBK+RehQKxxGtJa9FqftvqEnh3ez1YaYxqj7jgTdzJ/WAYVmKMovBT1myrX3FamqKSOgMsNedLhVTLAhQup3sNcYEjGNo8b0HZ5+AgMgCwYRGCe//XQOMAaAAzqDILgmpEZ/43RKHcQpHEQwbURfNQJpadJe2sz3q5FlQnTGXQ9oSMokidhlC+aR/IpNHieuBGLhFZ2GfnwVQ0geBbQpTPA==) (229 bytes): A port of my [TIC-80 256byte game](http://tic80.com/play?cart=1735) from LoveByte'21
|
||||
* [OhNoAnotherTunnel](v0.1pre4#Ag95rdCB5Ww5NofyQaKF4P1mrNRso4azgiem4hK99Gh8OMzSpFq3NsNDo7O7pqln10D11l9uXr/ritw7OEzKwbEfCdvaRnS2Z0Kz0iDEZt/gIqOdvFmxsL1MjPQ4XInPbUJpQUonhQq29oP2omFabnQxn0bzoK7mZjcwc5GetHG+hGajkJcRr8oOnjfCol8RD+ha33GYtPnut+GLe4ktzf5UxZwGs6oT9qqC61lRDakN) (177 bytes): A port of my [entry](http://tic80.com/play?cart=1871) in the Outline'21 bytebattle final
|
||||
* [Technotunnel](v0.1pre4#AqL8HeK1M9dn2nWNIF5vaq/Vh64pMt5nJIFoFKpBMPUsGtDtpqjo1JbT9LzPhAxCqJ7Yh4TA6oTGd4xhLowf+cWZMY73+7AZmfXJJsBi4cej/hH+4wlAgxFIrnOYnr/18IpnZbsHf0eGm1BhahX74+cVR0TRmNQmYC7GhCNS3mv/3MJn74lCj7t28aBJPjEZhP9fGXdG2u5Egh/Tjdg=) (158 bytes): A port of my [entry](https://tic80.com/play?cart=1873) in the Outline'21 bytebattle quater final
|
||||
* [Font & Palette](v0.1pre4#AgKaeeOuwg5gCKvFIeiitEwMpUI2rymEcu+DDB1vMu9uBoufvUxIr4Y5p4Jj2ukoNO4PE7QS5cN1ZyDMCRfSzYIGZxKlN2J6NKEWK7KVPk9wVUgn1Ip+hsMinWgEO8ETKfPuHoIa4kjI+ULFOMad7vd3rt/lh1Vy9w+R2MXG/7T61d3c7C6KY+eQNS0eW3ys4iU8R6SycuWZuuZ2Sg3Qxp826s+Kt+2qBojpzNOSoyFqyrVyYMTKEkSl0BZOj59Cs1hPm5bq0F1MmVhGAzMhW9V4YeAe): Just a simple viewer for the default font and palette.
|
||||
* [Fireworks](v0.1.1#AgwvgP+M59snqjl4CMKw5sqm1Zw9yJCbSviMjeLUdHus2a3yl/a99+uiBeqZgP/2jqSjrLjRk73COMM6OSLpsxK8ugT1kuk/q4hQUqqPpGozHoa0laulzGGcahzdfdJsYaK1sIdeIYS9M5PnJx/Wk9H+PvWEPy2Zvv7I6IW7Fg==) (127 bytes): Some fireworks to welcome 2022.
|
||||
* [Skip Ahead](v0.1.1#AgyfpZ80wkW28kiUZ9VIK4v+RPnVxqjK1dz2BcDoNyQPsS2g4OgEzkTe6jyoAfFOmqKrS8SM2aRljBal9mjNn8i4fP9eBK+RehQKxxGtJa9FqftvqEnh3ez1YaYxqj7jgTdzJ/WAYVmKMovBT1myrX3FamqKSOgMsNedLhVTLAhQup3sNcYEjGNo8b0HZ5+AgMgCwYRGCe//XQOMAaAAzqDILgmpEZ/43RKHcQpHEQwbURfNQJpadJe2sz3q5FlQnTGXQ9oSMokidhlC+aR/IpNHieuBGLhFZ2GfnwVQ0geBbQpTPA==) (229 bytes): A port of my [TIC-80 256byte game](http://tic80.com/play?cart=1735) from LoveByte'21
|
||||
* [OhNoAnotherTunnel](v0.1.1#AgPP1oEFvPzY/rBZwTumtYn37zeMFgpir1Bkn91jsNcp26VzoUpkAOOJTtnzVBfW+/dGnnIdbq/irBUJztY5wuua80DORTYZndgdwZHcSk15ajc4nyO0g1A6kGWyW56oZk0iPYJA9WtUmoj0Plvy1CGwIZrMe57X7QZcdqc3u6zjTA41Tpiqi9vnO3xbhi8o594Vx0XPXwVzpYq1ZCTYenfAGaXKkDmAFJqiVIsiCg==) (175 bytes): A port of my [entry](http://tic80.com/play?cart=1871) in the Outline'21 bytebattle final
|
||||
* [Technotunnel](v0.1.1#AhPXpq894LaUhp5+HQf39f39/Jc8g5zUrBSc0uyKh36ivskczhY84h55zL8gWpkdvKuRQI+KIt80isKzh8jkM8nILcx0RUvyk8yjE8TgNsgkcORVI0RY5k3qE4ySjaycxa2DVZH61UWZuLsCouuwT7I80TbmmetQSbMywJ/avrrCZIAH0UzQfvOiCJNG48NI0FFY1vjB7a7dcp8Uqg==) (157 bytes): A port of my [entry](https://tic80.com/play?cart=1873) in the Outline'21 bytebattle quater final
|
||||
* [Font & Palette](v0.1.1#At/p39+IBnj6ry1TRe7jzVy2A4tXgBvmoW2itzoyF2aM28pGy5QDiKxqrk8l9sbWZLtnAb+jgOfU+9QhpuyCAkhN6gPOU481IUL/df96vNe3h288Dqwhd3sfFpothIVFsMwRK72kW2hiR7zWsaXyy5pNmjR6BJk4piWx9ApT1ZwoUajhk6/zij6itq/FD1U3jj/J3MOwqZ2ef8Bv6ZPQlJIYVf62icGa69wS6SI1qBpIFiF14F8PcztRVbKIxLpT4ArCS6nz6FPnyUkqATGSBNPJ): Just a simple viewer for the default font and palette.
|
||||
|
||||
Examplers for older versions:
|
||||
|
||||
* [Technotunnel B/W](v0.1pre2#AQrDAQHAAQIBfwp9A0AgAUEAsiABQcACb7JDmhkgQ5MiBCAEIASUIAFBwAJtQfgAa7IiBSAFlJKRIgaVIgcgByAAskHQD7KVIgIQAEPNzEw/lCIDlCAHIAeUIAOUIAOUQQGykiADIAOUk5GSIgiUIAOTQQqylCACkiIJqCAFIAaVIAiUQQqylCACkiIKqHMgCEEyspQgBpUiCyACkkEUspSocUEFcbJBArIgC5OUQRaylJeoOgB4IAFBAWoiAUGA2ARIDQALCw==) (199 bytes uncompressed): A port of my [entry](https://tic80.com/play?cart=1873) in the Outline'21 bytebattle quater final (older MicroW8 version with monochrome palette)
|
||||
* [XorScroll](v0.1pre2#AQovAS0BAX8DQCABIAFBwAJvIABBCm1qIAFBwAJtczoAeCABQQFqIgFBgNgESA0ACws=) (50 bytes uncompressed): A simple scrolling XOR pattern. Fun fact: This is the pre-loaded effect when entering a bytebattle.
|
||||
* [CircleWorm](v0.1pre2#AQp7AXkCAX8CfUEgEA0DQCABskEEspUiAkECspUgALJBiCeylSIDQQWylJIQAEEBspJBoAGylCACQQOylSADQQSylJIQAEEBspJB+ACylCADQRGylCACQQKylJIQAEECspJBELKUIAFBAmxBP2oQEiABQQFqIgFBP0gNAAsL) (126 bytes uncompressed): Just a test for the circle fill function.
|
||||
|
||||
## Versions
|
||||
|
||||
* [v0.1pre1](v0.1pre1)
|
||||
* [v0.1pre2](v0.1pre2)
|
||||
* [v0.1pre3](v0.1pre3)
|
||||
* [v0.1pre4](v0.1pre4)
|
||||
* [v0.1pre5](v0.1pre5)
|
||||
### 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)
|
||||
* [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)
|
||||
|
||||
Changes:
|
||||
|
||||
* implement more robust file watcher
|
||||
* add basic video recording on F10 in web runtime
|
||||
* add screenshot on F9
|
||||
* add watchdog to interrupt hanging update in native runtime
|
||||
* add devkit mode to web runtime
|
||||
* add unpack and compile commands to uw8
|
||||
* add support for table/element section in pack command
|
||||
* disable wayland support (caused missing window decorations in gnome)
|
||||
|
||||
### 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)
|
||||
* [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)
|
||||
|
||||
@@ -105,7 +105,7 @@ as a cheap random-access PRNG (aka noise function).
|
||||
|
||||
## Graphics
|
||||
|
||||
The default palette can be seen [here](../v0.1pre4#AgKaeeOuwg5gCKvFIeiitEwMpUI2rymEcu+DDB1vMu9uBoufvUxIr4Y5p4Jj2ukoNO4PE7QS5cN1ZyDMCRfSzYIGZxKlN2J6NKEWK7KVPk9wVUgn1Ip+hsMinWgEO8ETKfPuHoIa4kjI+ULFOMad7vd3rt/lh1Vy9w+R2MXG/7T61d3c7C6KY+eQNS0eW3ys4iU8R6SycuWZuuZ2Sg3Qxp826s+Kt+2qBojpzNOSoyFqyrVyYMTKEkSl0BZOj59Cs1hPm5bq0F1MmVhGAzMhW9V4YeAe). (Press Z on the keyboard to switch to palette.)
|
||||
The default palette can be seen [here](../v0.1.0#At/p39+IBnj6ry1TRe7jzVy2A4tXgBvmoW2itzoyF2aM28pGy5QDiKxqrk8l9sbWZLtnAb+jgOfU+9QhpuyCAkhN6gPOU481IUL/df96vNe3h288Dqwhd3sfFpothIVFsMwRK72kW2hiR7zWsaXyy5pNmjR6BJk4piWx9ApT1ZwoUajhk6/zij6itq/FD1U3jj/J3MOwqZ2ef8Bv6ZPQlJIYVf62icGa69wS6SI1qBpIFiF14F8PcztRVbKIxLpT4ArCS6nz6FPnyUkqATGSBNPJ). (Press Z on the keyboard to switch to palette.)
|
||||
|
||||
The palette can be changed by writing 32bit rgba colors to addresses 0x13000-0x13400.
|
||||
|
||||
@@ -192,7 +192,7 @@ The integer time in milliseconds can also be read at address 0x40.
|
||||
|
||||
## Text output
|
||||
|
||||
The default font can be seen [here](../v0.1pre4#AgKaeeOuwg5gCKvFIeiitEwMpUI2rymEcu+DDB1vMu9uBoufvUxIr4Y5p4Jj2ukoNO4PE7QS5cN1ZyDMCRfSzYIGZxKlN2J6NKEWK7KVPk9wVUgn1Ip+hsMinWgEO8ETKfPuHoIa4kjI+ULFOMad7vd3rt/lh1Vy9w+R2MXG/7T61d3c7C6KY+eQNS0eW3ys4iU8R6SycuWZuuZ2Sg3Qxp826s+Kt+2qBojpzNOSoyFqyrVyYMTKEkSl0BZOj59Cs1hPm5bq0F1MmVhGAzMhW9V4YeAe).
|
||||
The default font can be seen [here](../v0.1.0#At/p39+IBnj6ry1TRe7jzVy2A4tXgBvmoW2itzoyF2aM28pGy5QDiKxqrk8l9sbWZLtnAb+jgOfU+9QhpuyCAkhN6gPOU481IUL/df96vNe3h288Dqwhd3sfFpothIVFsMwRK72kW2hiR7zWsaXyy5pNmjR6BJk4piWx9ApT1ZwoUajhk6/zij6itq/FD1U3jj/J3MOwqZ2ef8Bv6ZPQlJIYVf62icGa69wS6SI1qBpIFiF14F8PcztRVbKIxLpT4ArCS6nz6FPnyUkqATGSBNPJ).
|
||||
|
||||
The font can be changed by writing 1bpp 8x8 characters to addresses 0x13400-0x13c00.
|
||||
|
||||
@@ -284,6 +284,8 @@ Runs `<file>` which can be a binary WebAssembly module, an `.uw8` cart, a wat (W
|
||||
|
||||
Options:
|
||||
|
||||
* `-t FRAMES`, `--timeout FRAMES` : Sets the timeout in frames (1/60s). If the start or update function runs longer than this it is forcibly interupted
|
||||
and execution of the cart is stopped. Defaults to 30 (0.5s)
|
||||
* `-w`, `--watch`: Reloads the given file every time it changes on disk.
|
||||
* `-p`, `--pack`: Pack the file into an `.uw8` cart before running it and print the resulting size.
|
||||
* `-u`, `--uncompressed`: Use the uncompressed `uw8` format for packing.
|
||||
@@ -303,6 +305,27 @@ Options:
|
||||
* `-u`, `--uncompressed`: Use the uncompressed `uw8` format for packing.
|
||||
* `-l LEVEL`, `--level LEVEL`: Compression level (0-9). Higher compression levels are really slow.
|
||||
|
||||
## `uw8 unpack`
|
||||
|
||||
Usage:
|
||||
|
||||
`uw8 unpack <infile> <outfile>`
|
||||
|
||||
Unpacks a MicroW8 module into a standard WebAssembly module.
|
||||
|
||||
## `uw8 compile`
|
||||
|
||||
Usage:
|
||||
|
||||
`uw8 compile [<options>] <infile> <outfile>`
|
||||
|
||||
Compiles a [CurlyWas](https://github.com/exoticorn/curlywas) source file to a standard WebAssembly module. Most useful together with
|
||||
the `--debug` option to get a module that works well in the Chrome debugger.
|
||||
|
||||
Options:
|
||||
|
||||
* `-d`, `--debug`: Generate a name section to help debugging
|
||||
|
||||
## `uw8 filter-exports`
|
||||
|
||||
Usage:
|
||||
@@ -388,3 +411,33 @@ the first function in the file under the name `upd`.
|
||||
|
||||
Same as version `01` except everything after the first byte is compressed
|
||||
using a [custom LZ compression scheme](https://github.com/exoticorn/upkr).
|
||||
|
||||
# The web runtime
|
||||
|
||||
Load carts into the web runtime either by using the "Load cart..." button, or by dragging the file
|
||||
onto the screen area.
|
||||
|
||||
## Input
|
||||
|
||||
For input, you can either use a standard gamepad or keyboard. On a keyboard use the arrow keys and the keys Z, X, A and S to emulate the A, B, X and Y buttons.
|
||||
|
||||
## Video recording
|
||||
|
||||
Press F10 to start recording, press again to stop. Then a download dialog will open for the video file.
|
||||
The file might miss some metadata needed to load in some video editing tools, in that case you can run
|
||||
it through ffmpeg like this `ffmpeg -i IN_NAME.webm -c copy -o OUT_NAME.webm to fix it up.
|
||||
|
||||
To convert it to 1280x720, for example for a lovebyte upload, you can use:
|
||||
|
||||
```
|
||||
ffmpeg -i IN.webm -vf "scale=960:720:flags=neighbor,pad=1280:720:160:0" -r 60 OUT.mp4
|
||||
```
|
||||
|
||||
## Screenshot
|
||||
|
||||
Pressing F9 opens a download dialog with a screenshot.
|
||||
|
||||
## Devkit mode
|
||||
|
||||
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.
|
||||
5
site/static/img/microw8.svg
Normal file
5
site/static/img/microw8.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg width="120" height="120" version="1.1" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m3.9727 6.3613v27.945h7.8691l2.8281 66.549 6.9199-56.922h16.969l6.4375 56.922 4.1523-66.549h17.148l-9.5488 81.697h27.195c-4.1759-2.1972-7.3595-5.016-9.5234-8.4707-2.2464-3.6905-3.3691-7.6805-3.3691-11.973 0-4.7735 1.3845-8.9251 4.1523-12.455 2.7679-3.53 6.4981-6.3194 11.191-8.3652-4.2521-2.7277-7.3402-5.4948-9.2656-8.3027-1.8854-2.8481-2.8281-6.5783-2.8281-11.191 0-4.7334 1.223-8.8256 3.6699-12.275 2.4469-3.4498 5.7559-6.0981 9.9277-7.9434 4.212-1.8854 8.9647-2.8262 14.26-2.8262 5.2203 0 9.8397 0.84602 13.867 2.5234v-28.363h-40.227a14.855 14.855 0 0 1 0.019531 0.40234 14.855 14.855 0 0 1-14.855 14.855 14.855 14.855 0 0 1-14.855-14.855 14.855 14.855 0 0 1 0.052734-0.40234zm98.186 38.775c-3.0888 0-5.4939 0.863-7.2187 2.5879-1.6848 1.6848-2.5273 4.192-2.5273 7.5215 0 2.9283 0.98169 5.3538 2.9473 7.2793 1.9656 1.8854 5.0352 3.6113 9.207 5.1758 2.7277-2.0057 4.5928-3.971 5.5957-5.8965 1.0028-1.9656 1.5039-4.1129 1.5039-6.4395 0-2.9684-0.8017-5.4144-2.4062-7.3398-1.5644-1.9255-3.9326-2.8887-7.1016-2.8887zm-72.203 12.938-6.4902 57.93h12.393zm68.113 21.781c-2.4469 1.5644-4.3938 3.5502-5.8379 5.957-1.4441 2.4068-2.166 5.2741-2.166 8.6035 0 3.4498 1.0041 6.2781 3.0098 8.4844 2.0458 2.1662 5.0726 3.25 9.084 3.25 4.1317 0 7.142-1.1043 9.0274-3.3106 1.8854-2.2464 2.8281-4.8723 2.8281-7.8809 0-2.7679-0.56235-5.0153-1.6856-6.7402-1.0831-1.7249-2.7886-3.2096-5.1152-4.4531-2.3266-1.2836-5.3738-2.5864-9.1445-3.9102z" fill="#85a6b2" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
1
site/static/v0.1.1/index.html
Normal file
1
site/static/v0.1.1/index.html
Normal file
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
|
||||
<section>
|
||||
<h1 class="text-center heading-text">A WebAssembly based fantasy console</h1>
|
||||
</section>
|
||||
<a href="v0.1pre5">
|
||||
<a href="v0.1.1">
|
||||
<img class="demonstration-gif" style="width:640px;height:480px;image-rendering:pixelated" src="img/technotunnel.png"></img>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
70
src/filewatcher.rs
Normal file
70
src/filewatcher.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use anyhow::{bail, Result};
|
||||
use notify::{DebouncedEvent, Watcher, RecommendedWatcher};
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
path::{Path, PathBuf},
|
||||
sync::mpsc,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
pub struct FileWatcher {
|
||||
_watcher: RecommendedWatcher,
|
||||
watched_files: BTreeSet<PathBuf>,
|
||||
rx: mpsc::Receiver<DebouncedEvent>,
|
||||
}
|
||||
|
||||
pub struct FileWatcherBuilder(BTreeSet<PathBuf>);
|
||||
|
||||
impl FileWatcher {
|
||||
pub fn builder() -> FileWatcherBuilder {
|
||||
FileWatcherBuilder(BTreeSet::new())
|
||||
}
|
||||
|
||||
pub fn poll_changed_file(&self) -> Result<Option<PathBuf>> {
|
||||
let event = self.rx.try_recv();
|
||||
match event {
|
||||
Ok(DebouncedEvent::Create(path) | DebouncedEvent::Write(path)) => {
|
||||
let handle = same_file::Handle::from_path(&path)?;
|
||||
for file in &self.watched_files {
|
||||
if handle == same_file::Handle::from_path(file)? {
|
||||
return Ok(Some(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(mpsc::TryRecvError::Disconnected) => bail!("File watcher disconnected"),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileWatcherBuilder {
|
||||
pub fn add_file<P: Into<PathBuf>>(&mut self, path: P) -> &mut Self {
|
||||
self.0.insert(path.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<FileWatcher> {
|
||||
let mut directories: BTreeSet<&Path> = BTreeSet::new();
|
||||
|
||||
for file in &self.0 {
|
||||
if let Some(directory) = file.parent() {
|
||||
directories.insert(directory);
|
||||
}
|
||||
}
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let mut watcher = notify::watcher(tx, Duration::from_millis(100))?;
|
||||
|
||||
for directory in directories {
|
||||
watcher.watch(directory, notify::RecursiveMode::NonRecursive)?;
|
||||
}
|
||||
|
||||
Ok(FileWatcher {
|
||||
_watcher: watcher,
|
||||
watched_files: self.0,
|
||||
rx,
|
||||
})
|
||||
}
|
||||
}
|
||||
97
src/lib.rs
97
src/lib.rs
@@ -1,6 +1,8 @@
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
use std::{fs::File, time::Instant};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use std::{fs::File, thread, time::Instant};
|
||||
|
||||
use anyhow::Result;
|
||||
use minifb::{Key, Window, WindowOptions};
|
||||
@@ -8,7 +10,20 @@ use wasmtime::{
|
||||
Engine, GlobalType, Memory, MemoryType, Module, Mutability, Store, TypedFunc, ValType,
|
||||
};
|
||||
|
||||
static GAMEPAD_KEYS: &'static [Key] = &[Key::Up, Key::Down, Key::Left, Key::Right, Key::Z, Key::X, Key::A, Key::S];
|
||||
mod filewatcher;
|
||||
|
||||
pub use filewatcher::FileWatcher;
|
||||
|
||||
static GAMEPAD_KEYS: &'static [Key] = &[
|
||||
Key::Up,
|
||||
Key::Down,
|
||||
Key::Left,
|
||||
Key::Right,
|
||||
Key::Z,
|
||||
Key::X,
|
||||
Key::A,
|
||||
Key::S,
|
||||
];
|
||||
|
||||
pub struct MicroW8 {
|
||||
engine: Engine,
|
||||
@@ -16,6 +31,7 @@ pub struct MicroW8 {
|
||||
window: Window,
|
||||
window_buffer: Vec<u32>,
|
||||
instance: Option<UW8Instance>,
|
||||
timeout: u32,
|
||||
}
|
||||
|
||||
struct UW8Instance {
|
||||
@@ -24,12 +40,27 @@ struct UW8Instance {
|
||||
end_frame: TypedFunc<(), ()>,
|
||||
update: TypedFunc<(), ()>,
|
||||
start_time: Instant,
|
||||
module: Vec<u8>
|
||||
module: Vec<u8>,
|
||||
watchdog: Arc<Mutex<UW8WatchDog>>,
|
||||
}
|
||||
|
||||
impl Drop for UW8Instance {
|
||||
fn drop(&mut self) {
|
||||
if let Ok(mut watchdog) = self.watchdog.lock() {
|
||||
watchdog.stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct UW8WatchDog {
|
||||
interupt: wasmtime::InterruptHandle,
|
||||
timeout: u32,
|
||||
stop: bool,
|
||||
}
|
||||
|
||||
impl MicroW8 {
|
||||
pub fn new() -> Result<MicroW8> {
|
||||
let engine = wasmtime::Engine::default();
|
||||
let engine = wasmtime::Engine::new(wasmtime::Config::new().interruptable(true))?;
|
||||
|
||||
let loader_module =
|
||||
wasmtime::Module::new(&engine, include_bytes!("../platform/bin/loader.wasm"))?;
|
||||
@@ -47,6 +78,7 @@ impl MicroW8 {
|
||||
window,
|
||||
window_buffer: vec![0u32; 320 * 240],
|
||||
instance: None,
|
||||
timeout: 30,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -54,6 +86,10 @@ impl MicroW8 {
|
||||
self.window.is_open() && !self.window.is_key_down(Key::Escape)
|
||||
}
|
||||
|
||||
pub fn set_timeout(&mut self, timeout: u32) {
|
||||
self.timeout = timeout;
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
self.instance = None;
|
||||
for v in &mut self.window_buffer {
|
||||
@@ -130,7 +166,36 @@ impl MicroW8 {
|
||||
)?;
|
||||
}
|
||||
|
||||
let watchdog = Arc::new(Mutex::new(UW8WatchDog {
|
||||
interupt: store.interrupt_handle()?,
|
||||
timeout: self.timeout,
|
||||
stop: false,
|
||||
}));
|
||||
|
||||
{
|
||||
let watchdog = watchdog.clone();
|
||||
thread::spawn(move || loop {
|
||||
thread::sleep(Duration::from_millis(17));
|
||||
if let Ok(mut watchdog) = watchdog.lock() {
|
||||
if watchdog.stop {
|
||||
break;
|
||||
}
|
||||
if watchdog.timeout > 0 {
|
||||
watchdog.timeout -= 1;
|
||||
if watchdog.timeout == 0 {
|
||||
watchdog.interupt.interrupt();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let instance = linker.instantiate(&mut store, &module)?;
|
||||
if let Ok(mut watchdog) = watchdog.lock() {
|
||||
watchdog.timeout = 0;
|
||||
}
|
||||
let end_frame = platform_instance.get_typed_func::<(), (), _>(&mut store, "endFrame")?;
|
||||
let update = instance.get_typed_func::<(), (), _>(&mut store, "upd")?;
|
||||
|
||||
@@ -140,19 +205,26 @@ impl MicroW8 {
|
||||
end_frame,
|
||||
update,
|
||||
start_time: Instant::now(),
|
||||
module: module_data.into()
|
||||
module: module_data.into(),
|
||||
watchdog,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_frame(&mut self) -> Result<()> {
|
||||
let mut result = Ok(());
|
||||
if let Some(mut instance) = self.instance.take() {
|
||||
{
|
||||
let time = instance.start_time.elapsed().as_millis() as i32;
|
||||
let mut gamepad: u32 = 0;
|
||||
for key in self.window.get_keys().unwrap_or(Vec::new()) {
|
||||
if let Some(index) = GAMEPAD_KEYS.iter().enumerate().find(|(_, &k)| k == key).map(|(i, _)| i) {
|
||||
for key in self.window.get_keys() {
|
||||
if let Some(index) = GAMEPAD_KEYS
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, &k)| k == key)
|
||||
.map(|(i, _)| i)
|
||||
{
|
||||
gamepad |= 1 << index;
|
||||
}
|
||||
}
|
||||
@@ -162,7 +234,13 @@ impl MicroW8 {
|
||||
mem[68..72].copy_from_slice(&gamepad.to_le_bytes());
|
||||
}
|
||||
|
||||
instance.update.call(&mut instance.store, ())?;
|
||||
if let Ok(mut watchdog) = instance.watchdog.lock() {
|
||||
watchdog.timeout = self.timeout;
|
||||
}
|
||||
result = instance.update.call(&mut instance.store, ());
|
||||
if let Ok(mut watchdog) = instance.watchdog.lock() {
|
||||
watchdog.timeout = 0;
|
||||
}
|
||||
instance.end_frame.call(&mut instance.store, ())?;
|
||||
|
||||
let memory = instance.memory.data(&instance.store);
|
||||
@@ -178,7 +256,7 @@ impl MicroW8 {
|
||||
|
||||
if self.window.is_key_pressed(Key::R, minifb::KeyRepeat::No) {
|
||||
self.load_from_memory(&instance.module)?;
|
||||
} else {
|
||||
} else if result.is_ok() {
|
||||
self.instance = Some(instance);
|
||||
}
|
||||
}
|
||||
@@ -186,6 +264,7 @@ impl MicroW8 {
|
||||
self.window
|
||||
.update_with_buffer(&self.window_buffer, 320, 240)?;
|
||||
|
||||
result?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
57
src/main.rs
57
src/main.rs
@@ -1,17 +1,14 @@
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::process;
|
||||
use std::sync::mpsc;
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
process::exit,
|
||||
};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use notify::{DebouncedEvent, Watcher};
|
||||
use anyhow::Result;
|
||||
use pico_args::Arguments;
|
||||
use uw8::MicroW8;
|
||||
use uw8::{FileWatcher, MicroW8};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut args = Arguments::from_env();
|
||||
@@ -23,13 +20,17 @@ fn main() -> Result<()> {
|
||||
}
|
||||
Some("run") => run(args),
|
||||
Some("pack") => pack(args),
|
||||
Some("unpack") => unpack(args),
|
||||
Some("compile") => compile(args),
|
||||
Some("filter-exports") => filter_exports(args),
|
||||
Some("help") | None => {
|
||||
println!("uw8 {}", env!("CARGO_PKG_VERSION"));
|
||||
println!();
|
||||
println!("Usage:");
|
||||
println!(" uw8 run [-w/--watch] [-p/--pack] [-u/--uncompressed] [-l/--level] [-o/--output <out-file>] <file>");
|
||||
println!(" uw8 run [-t/--timeout <frames>] [-w/--watch] [-p/--pack] [-u/--uncompressed] [-l/--level] [-o/--output <out-file>] <file>");
|
||||
println!(" uw8 pack [-u/--uncompressed] [-l/--level] <in-file> <out-file>");
|
||||
println!(" uw8 unpack <in-file> <out-file>");
|
||||
println!(" uw8 compile [-d/--debug] <in-file> <out-file>");
|
||||
println!(" uw8 filter-exports <in-wasm> <out-wasm>");
|
||||
Ok(())
|
||||
}
|
||||
@@ -42,6 +43,7 @@ fn main() -> Result<()> {
|
||||
|
||||
fn run(mut args: Arguments) -> Result<()> {
|
||||
let watch_mode = args.contains(["-w", "--watch"]);
|
||||
let timeout: Option<u32> = args.opt_value_from_str(["-t", "--timeout"])?;
|
||||
|
||||
let mut config = Config::default();
|
||||
if args.contains(["-p", "--pack"]) {
|
||||
@@ -67,13 +69,18 @@ fn run(mut args: Arguments) -> Result<()> {
|
||||
|
||||
let mut uw8 = MicroW8::new()?;
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let mut watcher = notify::watcher(tx, Duration::from_millis(100))?;
|
||||
if let Some(timeout) = timeout {
|
||||
uw8.set_timeout(timeout);
|
||||
}
|
||||
|
||||
let mut watcher = FileWatcher::builder();
|
||||
|
||||
if watch_mode {
|
||||
watcher.watch(&filename, notify::RecursiveMode::NonRecursive)?;
|
||||
watcher.add_file(&filename);
|
||||
}
|
||||
|
||||
let watcher = watcher.build()?;
|
||||
|
||||
if let Err(err) = start_cart(&filename, &mut uw8, &config) {
|
||||
eprintln!("Load error: {}", err);
|
||||
if !watch_mode {
|
||||
@@ -82,14 +89,10 @@ fn run(mut args: Arguments) -> Result<()> {
|
||||
}
|
||||
|
||||
while uw8.is_open() {
|
||||
match rx.try_recv() {
|
||||
Ok(DebouncedEvent::Create(_) | DebouncedEvent::Write(_)) => {
|
||||
if let Err(err) = start_cart(&filename, &mut uw8, &config) {
|
||||
eprintln!("Load error: {}", err);
|
||||
}
|
||||
if watcher.poll_changed_file()?.is_some() {
|
||||
if let Err(err) = start_cart(&filename, &mut uw8, &config) {
|
||||
eprintln!("Load error: {}", err);
|
||||
}
|
||||
Err(mpsc::TryRecvError::Disconnected) => bail!("File watcher disconnected"),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if let Err(err) = uw8.run_frame() {
|
||||
@@ -167,6 +170,28 @@ fn pack(mut args: Arguments) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unpack(mut args: Arguments) -> Result<()> {
|
||||
let in_file = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
let out_file = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
|
||||
uw8_tool::unpack_file(&in_file, &out_file).into()
|
||||
}
|
||||
|
||||
fn compile(mut args: Arguments) -> Result<()> {
|
||||
let mut options = curlywas::Options::default();
|
||||
if args.contains(["-d", "--debug"]) {
|
||||
options = options.with_debug();
|
||||
}
|
||||
|
||||
let in_file = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
let out_file = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
|
||||
let module = curlywas::compile_file(in_file, options)?;
|
||||
File::create(out_file)?.write_all(&module)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn filter_exports(mut args: Arguments) -> Result<()> {
|
||||
let in_file = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
let out_file = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::{
|
||||
use wasm_encoder as enc;
|
||||
use wasmparser::{
|
||||
BinaryReader, ExportSectionReader, ExternalKind, FunctionBody, FunctionSectionReader,
|
||||
ImportSectionEntryType, ImportSectionReader, TypeSectionReader,
|
||||
ImportSectionEntryType, ImportSectionReader, TableSectionReader, TypeSectionReader,
|
||||
};
|
||||
|
||||
pub struct PackConfig {
|
||||
@@ -31,7 +31,9 @@ impl PackConfig {
|
||||
|
||||
impl Default for PackConfig {
|
||||
fn default() -> PackConfig {
|
||||
PackConfig { compression: Some(2) }
|
||||
PackConfig {
|
||||
compression: Some(2),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +158,8 @@ struct ParsedModule<'a> {
|
||||
start_section: Option<u32>,
|
||||
function_bodies: Vec<wasmparser::FunctionBody<'a>>,
|
||||
data_section: Option<Section<()>>,
|
||||
table_section: Option<Section<()>>,
|
||||
element_section: Option<Vec<Element>>,
|
||||
}
|
||||
|
||||
impl<'a> ParsedModule<'a> {
|
||||
@@ -170,6 +174,8 @@ impl<'a> ParsedModule<'a> {
|
||||
let mut start_section = None;
|
||||
let mut function_bodies = Vec::new();
|
||||
let mut data_section = None;
|
||||
let mut table_section = None;
|
||||
let mut element_section = None;
|
||||
|
||||
let mut offset = 0;
|
||||
|
||||
@@ -209,6 +215,17 @@ impl<'a> ParsedModule<'a> {
|
||||
Payload::DataSection(_) => {
|
||||
data_section = Some(Section::new(range, ()));
|
||||
}
|
||||
Payload::TableSection(reader) => {
|
||||
validate_table_section(reader)?;
|
||||
table_section = Some(Section::new(range, ()));
|
||||
}
|
||||
Payload::ElementSection(mut reader) => {
|
||||
let mut elements = Vec::with_capacity(reader.get_count() as usize);
|
||||
for _ in 0..reader.get_count() {
|
||||
elements.push(Element::parse(reader.read()?)?);
|
||||
}
|
||||
element_section = Some(elements);
|
||||
}
|
||||
Payload::CodeSectionStart { .. } => (),
|
||||
Payload::CodeSectionEntry(body) => function_bodies.push(body),
|
||||
Payload::CustomSection { .. } => (),
|
||||
@@ -229,6 +246,8 @@ impl<'a> ParsedModule<'a> {
|
||||
start_section,
|
||||
function_bodies,
|
||||
data_section,
|
||||
table_section,
|
||||
element_section,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -405,6 +424,10 @@ impl<'a> ParsedModule<'a> {
|
||||
module.section(&function_section);
|
||||
}
|
||||
|
||||
if let Some(tables) = self.table_section {
|
||||
copy_section(&mut module, &self.data[tables.range.clone()])?;
|
||||
}
|
||||
|
||||
if let Some(ref globals) = self.globals {
|
||||
copy_section(&mut module, &self.data[globals.range.clone()])?;
|
||||
for i in 0..globals.data {
|
||||
@@ -446,6 +469,25 @@ impl<'a> ParsedModule<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(elements) = self.element_section {
|
||||
let mut element_section = wasm_encoder::ElementSection::new();
|
||||
for element in elements {
|
||||
let mut functions = Vec::with_capacity(element.functions.len());
|
||||
for index in element.functions {
|
||||
functions.push(*function_map.get(&index).ok_or_else(|| {
|
||||
anyhow!("Function index {} not found in function map", index)
|
||||
})?);
|
||||
}
|
||||
element_section.active(
|
||||
None,
|
||||
&wasm_encoder::Instruction::I32Const(element.start_index as i32),
|
||||
ValType::FuncRef,
|
||||
wasm_encoder::Elements::Functions(&functions),
|
||||
);
|
||||
}
|
||||
module.section(&element_section);
|
||||
}
|
||||
|
||||
{
|
||||
let mut code_section = enc::CodeSection::new();
|
||||
|
||||
@@ -502,6 +544,19 @@ fn read_type_section(reader: TypeSectionReader) -> Result<Vec<base_module::Funct
|
||||
Ok(function_types)
|
||||
}
|
||||
|
||||
fn validate_table_section(mut reader: TableSectionReader) -> Result<()> {
|
||||
if reader.get_count() != 1 {
|
||||
bail!("Only up to one table supported");
|
||||
}
|
||||
|
||||
let type_ = reader.read()?;
|
||||
if type_.element_type != wasmparser::Type::FuncRef {
|
||||
bail!("Only one funcref table is supported");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Section<T> {
|
||||
range: std::ops::Range<usize>,
|
||||
@@ -579,6 +634,51 @@ impl ImportSection {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Element {
|
||||
start_index: u32,
|
||||
functions: Vec<u32>,
|
||||
}
|
||||
|
||||
impl Element {
|
||||
fn parse(element: wasmparser::Element) -> Result<Element> {
|
||||
if element.ty != wasmparser::Type::FuncRef {
|
||||
bail!("Table element type is not FuncRef");
|
||||
}
|
||||
|
||||
let start_index = if let wasmparser::ElementKind::Active {
|
||||
init_expr,
|
||||
table_index: 0,
|
||||
} = element.kind
|
||||
{
|
||||
let mut init_reader = init_expr.get_operators_reader();
|
||||
if let wasmparser::Operator::I32Const { value: start_index } = init_reader.read()? {
|
||||
start_index as u32
|
||||
} else {
|
||||
bail!("Table element start index is not a integer constant");
|
||||
}
|
||||
} else {
|
||||
bail!("Unsupported table element kind");
|
||||
};
|
||||
|
||||
let mut items_reader = element.items.get_items_reader()?;
|
||||
|
||||
let mut functions = Vec::with_capacity(items_reader.get_count() as usize);
|
||||
for _ in 0..items_reader.get_count() {
|
||||
if let wasmparser::ElementItem::Func(index) = items_reader.read()? {
|
||||
functions.push(index);
|
||||
} else {
|
||||
bail!("Table element item is not a function");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Element {
|
||||
start_index,
|
||||
functions,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FunctionImport {
|
||||
module: String,
|
||||
@@ -678,8 +778,13 @@ fn remap_function(
|
||||
.get(&function_index)
|
||||
.ok_or_else(|| anyhow!("Function index out of range: {}", function_index))?,
|
||||
),
|
||||
De::CallIndirect { .. }
|
||||
| De::ReturnCall { .. }
|
||||
De::CallIndirect { index, table_index } => En::CallIndirect {
|
||||
ty: *type_map
|
||||
.get(&index)
|
||||
.ok_or_else(|| anyhow!("Unknown function type in call indirect"))?,
|
||||
table: table_index,
|
||||
},
|
||||
De::ReturnCall { .. }
|
||||
| De::ReturnCallIndirect { .. }
|
||||
| De::Delegate { .. }
|
||||
| De::CatchAll => todo!(),
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="uw8">
|
||||
<a href="https://exoticorn.github.io/microw8">MicroW8</a> 0.1.0
|
||||
<a href="https://exoticorn.github.io/microw8">MicroW8</a> 0.1.1
|
||||
</div>
|
||||
<div id="centered">
|
||||
<canvas id="screen" width="320" height="240"></canvas>
|
||||
<div id="message"></div>
|
||||
<canvas id="screen" width="320" height="240">
|
||||
</canvas>
|
||||
<div id="timer" hidden="true"></div>
|
||||
<div id="message"></div>
|
||||
<button id="cartButton" style="visibility:hidden">Load cart...</button>
|
||||
</div>
|
||||
<div id="footer">
|
||||
|
||||
@@ -13,6 +13,8 @@ let screen = document.getElementById('screen');
|
||||
let canvasCtx = screen.getContext('2d');
|
||||
let imageData = canvasCtx.createImageData(320, 240);
|
||||
|
||||
let devkitMode;
|
||||
|
||||
let cancelFunction;
|
||||
|
||||
let currentData;
|
||||
@@ -51,9 +53,23 @@ let keyHandler = (e) => {
|
||||
break;
|
||||
case 'KeyR':
|
||||
if (isKeyDown) {
|
||||
runModule(currentData);
|
||||
runModule(currentData, true);
|
||||
}
|
||||
break;
|
||||
case 'F9':
|
||||
if(isKeyDown) {
|
||||
screen.toBlob(blob => {
|
||||
downloadBlob(blob, '.png');
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
break;
|
||||
case 'F10':
|
||||
if(isKeyDown) {
|
||||
recordVideo();
|
||||
}
|
||||
e.preventDefault();
|
||||
break;
|
||||
}
|
||||
|
||||
if (isKeyDown) {
|
||||
@@ -96,7 +112,11 @@ async function runModule(data, keepUrl) {
|
||||
screen.width = screen.width;
|
||||
|
||||
try {
|
||||
let memory = new WebAssembly.Memory({ initial: 4, maximum: 4 });
|
||||
let memSize = { initial: 4 };
|
||||
if(!devkitMode) {
|
||||
memSize.maximum = 4;
|
||||
}
|
||||
let memory = new WebAssembly.Memory({ initial: 4, maximum: devkitMode ? 16 : 4 });
|
||||
let memU8 = U8(memory.buffer);
|
||||
|
||||
let importObject = {
|
||||
@@ -108,7 +128,7 @@ async function runModule(data, keepUrl) {
|
||||
let loader;
|
||||
|
||||
let loadModuleData = (data) => {
|
||||
if (U8(data)[0] != 0) {
|
||||
if (loader && (!devkitMode || U8(data)[0] != 0)) {
|
||||
memU8.set(U8(data));
|
||||
let length = loader.exports.load_uw8(data.byteLength);
|
||||
data = new ArrayBuffer(length);
|
||||
@@ -220,17 +240,75 @@ async function runModule(data, keepUrl) {
|
||||
}
|
||||
}
|
||||
|
||||
function downloadBlob(blob, ext) {
|
||||
let a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(blob);
|
||||
a.download = 'microw8_' + new Date().toISOString() + ext;
|
||||
a.click();
|
||||
URL.revokeObjectURL(a.href);
|
||||
}
|
||||
|
||||
let videoRecorder;
|
||||
let videoStartTime;
|
||||
function recordVideo() {
|
||||
if(videoRecorder) {
|
||||
videoRecorder.stop();
|
||||
videoRecorder = null;
|
||||
return;
|
||||
}
|
||||
|
||||
videoRecorder = new MediaRecorder(screen.captureStream(), {
|
||||
mimeType: 'video/webm',
|
||||
videoBitsPerSecond: 25000000
|
||||
});
|
||||
|
||||
let chunks = [];
|
||||
videoRecorder.ondataavailable = e => {
|
||||
chunks.push(e.data);
|
||||
};
|
||||
|
||||
let timer = document.getElementById("timer");
|
||||
timer.hidden = false;
|
||||
timer.innerText = "00:00";
|
||||
|
||||
videoRecorder.onstop = () => {
|
||||
timer.hidden = true;
|
||||
downloadBlob(new Blob(chunks, {type: 'video/webm'}), '.webm');
|
||||
};
|
||||
|
||||
videoRecorder.start();
|
||||
videoStartTime = Date.now();
|
||||
|
||||
function updateTimer() {
|
||||
if(!videoStartTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
let duration = Math.floor((Date.now() - videoStartTime) / 1000);
|
||||
timer.innerText = Math.floor(duration / 60).toString().padStart(2, '0') + ':' + (duration % 60).toString().padStart(2, '0');
|
||||
|
||||
setTimeout(updateTimer, 1000);
|
||||
}
|
||||
|
||||
setTimeout(updateTimer, 1000);
|
||||
}
|
||||
|
||||
async function runModuleFromURL(url, keepUrl) {
|
||||
let response = await fetch(url);
|
||||
let type = response.headers.get('Content-Type');
|
||||
if(type && type.includes('html')) {
|
||||
throw false;
|
||||
}
|
||||
runModule(await response.arrayBuffer(), keepUrl);
|
||||
runModule(await response.arrayBuffer(), keepUrl || devkitMode);
|
||||
}
|
||||
|
||||
function runModuleFromHash() {
|
||||
let hash = window.location.hash.slice(1);
|
||||
if(hash == 'devkit') {
|
||||
devkitMode = true;
|
||||
return;
|
||||
}
|
||||
devkitMode = false;
|
||||
if (hash.length > 0) {
|
||||
if (hash.startsWith("url=")) {
|
||||
runModuleFromURL(hash.slice(4), true);
|
||||
|
||||
@@ -48,6 +48,16 @@ a:hover {
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
#timer::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
background-color: red;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
#message {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user