mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-20 19:26:43 +01:00
Compare commits
4 Commits
4e18d38538
...
v0.2.1-che
| Author | SHA1 | Date | |
|---|---|---|---|
| a20e569723 | |||
| 8a473cc9b9 | |||
| 4a4beded11 | |||
| 9d629be747 |
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@@ -30,9 +30,9 @@ jobs:
|
|||||||
run: sudo apt-get install -y libxkbcommon-dev libasound2-dev
|
run: sudo apt-get install -y libxkbcommon-dev libasound2-dev
|
||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
- name: Cache build dirs
|
- name: Cache build dirs
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/bin/
|
~/.cargo/bin/
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: cargo build --release --verbose
|
run: cargo build --release --verbose
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: uw8-${{ matrix.build }}
|
name: uw8-${{ matrix.build }}
|
||||||
path: target/release/${{ matrix.exe }}
|
path: target/release/${{ matrix.exe }}
|
||||||
|
|||||||
6
.github/workflows/main.yml
vendored
6
.github/workflows/main.yml
vendored
@@ -8,12 +8,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
- name: build_and_deploy
|
- name: build_and_deploy
|
||||||
uses: shalzz/zola-deploy-action@70a101a14bbdeed13e7a42a9ed06b35c9e9e826e
|
uses: shalzz/zola-deploy-action@v0.14.1
|
||||||
env:
|
env:
|
||||||
# Target branch
|
# Target branch
|
||||||
PAGES_BRANCH: gh-pages
|
PAGES_BRANCH: gh-pages
|
||||||
BUILD_DIR: site
|
BUILD_DIR: site
|
||||||
# Provide personal access token
|
# Provide personal access token
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
TOKEN: $GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
3720
Cargo.lock
generated
3720
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
22
Cargo.toml
22
Cargo.toml
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "uw8"
|
name = "uw8"
|
||||||
version = "0.2.2"
|
version = "0.2.1"
|
||||||
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 = { version = "19.0.1", optional = true }
|
wasmtime = { version = "0.37.0", optional = true }
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
env_logger = "0.11.3"
|
env_logger = "0.9"
|
||||||
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 = "4"
|
||||||
pico-args = "0.5"
|
pico-args = "0.4"
|
||||||
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.2", optional = true }
|
||||||
tokio = { version = "1.37.0", features = ["sync", "rt"], optional = true }
|
tokio = { version = "1.17.0", features = ["sync", "rt"], optional = true }
|
||||||
tokio-stream = { version = "0.1.15", features = ["sync"], optional = true }
|
tokio-stream = { version = "0.1.8", features = ["sync"], optional = true }
|
||||||
webbrowser = { version = "0.8.13", optional = true }
|
webbrowser = { version = "0.6.0", optional = true }
|
||||||
ansi_term = "0.12.1"
|
ansi_term = "0.12.1"
|
||||||
cpal = { version = "0.15.3", optional = true }
|
cpal = { version = "0.14.1", optional = true }
|
||||||
rubato = { version = "0.15.0", optional = true }
|
rubato = { version = "0.11.0", optional = true }
|
||||||
|
|||||||
@@ -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.2.2/microw8-0.2.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.2.2/microw8-0.2.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.2.2/microw8-0.2.2-windows.zip)
|
* [Windows](https://github.com/exoticorn/microw8/releases/download/v0.1.2/microw8-0.1.2-windows.zip)
|
||||||
|
|
||||||
The download includes
|
The download includes
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
include "../include/microw8-api.cwa"
|
|
||||||
|
|
||||||
const SPRITE = 0x20000;
|
|
||||||
|
|
||||||
export fn upd() {
|
|
||||||
cls(0);
|
|
||||||
let t = time() / 2_f;
|
|
||||||
let i: i32;
|
|
||||||
loop spriteLoop {
|
|
||||||
let inline x = sin(t * -1.3 + i as f32 * (3.141 / 30_f)) * 180_f + 160_f;
|
|
||||||
let inline y = sin(t * 1.7 + i as f32 * (3.141 / 40_f)) * 140_f + 120_f;
|
|
||||||
blitSprite(SPRITE, 16, x as i32, y as i32, (i & 3) * 0x200 + 0x100);
|
|
||||||
branch_if (i +:= 1) < 100: spriteLoop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
start fn start() {
|
|
||||||
printChar('OO');
|
|
||||||
circle(8_f, 8_f, 6_f, 75);
|
|
||||||
grabSprite(SPRITE, 16, 0, 0, 0);
|
|
||||||
}
|
|
||||||
@@ -30,13 +30,11 @@ import "env.printInt" fn printInt(i32);
|
|||||||
import "env.setTextColor" fn setTextColor(i32);
|
import "env.setTextColor" fn setTextColor(i32);
|
||||||
import "env.setBackgroundColor" fn setBackgroundColor(i32);
|
import "env.setBackgroundColor" fn setBackgroundColor(i32);
|
||||||
import "env.setCursorPosition" fn setCursorPosition(i32, i32);
|
import "env.setCursorPosition" fn setCursorPosition(i32, i32);
|
||||||
import "env.rectangleOutline" fn rectangleOutline(f32, f32, f32, f32, i32);
|
import "env.rectangle_outline" fn rectangle_outline(f32, f32, f32, f32, i32);
|
||||||
import "env.circleOutline" fn circleOutline(f32, f32, f32, i32);
|
import "env.circle_outline" fn circle_outline(f32, f32, f32, i32);
|
||||||
import "env.exp" fn exp(f32) -> f32;
|
import "env.exp" fn exp(f32) -> f32;
|
||||||
import "env.playNote" fn playNote(i32, i32);
|
import "env.playNote" fn playNote(i32, i32);
|
||||||
import "env.sndGes" fn sndGes(i32) -> f32;
|
import "env.sndGes" fn sndGes(i32) -> f32;
|
||||||
import "env.blitSprite" fn blitSprite(i32, i32, i32, i32, i32);
|
|
||||||
import "env.grabSprite" fn grabSprite(i32, i32, i32, i32, i32);
|
|
||||||
|
|
||||||
const TIME_MS = 0x40;
|
const TIME_MS = 0x40;
|
||||||
const GAMEPAD = 0x44;
|
const GAMEPAD = 0x44;
|
||||||
|
|||||||
@@ -30,13 +30,11 @@
|
|||||||
(import "env" "setTextColor" (func $setTextColor (param i32)))
|
(import "env" "setTextColor" (func $setTextColor (param i32)))
|
||||||
(import "env" "setBackgroundColor" (func $setBackgroundColor (param i32)))
|
(import "env" "setBackgroundColor" (func $setBackgroundColor (param i32)))
|
||||||
(import "env" "setCursorPosition" (func $setCursorPosition (param i32) (param i32)))
|
(import "env" "setCursorPosition" (func $setCursorPosition (param i32) (param i32)))
|
||||||
(import "env" "rectangleOutline" (func $rectangleOutline (param f32) (param f32) (param f32) (param f32) (param i32)))
|
(import "env" "rectangle_outline" (func $rectangle_outline (param f32) (param f32) (param f32) (param f32) (param i32)))
|
||||||
(import "env" "circleOutline" (func $circleOutline (param f32) (param f32) (param f32) (param i32)))
|
(import "env" "circle_outline" (func $circle_outline (param f32) (param f32) (param f32) (param i32)))
|
||||||
(import "env" "exp" (func $exp (param f32) (result f32)))
|
(import "env" "exp" (func $exp (param f32) (result f32)))
|
||||||
(import "env" "playNote" (func $playNote (param i32) (param i32)))
|
(import "env" "playNote" (func $playNote (param i32) (param i32)))
|
||||||
(import "env" "sndGes" (func $sndGes (param i32) (result f32)))
|
(import "env" "sndGes" (func $sndGes (param i32) (result f32)))
|
||||||
(import "env" "blitSprite" (func $blitSprite (param i32) (param i32) (param i32) (param i32) (param i32)))
|
|
||||||
(import "env" "grabSprite" (func $grabSprite (param i32) (param i32) (param i32) (param i32) (param i32)))
|
|
||||||
|
|
||||||
;; to use defines, include this file with a preprocessor
|
;; to use defines, include this file with a preprocessor
|
||||||
;; like gpp (https://logological.org/gpp).
|
;; like gpp (https://logological.org/gpp).
|
||||||
|
|||||||
180
platform/Cargo.lock
generated
180
platform/Cargo.lock
generated
@@ -110,9 +110,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.3.2"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
@@ -151,39 +151,32 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"ariadne",
|
"ariadne",
|
||||||
"chumsky",
|
"chumsky",
|
||||||
"pico-args 0.4.2",
|
"pico-args",
|
||||||
"wasm-encoder 0.10.0",
|
"wasm-encoder 0.10.0",
|
||||||
"wasmparser 0.83.0",
|
"wasmparser 0.83.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fallible_collections"
|
name = "fallible_collections"
|
||||||
version = "0.4.6"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f57ccc32870366ae684be48b32a1a2e196f98a42a9b4361fe77e13fd4a34755"
|
checksum = "52db5973b6a19247baf19b30f41c23a1bfffc2e9ce0a5db2f60e3cd5dc8895f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.25"
|
version = "1.0.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
|
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
"libc",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[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]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@@ -197,9 +190,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.11.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.7.6",
|
"ahash 0.7.6",
|
||||||
]
|
]
|
||||||
@@ -219,26 +212,6 @@ version = "2.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
|
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "idna"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-bidi",
|
|
||||||
"unicode-normalization",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "indexmap"
|
|
||||||
version = "1.9.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"hashbrown",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -251,25 +224,18 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
|
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lexopt"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "478ee9e62aaeaf5b140bd4138753d1f109765488581444218d3ddda43234f3e8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.139"
|
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 = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lodepng"
|
name = "lodepng"
|
||||||
version = "3.7.2"
|
version = "3.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0ad39f75bbaa4b10bb6f2316543632a8046a5bcf9c785488d79720b21f044f8"
|
checksum = "24844d5c0b922ddd52fb5bf0964a4c7f8e799a946ec01bb463771eb04fc1a323"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
|
||||||
"fallible_collections",
|
"fallible_collections",
|
||||||
"flate2",
|
"flate2",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -287,11 +253,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.6.2"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -321,24 +288,12 @@ dependencies = [
|
|||||||
"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"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
|
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pico-args"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "platform"
|
name = "platform"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -375,9 +330,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rgb"
|
name = "rgb"
|
||||||
version = "0.8.34"
|
version = "0.8.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3603b7d71ca82644f79b5a06d1220e9a58ede60bd32255f698cb1af8838b8db3"
|
checksum = "9a374af9a0e5fdcdd98c1c7b64f05004f9ea2555b6c75f211daa81268a3c50f1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
@@ -402,26 +357,6 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "1.0.38"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "1.0.38"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.43"
|
version = "0.1.43"
|
||||||
@@ -441,36 +376,6 @@ dependencies = [
|
|||||||
"crunchy",
|
"crunchy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[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.9.0"
|
version = "1.9.0"
|
||||||
@@ -485,24 +390,13 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "upkr"
|
name = "upkr"
|
||||||
version = "0.2.1"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/exoticorn/upkr.git?rev=080db40d0088bbee2bdf3c5c75288ac7853d6b7a#080db40d0088bbee2bdf3c5c75288ac7853d6b7a"
|
source = "git+https://github.com/exoticorn/upkr.git?rev=d93aec186c9fb91d962c488682a2db125c61306c#d93aec186c9fb91d962c488682a2db125c61306c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cdivsufsort",
|
"cdivsufsort",
|
||||||
"lexopt",
|
"pbr",
|
||||||
"thiserror",
|
"pico-args",
|
||||||
]
|
|
||||||
|
|
||||||
[[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]]
|
||||||
@@ -511,11 +405,11 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"pbr",
|
"pbr",
|
||||||
"pico-args 0.5.0",
|
"pico-args",
|
||||||
"upkr",
|
"upkr",
|
||||||
"walrus",
|
"walrus",
|
||||||
"wasm-encoder 0.22.0",
|
"wasm-encoder 0.8.0",
|
||||||
"wasmparser 0.99.0",
|
"wasmparser 0.81.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -558,18 +452,18 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-encoder"
|
name = "wasm-encoder"
|
||||||
version = "0.10.0"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aa9d9bf45fc46f71c407837c9b30b1e874197f2dc357588430b21e5017d290ab"
|
checksum = "db0c351632e46cc06a58a696a6c11e4cf90cad4b9f8f07a0b59128d616c29bb0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"leb128",
|
"leb128",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-encoder"
|
name = "wasm-encoder"
|
||||||
version = "0.22.0"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef126be0e14bdf355ac1a8b41afc89195289e5c7179f80118e3abddb472f0810"
|
checksum = "aa9d9bf45fc46f71c407837c9b30b1e874197f2dc357588430b21e5017d290ab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"leb128",
|
"leb128",
|
||||||
]
|
]
|
||||||
@@ -582,19 +476,15 @@ checksum = "b35c86d22e720a07d954ebbed772d01180501afe7d03d464f413bb5f8914a8d6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.83.0"
|
version = "0.81.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a"
|
checksum = "98930446519f63d00a836efdc22f67766ceae8dbcc1571379f2bcabc6b2b9abc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.99.0"
|
version = "0.83.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ef3b717afc67f848f412d4f02c127dd3e35a0eecd58c684580414df4fde01d3"
|
checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a"
|
||||||
dependencies = [
|
|
||||||
"indexmap",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ edition = "2021"
|
|||||||
curlywas = { git="https://github.com/exoticorn/curlywas.git", rev="0e7ea50" }
|
curlywas = { git="https://github.com/exoticorn/curlywas.git", rev="0e7ea50" }
|
||||||
uw8-tool = { path="../uw8-tool" }
|
uw8-tool = { path="../uw8-tool" }
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
lodepng = "3.7.2"
|
lodepng = "3.4"
|
||||||
Binary file not shown.
Binary file not shown.
@@ -171,7 +171,7 @@ export fn rectangle(x: f32, y: f32, w: f32, h: f32, col: i32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn rectangleOutline(x: f32, y: f32, w: f32, h: f32, col: i32) {
|
export fn rectangle_outline(x: f32, y: f32, w: f32, h: f32, col: i32) {
|
||||||
let xl = nearest(x) as i32;
|
let xl = nearest(x) as i32;
|
||||||
let xr = nearest(x + w) as i32;
|
let xr = nearest(x + w) as i32;
|
||||||
let yt = nearest(y) as i32;
|
let yt = nearest(y) as i32;
|
||||||
@@ -212,7 +212,7 @@ export fn circle(cx: f32, cy: f32, radius: f32, col: i32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn circleOutline(cx: f32, cy: f32, radius: f32, col: i32) {
|
export fn circle_outline(cx: f32, cy: f32, radius: f32, col: i32) {
|
||||||
let prev_w: f32;
|
let prev_w: f32;
|
||||||
let y = clamp(nearest(cy - radius) as i32, -1, 241);
|
let y = clamp(nearest(cy - radius) as i32, -1, 241);
|
||||||
let maxY = clamp(nearest(cy + radius) as i32, -1, 241);
|
let maxY = clamp(nearest(cy + radius) as i32, -1, 241);
|
||||||
@@ -352,92 +352,6 @@ export fn line(x1: f32, y1: f32, x2: f32, y2: f32, col: i32) {
|
|||||||
setPixel(i32.trunc_sat_f32_s(x1 + f * dx), i32.trunc_sat_f32_s(y1 + f * dy), col);
|
setPixel(i32.trunc_sat_f32_s(x1 + f * dx), i32.trunc_sat_f32_s(y1 + f * dy), col);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn blitSprite(sprite: i32, size: i32, x: i32, y: i32, control: i32) {
|
|
||||||
let lazy width = size & 65535;
|
|
||||||
let lazy height = select(size >> 16, size >> 16, width);
|
|
||||||
|
|
||||||
let lazy x0 = select(x < 0, -x, 0);
|
|
||||||
let lazy x1 = select(x + width > 320, 320 - x, width);
|
|
||||||
let lazy y0 = select(y < 0, -y, 0);
|
|
||||||
let lazy y1 = select(y + height > 240, 240 - y, height);
|
|
||||||
|
|
||||||
let lazy numRows = y1 - y0;
|
|
||||||
let lazy numCols = x1 - x0;
|
|
||||||
if numRows <= 0 | numCols <= 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let trans = (control & 511) - 256;
|
|
||||||
let lazy flip_x = 1 - ((control >> 8) & 2);
|
|
||||||
let lazy flip_y = 1 - ((control >> 9) & 2);
|
|
||||||
if flip_x < 0 {
|
|
||||||
sprite += width - 1;
|
|
||||||
}
|
|
||||||
if flip_y < 0 {
|
|
||||||
sprite += (height - 1) * width;
|
|
||||||
}
|
|
||||||
|
|
||||||
let spriteRow = sprite + x0 * flip_x + y0 * flip_y * width;
|
|
||||||
let screenRow = x + x0 + (y + y0) * 320;
|
|
||||||
|
|
||||||
loop yloop {
|
|
||||||
let lx = 0;
|
|
||||||
loop xloop {
|
|
||||||
let lazy col = (spriteRow + lx * flip_x)?0;
|
|
||||||
if col != trans {
|
|
||||||
(screenRow + lx)?120 = col;
|
|
||||||
}
|
|
||||||
branch_if (lx +:= 1) < numCols: xloop;
|
|
||||||
}
|
|
||||||
spriteRow += width * flip_y;
|
|
||||||
screenRow += 320;
|
|
||||||
branch_if numRows -:= 1: yloop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn grabSprite(sprite: i32, size: i32, x: i32, y: i32, control: i32) {
|
|
||||||
let lazy width = size & 65535;
|
|
||||||
let lazy height = select(size >> 16, size >> 16, width);
|
|
||||||
|
|
||||||
let lazy x0 = select(x < 0, -x, 0);
|
|
||||||
let lazy x1 = select(x + width > 320, 320 - x, width);
|
|
||||||
let lazy y0 = select(y < 0, -y, 0);
|
|
||||||
let lazy y1 = select(y + height > 240, 240 - y, height);
|
|
||||||
|
|
||||||
let lazy numRows = y1 - y0;
|
|
||||||
let lazy numCols = x1 - x0;
|
|
||||||
if numRows <= 0 | numCols <= 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let trans = (control & 511) - 256;
|
|
||||||
let lazy flip_x = 1 - ((control >> 8) & 2);
|
|
||||||
let lazy flip_y = 1 - ((control >> 9) & 2);
|
|
||||||
if flip_x < 0 {
|
|
||||||
sprite += width - 1;
|
|
||||||
}
|
|
||||||
if flip_y < 0 {
|
|
||||||
sprite += (height - 1) * width;
|
|
||||||
}
|
|
||||||
|
|
||||||
let spriteRow = sprite + x0 * flip_x + y0 * flip_y * width;
|
|
||||||
let screenRow = x + x0 + (y + y0) * 320;
|
|
||||||
|
|
||||||
loop yloop {
|
|
||||||
let lx = 0;
|
|
||||||
loop xloop {
|
|
||||||
let lazy col = (screenRow + lx)?120;
|
|
||||||
if col != trans {
|
|
||||||
(spriteRow + lx * flip_x)?0 = col;
|
|
||||||
}
|
|
||||||
branch_if (lx +:= 1) < numCols: xloop;
|
|
||||||
}
|
|
||||||
spriteRow += width * flip_y;
|
|
||||||
screenRow += 320;
|
|
||||||
branch_if numRows -:= 1: yloop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
// TEXT //
|
// TEXT //
|
||||||
//////////
|
//////////
|
||||||
@@ -447,7 +361,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 {
|
||||||
@@ -459,8 +372,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;
|
||||||
@@ -494,9 +405,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;
|
||||||
@@ -506,34 +417,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;
|
||||||
}
|
}
|
||||||
@@ -565,12 +476,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);
|
||||||
@@ -593,7 +498,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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,28 +507,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) {
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ The initial motivation behind MicroW8 was to explore whether there was a way to
|
|||||||
* Memory: 256KB
|
* Memory: 256KB
|
||||||
* Gamepad input (D-Pad + 4 Buttons)
|
* Gamepad input (D-Pad + 4 Buttons)
|
||||||
|
|
||||||
For detailed [documentation see here](docs).
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
* [Skip Ahead](v0.2.0#AgVfq24KI2Ok2o8qVtPYj27fSuGnfeSKgbOkIOsaEQMov8TDYQ6UjdjwkZrYcM1i9alo4/+Bhm1PRFEa0YHJlJAk/PGoc2K41rejv9ZSqJqIHNjr7cappqhOR2jT+jk+0b0+U6hO+geRCTP2aufWs7L+f/Z27NFY8LKlqPSv+C6Rd6+ohoKi6sYl5Kcrlf1cyTinV7jTTnmbcXWVDBA5rRKxAGMUTDS8rHxqSztRITOaQVP1pSdYgi/BDdOJOxSOIkeaId84S+Ycls5na7EgwSfVIpgqF+tcfkUecb8t2mQrXA7pyKrh/wzHn5N6Oe5aOgmzY2YpTIct) (249 bytes): A port of my [TIC-80 256byte game](http://tic80.com/play?cart=1735) from LoveByte'21, now with sound
|
* [Skip Ahead](v0.2.0#AgVfq24KI2Ok2o8qVtPYj27fSuGnfeSKgbOkIOsaEQMov8TDYQ6UjdjwkZrYcM1i9alo4/+Bhm1PRFEa0YHJlJAk/PGoc2K41rejv9ZSqJqIHNjr7cappqhOR2jT+jk+0b0+U6hO+geRCTP2aufWs7L+f/Z27NFY8LKlqPSv+C6Rd6+ohoKi6sYl5Kcrlf1cyTinV7jTTnmbcXWVDBA5rRKxAGMUTDS8rHxqSztRITOaQVP1pSdYgi/BDdOJOxSOIkeaId84S+Ycls5na7EgwSfVIpgqF+tcfkUecb8t2mQrXA7pyKrh/wzHn5N6Oe5aOgmzY2YpTIct) (249 bytes): A port of my [TIC-80 256byte game](http://tic80.com/play?cart=1735) from LoveByte'21, now with sound
|
||||||
* [Fireworks](v0.2.0#AgwvgP+M59snqjl4CMKw5sqm1Zw9yJCbSviMjeLUdHus2a3yl/a99+uiBeqZgP/2jqSjrLjRk73COMM6OSLpsxK8ugT1kuk/q4hQUqqPpGozHoa0laulzGGcahzdfdJsYaK1sIdeIYS9M5PnJx/Wk9H+PvWEPy2Zvv7I6IW7Fg==) (127 bytes): Some fireworks to welcome 2022.
|
* [Fireworks](v0.2.0#AgwvgP+M59snqjl4CMKw5sqm1Zw9yJCbSviMjeLUdHus2a3yl/a99+uiBeqZgP/2jqSjrLjRk73COMM6OSLpsxK8ugT1kuk/q4hQUqqPpGozHoa0laulzGGcahzdfdJsYaK1sIdeIYS9M5PnJx/Wk9H+PvWEPy2Zvv7I6IW7Fg==) (127 bytes): Some fireworks to welcome 2022.
|
||||||
@@ -31,20 +29,6 @@ Examplers for older versions:
|
|||||||
|
|
||||||
## Versions
|
## Versions
|
||||||
|
|
||||||
### 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
|
### v0.2.1
|
||||||
|
|
||||||
* [Web runtime](v0.2.1)
|
* [Web runtime](v0.2.1)
|
||||||
|
|||||||
@@ -5,16 +5,13 @@ 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.
|
||||||
|
|
||||||
The memory has to be imported as `env` `memory` and has a maximum size of 256kb (4 pages).
|
The memory has to be imported as `env` `memory` and has a maximum size of 256kb (4 pages).
|
||||||
|
|
||||||
If the module exports a function called `start`, it will be called once after the module is
|
|
||||||
loaded.
|
|
||||||
|
|
||||||
# Memory map
|
# Memory map
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -146,13 +143,13 @@ Fills the circle at `cx, cy` and with `radius` with the given color index.
|
|||||||
|
|
||||||
(Sets all pixels where the pixel center lies inside the circle.)
|
(Sets all pixels where the pixel center lies inside the circle.)
|
||||||
|
|
||||||
### fn rectangleOutline(x: f32, y: f32, w: f32, h: f32, color: i32)
|
### fn rectangle_outline(x: f32, y: f32, w: f32, h: f32, color: i32)
|
||||||
|
|
||||||
Draws a one pixel outline on the inside of the given rectangle.
|
Draws a one pixel outline on the inside of the given rectangle.
|
||||||
|
|
||||||
(Draws the outermost pixels that are still inside the rectangle area.)
|
(Draws the outermost pixels that are still inside the rectangle area.)
|
||||||
|
|
||||||
### fn circleOutline(cx: f32, cy: f32, radius: f32, color: i32)
|
### fn circle_outline(cx: f32, cy: f32, radius: f32, color: i32)
|
||||||
|
|
||||||
Draws a one pixel outline on the inside of the given circle.
|
Draws a one pixel outline on the inside of the given circle.
|
||||||
|
|
||||||
@@ -162,21 +159,6 @@ Draws a one pixel outline on the inside of the given circle.
|
|||||||
|
|
||||||
Draws a line from `x1,y1` to `x2,y2` in the given color index.
|
Draws a line from `x1,y1` to `x2,y2` in the given color index.
|
||||||
|
|
||||||
### fn blitSprite(spriteData: i32, size: i32, x: i32, y: i32, control: i32)
|
|
||||||
|
|
||||||
Copies the pixel data at `spriteData` onto the screen at `x`, `y`. The size of the sprite is passed as `width | (height << 16)`.
|
|
||||||
If the height is given as 0, the sprite is is treated as square (width x width).
|
|
||||||
|
|
||||||
The control parameter controls masking and flipping of the sprite:
|
|
||||||
* bits 0-7: color mask index
|
|
||||||
* bit 8: switch on masked blit (pixel with color mask index are treated as transparent)
|
|
||||||
* bit 9: flip sprite x
|
|
||||||
* bit 10: flip sprite y
|
|
||||||
|
|
||||||
### fn grabSprite(spriteData: i32, size: i32, x: i32, y: i32, control: i32)
|
|
||||||
|
|
||||||
Copies the pixel data on the screen at `x`, `y` to `spriteData`. Parameters are exactly the same as `blitSprite`.
|
|
||||||
|
|
||||||
## Input
|
## Input
|
||||||
|
|
||||||
MicroW8 provides input from a gamepad with one D-Pad and 4 buttons, or a keyboard emulation thereof.
|
MicroW8 provides input from a gamepad with one D-Pad and 4 buttons, or a keyboard emulation thereof.
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -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.2.2">
|
<a href="v0.2.1">
|
||||||
<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>
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use notify_debouncer_mini::{
|
use notify::{DebouncedEvent, RecommendedWatcher, Watcher};
|
||||||
new_debouncer,
|
|
||||||
notify::{self, RecommendedWatcher},
|
|
||||||
DebouncedEvent, DebouncedEventKind, Debouncer,
|
|
||||||
};
|
|
||||||
use std::{collections::BTreeSet, path::PathBuf, sync::mpsc, time::Duration};
|
use std::{collections::BTreeSet, path::PathBuf, sync::mpsc, time::Duration};
|
||||||
|
|
||||||
pub struct FileWatcher {
|
pub struct FileWatcher {
|
||||||
debouncer: Debouncer<RecommendedWatcher>,
|
watcher: RecommendedWatcher,
|
||||||
watched_files: BTreeSet<PathBuf>,
|
watched_files: BTreeSet<PathBuf>,
|
||||||
directories: BTreeSet<PathBuf>,
|
directories: BTreeSet<PathBuf>,
|
||||||
rx: mpsc::Receiver<DebouncedEvent>,
|
rx: mpsc::Receiver<DebouncedEvent>,
|
||||||
@@ -16,18 +12,9 @@ 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 watcher = notify::watcher(tx, Duration::from_millis(100))?;
|
||||||
Ok(events) => {
|
|
||||||
for event in events {
|
|
||||||
let _ = tx.send(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("Error watching for file changes: {err}");
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
Ok(FileWatcher {
|
Ok(FileWatcher {
|
||||||
debouncer,
|
watcher,
|
||||||
watched_files: BTreeSet::new(),
|
watched_files: BTreeSet::new(),
|
||||||
directories: BTreeSet::new(),
|
directories: BTreeSet::new(),
|
||||||
rx,
|
rx,
|
||||||
@@ -39,8 +26,7 @@ impl FileWatcher {
|
|||||||
let parent = path.parent().ok_or_else(|| anyhow!("File has no parent"))?;
|
let parent = path.parent().ok_or_else(|| anyhow!("File has no parent"))?;
|
||||||
|
|
||||||
if !self.directories.contains(parent) {
|
if !self.directories.contains(parent) {
|
||||||
self.debouncer
|
self.watcher
|
||||||
.watcher()
|
|
||||||
.watch(parent, notify::RecursiveMode::NonRecursive)?;
|
.watch(parent, notify::RecursiveMode::NonRecursive)?;
|
||||||
self.directories.insert(parent.to_path_buf());
|
self.directories.insert(parent.to_path_buf());
|
||||||
}
|
}
|
||||||
@@ -50,18 +36,16 @@ impl FileWatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_changed_file(&self) -> Result<Option<PathBuf>> {
|
pub fn poll_changed_file(&self) -> Result<Option<PathBuf>> {
|
||||||
match self.rx.try_recv() {
|
let event = self.rx.try_recv();
|
||||||
Ok(event) => match event.kind {
|
match event {
|
||||||
DebouncedEventKind::Any => {
|
Ok(DebouncedEvent::Create(path) | DebouncedEvent::Write(path)) => {
|
||||||
let handle = same_file::Handle::from_path(&event.path)?;
|
let handle = same_file::Handle::from_path(&path)?;
|
||||||
for file in &self.watched_files {
|
for file in &self.watched_files {
|
||||||
if handle == same_file::Handle::from_path(file)? {
|
if handle == same_file::Handle::from_path(file)? {
|
||||||
return Ok(Some(event.path));
|
return Ok(Some(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
},
|
|
||||||
Err(mpsc::TryRecvError::Disconnected) => bail!("File watcher disconnected"),
|
Err(mpsc::TryRecvError::Disconnected) => bail!("File watcher disconnected"),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ 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 {
|
||||||
@@ -90,10 +90,10 @@ 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")?;
|
||||||
|
|
||||||
let platform_data = include_bytes!("../platform/bin/platform.uw8");
|
let platform_data = include_bytes!("../platform/bin/platform.uw8");
|
||||||
memory.data_mut(&mut store)[..platform_data.len()].copy_from_slice(platform_data);
|
memory.data_mut(&mut store)[..platform_data.len()].copy_from_slice(platform_data);
|
||||||
@@ -131,10 +131,10 @@ impl super::Runtime for MicroW8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let instance = linker.instantiate(&mut store, &module)?;
|
let instance = linker.instantiate(&mut store, &module)?;
|
||||||
let end_frame = platform_instance.get_typed_func::<(), ()>(&mut store, "endFrame")?;
|
let end_frame = platform_instance.get_typed_func::<(), (), _>(&mut store, "endFrame")?;
|
||||||
let update = instance.get_typed_func::<(), ()>(&mut store, "upd").ok();
|
let update = instance.get_typed_func::<(), (), _>(&mut store, "upd").ok();
|
||||||
|
|
||||||
if let Some(start) = instance.get_typed_func::<(), ()>(&mut store, "start").ok() {
|
if let Some(start) = instance.get_typed_func::<(), (), _>(&mut store, "start").ok() {
|
||||||
start.call(&mut store, ())?;
|
start.call(&mut store, ())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,12 +255,15 @@ fn add_native_functions(
|
|||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
for i in 0..16 {
|
for i in 0..16 {
|
||||||
let global = wasmtime::Global::new(
|
linker.define(
|
||||||
|
"env",
|
||||||
|
&format!("g_reserved{}", i),
|
||||||
|
wasmtime::Global::new(
|
||||||
&mut *store,
|
&mut *store,
|
||||||
GlobalType::new(ValType::I32, Mutability::Const),
|
GlobalType::new(ValType::I32, Mutability::Const),
|
||||||
0.into(),
|
0.into(),
|
||||||
|
)?,
|
||||||
)?;
|
)?;
|
||||||
linker.define(&store, "env", &format!("g_reserved{}", i), global)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -273,18 +276,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)
|
||||||
@@ -311,15 +310,15 @@ 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)?;
|
||||||
let instance = linker.instantiate(&mut store, module)?;
|
let instance = linker.instantiate(&mut store, module)?;
|
||||||
|
|
||||||
let snd = instance
|
let snd = instance
|
||||||
.get_typed_func::<(i32,), f32>(&mut store, "snd")
|
.get_typed_func::<(i32,), f32, _>(&mut store, "snd")
|
||||||
.or_else(|_| platform_instance.get_typed_func::<(i32,), f32>(&mut store, "sndGes"))?;
|
.or_else(|_| platform_instance.get_typed_func::<(i32,), f32, _>(&mut store, "sndGes"))?;
|
||||||
|
|
||||||
let host = cpal::default_host();
|
let host = cpal::default_host();
|
||||||
let device = host
|
let device = host
|
||||||
@@ -328,26 +327,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.channels() == 2
|
config.channels() == 2 && config.sample_format() == cpal::SampleFormat::F32
|
||||||
&& (config.sample_format() == cpal::SampleFormat::F32
|
|
||||||
|| config.sample_format() == cpal::SampleFormat::I16)
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
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 prio = if rate >= 44100 {
|
if rate >= 44100 {
|
||||||
rate - 44100
|
rate - 44100
|
||||||
} else {
|
} else {
|
||||||
(44100 - rate) * 1000
|
(44100 - rate) * 1000
|
||||||
};
|
}
|
||||||
prio + (config.sample_format() == cpal::SampleFormat::I16) as u32
|
|
||||||
});
|
});
|
||||||
let config = configs
|
let config = configs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| anyhow!("Could not find float or 16bit signed output config"))?;
|
.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());
|
||||||
@@ -358,7 +354,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 config = cpal::StreamConfig {
|
let config = cpal::StreamConfig {
|
||||||
buffer_size,
|
buffer_size,
|
||||||
..config.config()
|
..config.config()
|
||||||
@@ -378,8 +373,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,
|
||||||
@@ -391,8 +386,9 @@ 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,
|
||||||
|
move |mut outer_buffer: &mut [f32], _| {
|
||||||
let mut first_update = true;
|
let mut first_update = true;
|
||||||
while let Ok(update) = rx.try_recv() {
|
while let Ok(update) = rx.try_recv() {
|
||||||
if first_update {
|
if first_update {
|
||||||
@@ -465,7 +461,8 @@ fn init_sound(
|
|||||||
resampler.output_index = 0;
|
resampler.output_index = 0;
|
||||||
} else {
|
} else {
|
||||||
for i in 0..copy_size {
|
for i in 0..copy_size {
|
||||||
buffer[i * 2] = resampler.output_buffers[0][resampler.output_index + i];
|
buffer[i * 2] =
|
||||||
|
resampler.output_buffers[0][resampler.output_index + i];
|
||||||
buffer[i * 2 + 1] =
|
buffer[i * 2 + 1] =
|
||||||
resampler.output_buffers[1][resampler.output_index + i];
|
resampler.output_buffers[1][resampler.output_index + i];
|
||||||
}
|
}
|
||||||
@@ -481,40 +478,14 @@ fn init_sound(
|
|||||||
}
|
}
|
||||||
|
|
||||||
outer_buffer = &mut outer_buffer[step_size..];
|
outer_buffer = &mut outer_buffer[step_size..];
|
||||||
current_time = current_time.wrapping_add((step_size * 500 / sample_rate).max(1) as i32);
|
current_time =
|
||||||
}
|
current_time.wrapping_add((step_size * 500 / sample_rate).max(1) as i32);
|
||||||
};
|
|
||||||
let stream = if sample_format == cpal::SampleFormat::F32 {
|
|
||||||
device.build_output_stream(
|
|
||||||
&config,
|
|
||||||
callback,
|
|
||||||
move |err| {
|
|
||||||
dbg!(err);
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
)?
|
|
||||||
} else {
|
|
||||||
device.build_output_stream(
|
|
||||||
&config,
|
|
||||||
move |mut buffer: &mut [i16], info| {
|
|
||||||
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, info);
|
|
||||||
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..];
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move |err| {
|
move |err| {
|
||||||
dbg!(err);
|
dbg!(err);
|
||||||
},
|
},
|
||||||
None,
|
)?;
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Uw8Sound { stream, tx })
|
Ok(Uw8Sound { stream, tx })
|
||||||
}
|
}
|
||||||
|
|||||||
13
test.cwa
Normal file
13
test.cwa
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import "env.memory" memory(4);
|
||||||
|
import "env.printString" fn print(i32);
|
||||||
|
|
||||||
|
export fn upd() {
|
||||||
|
}
|
||||||
|
|
||||||
|
start fn start() {
|
||||||
|
print(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
data 0 {
|
||||||
|
"Press " i8(0xe0) " and " i8(0xe1) " to adjust, " i8(0xcc) " to commit." i8(0)
|
||||||
|
}
|
||||||
@@ -2,18 +2,17 @@ import "env.memory" memory(4);
|
|||||||
import "env.pow" fn pow(f32, f32) -> f32;
|
import "env.pow" fn pow(f32, f32) -> f32;
|
||||||
import "env.sin" fn sin(f32) -> f32;
|
import "env.sin" fn sin(f32) -> f32;
|
||||||
import "env.cls" fn cls(i32);
|
import "env.cls" fn cls(i32);
|
||||||
import "env.exp" fn exp(f32) -> f32;
|
|
||||||
import "env.rectangle" fn rectangle(f32, f32, f32, f32, i32);
|
import "env.rectangle" fn rectangle(f32, f32, f32, f32, i32);
|
||||||
|
|
||||||
include "../platform/src/ges.cwa"
|
include "../platform/src/ges.cwa"
|
||||||
|
|
||||||
export fn snd(t: i32) -> f32 {
|
export fn snd(t: i32) -> f32 {
|
||||||
sndGes(t)
|
gesSnd(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn upd() {
|
export fn upd() {
|
||||||
80?0 = 32!32 / 200 & 2 | 0x41;
|
80?0 = 32!32 / 200 & 2 | 0x41;
|
||||||
80?3 = (32!32 / 400)%8*12/7 + 40;
|
80?3 = (32!32 / 400)%7*12/7 + 40;
|
||||||
let pulse = (32!32 * 256 / 2000) & 511;
|
let pulse = (32!32 * 256 / 2000) & 511;
|
||||||
if pulse >= 256 {
|
if pulse >= 256 {
|
||||||
pulse = 511 - pulse;
|
pulse = 511 - pulse;
|
||||||
|
|||||||
134
uw8-tool/Cargo.lock
generated
134
uw8-tool/Cargo.lock
generated
@@ -56,21 +56,6 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "form_urlencoded"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
|
||||||
dependencies = [
|
|
||||||
"percent-encoding",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.12.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -86,26 +71,6 @@ version = "2.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
|
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "idna"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-bidi",
|
|
||||||
"unicode-normalization",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "indexmap"
|
|
||||||
version = "1.9.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"hashbrown",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -118,12 +83,6 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
|
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lexopt"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "478ee9e62aaeaf5b140bd4138753d1f109765488581444218d3ddda43234f3e8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.112"
|
version = "0.2.112"
|
||||||
@@ -160,17 +119,11 @@ dependencies = [
|
|||||||
"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.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
@@ -210,26 +163,6 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "1.0.38"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "1.0.38"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.44"
|
version = "0.1.44"
|
||||||
@@ -241,36 +174,6 @@ dependencies = [
|
|||||||
"winapi",
|
"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.8.0"
|
version = "1.8.0"
|
||||||
@@ -285,24 +188,13 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "upkr"
|
name = "upkr"
|
||||||
version = "0.2.1"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/exoticorn/upkr.git?rev=080db40d0088bbee2bdf3c5c75288ac7853d6b7a#080db40d0088bbee2bdf3c5c75288ac7853d6b7a"
|
source = "git+https://github.com/exoticorn/upkr.git?rev=d93aec186c9fb91d962c488682a2db125c61306c#d93aec186c9fb91d962c488682a2db125c61306c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cdivsufsort",
|
"cdivsufsort",
|
||||||
"lexopt",
|
"pbr",
|
||||||
"thiserror",
|
"pico-args",
|
||||||
]
|
|
||||||
|
|
||||||
[[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]]
|
||||||
@@ -315,7 +207,7 @@ dependencies = [
|
|||||||
"upkr",
|
"upkr",
|
||||||
"walrus",
|
"walrus",
|
||||||
"wasm-encoder",
|
"wasm-encoder",
|
||||||
"wasmparser 0.99.0",
|
"wasmparser 0.81.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -352,9 +244,9 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-encoder"
|
name = "wasm-encoder"
|
||||||
version = "0.22.0"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef126be0e14bdf355ac1a8b41afc89195289e5c7179f80118e3abddb472f0810"
|
checksum = "db0c351632e46cc06a58a696a6c11e4cf90cad4b9f8f07a0b59128d616c29bb0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"leb128",
|
"leb128",
|
||||||
]
|
]
|
||||||
@@ -367,13 +259,9 @@ checksum = "b35c86d22e720a07d954ebbed772d01180501afe7d03d464f413bb5f8914a8d6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.99.0"
|
version = "0.81.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ef3b717afc67f848f412d4f02c127dd3e35a0eecd58c684580414df4fde01d3"
|
checksum = "98930446519f63d00a836efdc22f67766ceae8dbcc1571379f2bcabc6b2b9abc"
|
||||||
dependencies = [
|
|
||||||
"indexmap",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
|
|||||||
@@ -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.99"
|
wasmparser = "0.81"
|
||||||
wasm-encoder = "0.22"
|
wasm-encoder = "0.8"
|
||||||
walrus = "0.19"
|
walrus = "0.19"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
pico-args = "0.5"
|
pico-args = "0.4"
|
||||||
upkr = { git = "https://github.com/exoticorn/upkr.git", rev = "080db40d0088bbee2bdf3c5c75288ac7853d6b7a" }
|
upkr = { git = "https://github.com/exoticorn/upkr.git", rev = "d93aec186c9fb91d962c488682a2db125c61306c" }
|
||||||
pbr = "1"
|
pbr = "1"
|
||||||
@@ -3,7 +3,7 @@ use std::{collections::HashMap, fs::File, path::Path};
|
|||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use wasm_encoder::{
|
use wasm_encoder::{
|
||||||
CodeSection, EntityType, ExportKind, ExportSection, Function, FunctionSection, ImportSection,
|
CodeSection, EntityType, Export, ExportSection, Function, FunctionSection, ImportSection,
|
||||||
Instruction, MemoryType, Module, TypeSection, ValType,
|
Instruction, MemoryType, Module, TypeSection, ValType,
|
||||||
};
|
};
|
||||||
use ValType::*;
|
use ValType::*;
|
||||||
@@ -152,14 +152,14 @@ impl BaseModule {
|
|||||||
add_function(
|
add_function(
|
||||||
&mut functions,
|
&mut functions,
|
||||||
&type_map,
|
&type_map,
|
||||||
"rectangleOutline",
|
"rectangle_outline",
|
||||||
&[F32, F32, F32, F32, I32],
|
&[F32, F32, F32, F32, I32],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
add_function(
|
add_function(
|
||||||
&mut functions,
|
&mut functions,
|
||||||
&type_map,
|
&type_map,
|
||||||
"circleOutline",
|
"circle_outline",
|
||||||
&[F32, F32, F32, I32],
|
&[F32, F32, F32, I32],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
@@ -169,21 +169,6 @@ impl BaseModule {
|
|||||||
add_function(&mut functions, &type_map, "playNote", &[I32, I32], None);
|
add_function(&mut functions, &type_map, "playNote", &[I32, I32], None);
|
||||||
add_function(&mut functions, &type_map, "sndGes", &[I32], Some(F32));
|
add_function(&mut functions, &type_map, "sndGes", &[I32], Some(F32));
|
||||||
|
|
||||||
add_function(
|
|
||||||
&mut functions,
|
|
||||||
&type_map,
|
|
||||||
"blitSprite",
|
|
||||||
&[I32, I32, I32, I32, I32],
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
add_function(
|
|
||||||
&mut functions,
|
|
||||||
&type_map,
|
|
||||||
"grabSprite",
|
|
||||||
&[I32, I32, I32, I32, I32],
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
for i in functions.len()..64 {
|
for i in functions.len()..64 {
|
||||||
add_function(
|
add_function(
|
||||||
&mut functions,
|
&mut functions,
|
||||||
@@ -233,13 +218,13 @@ impl BaseModule {
|
|||||||
let mut imports = ImportSection::new();
|
let mut imports = ImportSection::new();
|
||||||
|
|
||||||
for (module, name, type_) in &self.function_imports {
|
for (module, name, type_) in &self.function_imports {
|
||||||
imports.import(*module, name.as_str(), EntityType::Function(*type_));
|
imports.import(*module, Some(name.as_str()), EntityType::Function(*type_));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (module, name, import) in &self.global_imports {
|
for (module, name, import) in &self.global_imports {
|
||||||
imports.import(
|
imports.import(
|
||||||
*module,
|
*module,
|
||||||
name.as_str(),
|
Some(name.as_str()),
|
||||||
EntityType::Global(wasm_encoder::GlobalType {
|
EntityType::Global(wasm_encoder::GlobalType {
|
||||||
val_type: import.type_,
|
val_type: import.type_,
|
||||||
mutable: import.mutable,
|
mutable: import.mutable,
|
||||||
@@ -249,12 +234,11 @@ impl BaseModule {
|
|||||||
|
|
||||||
imports.import(
|
imports.import(
|
||||||
"env",
|
"env",
|
||||||
"memory",
|
Some("memory"),
|
||||||
MemoryType {
|
MemoryType {
|
||||||
minimum: self.memory as u64,
|
minimum: self.memory as u64,
|
||||||
maximum: None,
|
maximum: None,
|
||||||
memory64: false,
|
memory64: false,
|
||||||
shared: false,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -275,7 +259,7 @@ impl BaseModule {
|
|||||||
let mut exports = ExportSection::new();
|
let mut exports = ExportSection::new();
|
||||||
|
|
||||||
for (name, fnc) in &self.exports {
|
for (name, fnc) in &self.exports {
|
||||||
exports.export(*name, ExportKind::Func, *fnc);
|
exports.export(*name, Export::Function(*fnc));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.section(&exports);
|
module.section(&exports);
|
||||||
@@ -303,7 +287,7 @@ impl BaseModule {
|
|||||||
|
|
||||||
pub fn create_binary(path: &Path) -> Result<()> {
|
pub fn create_binary(path: &Path) -> Result<()> {
|
||||||
let base1 = BaseModule::for_format_version(1)?.to_wasm();
|
let base1 = BaseModule::for_format_version(1)?.to_wasm();
|
||||||
let data = upkr::pack(&base1, 4, &upkr::Config::default(), None);
|
let data = upkr::pack(&base1, 4, false, None);
|
||||||
File::create(path)?.write_all(&data)?;
|
File::create(path)?.write_all(&data)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use std::{
|
|||||||
use wasm_encoder as enc;
|
use wasm_encoder as enc;
|
||||||
use wasmparser::{
|
use wasmparser::{
|
||||||
BinaryReader, ExportSectionReader, ExternalKind, FunctionBody, FunctionSectionReader,
|
BinaryReader, ExportSectionReader, ExternalKind, FunctionBody, FunctionSectionReader,
|
||||||
ImportSectionReader, TableSectionReader, TypeRef, TypeSectionReader,
|
ImportSectionEntryType, ImportSectionReader, TableSectionReader, TypeSectionReader,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct PackConfig {
|
pub struct PackConfig {
|
||||||
@@ -63,7 +63,7 @@ pub fn pack(data: &[u8], config: &PackConfig) -> Result<Vec<u8>> {
|
|||||||
uw8.extend_from_slice(&upkr::pack(
|
uw8.extend_from_slice(&upkr::pack(
|
||||||
&result[8..],
|
&result[8..],
|
||||||
level,
|
level,
|
||||||
&upkr::Config::default(),
|
false,
|
||||||
Some(&mut |pos| {
|
Some(&mut |pos| {
|
||||||
pb.set(pos as u64);
|
pb.set(pos as u64);
|
||||||
}),
|
}),
|
||||||
@@ -90,10 +90,7 @@ pub fn unpack(data: Vec<u8>) -> Result<Vec<u8>> {
|
|||||||
let (version, data) = match data[0] {
|
let (version, data) = match data[0] {
|
||||||
0 => return Ok(data),
|
0 => return Ok(data),
|
||||||
1 => (1, data[1..].to_vec()),
|
1 => (1, data[1..].to_vec()),
|
||||||
2 => (
|
2 => (1, upkr::unpack(&data[1..], false)),
|
||||||
1,
|
|
||||||
upkr::unpack(&data[1..], &upkr::Config::default(), 4 * 1024 * 1024)?,
|
|
||||||
),
|
|
||||||
other => bail!("Uknown format version {}", other),
|
other => bail!("Uknown format version {}", other),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -136,8 +133,8 @@ pub fn unpack(data: Vec<u8>) -> Result<Vec<u8>> {
|
|||||||
Ok(dest)
|
Ok(dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_val_type(type_: &wasmparser::ValType) -> Result<ValType> {
|
fn to_val_type(type_: &wasmparser::Type) -> Result<ValType> {
|
||||||
use wasmparser::ValType::*;
|
use wasmparser::Type::*;
|
||||||
Ok(match *type_ {
|
Ok(match *type_ {
|
||||||
I32 => ValType::I32,
|
I32 => ValType::I32,
|
||||||
I64 => ValType::I64,
|
I64 => ValType::I64,
|
||||||
@@ -147,7 +144,7 @@ fn to_val_type(type_: &wasmparser::ValType) -> Result<ValType> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_val_type_vec(types: &[wasmparser::ValType]) -> Result<Vec<ValType>> {
|
fn to_val_type_vec(types: &[wasmparser::Type]) -> Result<Vec<ValType>> {
|
||||||
types.into_iter().map(to_val_type).collect()
|
types.into_iter().map(to_val_type).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +202,7 @@ impl<'a> ParsedModule<'a> {
|
|||||||
import_section = Some(Section::new(range, ImportSection::parse(reader)?));
|
import_section = Some(Section::new(range, ImportSection::parse(reader)?));
|
||||||
}
|
}
|
||||||
Payload::GlobalSection(reader) => {
|
Payload::GlobalSection(reader) => {
|
||||||
global_section = Some(Section::new(range, reader.count()));
|
global_section = Some(Section::new(range, reader.get_count()));
|
||||||
}
|
}
|
||||||
Payload::FunctionSection(reader) => {
|
Payload::FunctionSection(reader) => {
|
||||||
function_section = Some(Section::new(range, read_function_section(reader)?));
|
function_section = Some(Section::new(range, read_function_section(reader)?));
|
||||||
@@ -224,21 +221,21 @@ impl<'a> ParsedModule<'a> {
|
|||||||
table_section = Some(Section::new(range, ()));
|
table_section = Some(Section::new(range, ()));
|
||||||
}
|
}
|
||||||
Payload::MemorySection(reader) => {
|
Payload::MemorySection(reader) => {
|
||||||
if reader.count() != 0 {
|
if reader.get_count() != 0 {
|
||||||
bail!("Found non-empty MemorySection. Memory has to be imported!");
|
bail!("Found non-empty MemorySection. Memory has to be imported!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Payload::ElementSection(reader) => {
|
Payload::ElementSection(mut reader) => {
|
||||||
let mut elements = Vec::with_capacity(reader.count() as usize);
|
let mut elements = Vec::with_capacity(reader.get_count() as usize);
|
||||||
for element in reader {
|
for _ in 0..reader.get_count() {
|
||||||
elements.push(Element::parse(element?)?);
|
elements.push(Element::parse(reader.read()?)?);
|
||||||
}
|
}
|
||||||
element_section = Some(elements);
|
element_section = Some(elements);
|
||||||
}
|
}
|
||||||
Payload::CodeSectionStart { .. } => (),
|
Payload::CodeSectionStart { .. } => (),
|
||||||
Payload::CodeSectionEntry(body) => function_bodies.push(body),
|
Payload::CodeSectionEntry(body) => function_bodies.push(body),
|
||||||
Payload::CustomSection { .. } => (),
|
Payload::CustomSection { .. } => (),
|
||||||
Payload::End(..) => break,
|
Payload::End => break,
|
||||||
other => bail!("Unsupported section: {:?}", other),
|
other => bail!("Unsupported section: {:?}", other),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,7 +463,7 @@ impl<'a> ParsedModule<'a> {
|
|||||||
{
|
{
|
||||||
let mut export_section = enc::ExportSection::new();
|
let mut export_section = enc::ExportSection::new();
|
||||||
for (name, fnc) in my_exports {
|
for (name, fnc) in my_exports {
|
||||||
export_section.export(&name, enc::ExportKind::Func, fnc);
|
export_section.export(&name, enc::Export::Function(fnc));
|
||||||
}
|
}
|
||||||
module.section(&export_section);
|
module.section(&export_section);
|
||||||
}
|
}
|
||||||
@@ -489,7 +486,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::Instruction::I32Const(element.start_index as i32),
|
||||||
ValType::FuncRef,
|
ValType::FuncRef,
|
||||||
wasm_encoder::Elements::Functions(&functions),
|
wasm_encoder::Elements::Functions(&functions),
|
||||||
);
|
);
|
||||||
@@ -538,27 +535,28 @@ fn read_type_section(reader: TypeSectionReader) -> Result<Vec<base_module::Funct
|
|||||||
|
|
||||||
for type_def in reader {
|
for type_def in reader {
|
||||||
match type_def? {
|
match type_def? {
|
||||||
wasmparser::Type::Func(fnc) => {
|
wasmparser::TypeDef::Func(fnc) => {
|
||||||
if fnc.results().len() > 1 {
|
if fnc.returns.len() > 1 {
|
||||||
bail!("Multi-value not supported");
|
bail!("Multi-value not supported");
|
||||||
}
|
}
|
||||||
let params = to_val_type_vec(fnc.params())?;
|
let params = to_val_type_vec(&fnc.params)?;
|
||||||
let result = to_val_type_vec(fnc.results())?.into_iter().next();
|
let result = to_val_type_vec(&fnc.returns)?.into_iter().next();
|
||||||
function_types.push(FunctionType { params, result });
|
function_types.push(FunctionType { params, result });
|
||||||
}
|
}
|
||||||
|
t => bail!("Unsupported type def {:?}", t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(function_types)
|
Ok(function_types)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_table_section(reader: TableSectionReader) -> Result<()> {
|
fn validate_table_section(mut reader: TableSectionReader) -> Result<()> {
|
||||||
if reader.count() != 1 {
|
if reader.get_count() != 1 {
|
||||||
bail!("Only up to one table supported");
|
bail!("Only up to one table supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
let type_ = reader.into_iter().next().unwrap()?;
|
let type_ = reader.read()?;
|
||||||
if type_.element_type != wasmparser::ValType::FuncRef {
|
if type_.element_type != wasmparser::Type::FuncRef {
|
||||||
bail!("Only one funcref table is supported");
|
bail!("Only one funcref table is supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,20 +590,21 @@ impl ImportSection {
|
|||||||
|
|
||||||
for import in reader {
|
for import in reader {
|
||||||
let import = import?;
|
let import = import?;
|
||||||
|
if let Some(field) = import.field {
|
||||||
match import.ty {
|
match import.ty {
|
||||||
TypeRef::Func(type_) => {
|
ImportSectionEntryType::Function(type_) => {
|
||||||
functions.push(FunctionImport {
|
functions.push(FunctionImport {
|
||||||
module: import.module.to_string(),
|
module: import.module.to_string(),
|
||||||
field: import.name.to_string(),
|
field: field.to_string(),
|
||||||
type_,
|
type_,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
TypeRef::Memory(mem) => {
|
ImportSectionEntryType::Memory(mem) => {
|
||||||
if import.module != "env" || import.name != "memory" {
|
if import.module != "env" || field != "memory" {
|
||||||
bail!(
|
bail!(
|
||||||
"Wrong name of memory import {}.{}, should be env.memory",
|
"Wrong name of memory import {}.{}, should be env.memory",
|
||||||
import.module,
|
import.module,
|
||||||
import.name
|
field
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if mem.memory64 || mem.shared {
|
if mem.memory64 || mem.shared {
|
||||||
@@ -613,10 +612,10 @@ impl ImportSection {
|
|||||||
}
|
}
|
||||||
memory = mem.maximum.unwrap_or(mem.initial) as u32;
|
memory = mem.maximum.unwrap_or(mem.initial) as u32;
|
||||||
}
|
}
|
||||||
TypeRef::Global(glbl) => {
|
ImportSectionEntryType::Global(glbl) => {
|
||||||
globals.push(GlobalImport {
|
globals.push(GlobalImport {
|
||||||
module: import.module.to_string(),
|
module: import.module.to_string(),
|
||||||
field: import.name.to_string(),
|
field: field.to_string(),
|
||||||
type_: GlobalType {
|
type_: GlobalType {
|
||||||
type_: to_val_type(&glbl.content_type)?,
|
type_: to_val_type(&glbl.content_type)?,
|
||||||
mutable: glbl.mutable,
|
mutable: glbl.mutable,
|
||||||
@@ -625,6 +624,12 @@ impl ImportSection {
|
|||||||
}
|
}
|
||||||
_ => bail!("Unsupported import item {:?}", import.ty),
|
_ => bail!("Unsupported import item {:?}", import.ty),
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
bail!(
|
||||||
|
"Found import without field, only module '{}'",
|
||||||
|
import.module
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ImportSection {
|
Ok(ImportSection {
|
||||||
@@ -643,17 +648,17 @@ struct Element {
|
|||||||
|
|
||||||
impl Element {
|
impl Element {
|
||||||
fn parse(element: wasmparser::Element) -> Result<Element> {
|
fn parse(element: wasmparser::Element) -> Result<Element> {
|
||||||
match element.items {
|
if element.ty != wasmparser::Type::FuncRef {
|
||||||
wasmparser::ElementItems::Functions(funcs_reader) => {
|
bail!("Table element type is not FuncRef");
|
||||||
|
}
|
||||||
|
|
||||||
let start_index = if let wasmparser::ElementKind::Active {
|
let start_index = if let wasmparser::ElementKind::Active {
|
||||||
offset_expr,
|
init_expr,
|
||||||
table_index: 0,
|
table_index: 0,
|
||||||
} = element.kind
|
} = element.kind
|
||||||
{
|
{
|
||||||
let mut init_reader = offset_expr.get_operators_reader();
|
let mut init_reader = init_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()?
|
|
||||||
{
|
|
||||||
start_index as u32
|
start_index as u32
|
||||||
} else {
|
} else {
|
||||||
bail!("Table element start index is not a integer constant");
|
bail!("Table element start index is not a integer constant");
|
||||||
@@ -662,9 +667,15 @@ impl Element {
|
|||||||
bail!("Unsupported table element kind");
|
bail!("Unsupported table element kind");
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut functions = Vec::with_capacity(funcs_reader.count() as usize);
|
let mut items_reader = element.items.get_items_reader()?;
|
||||||
for index in funcs_reader {
|
|
||||||
functions.push(index?);
|
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 {
|
Ok(Element {
|
||||||
@@ -672,9 +683,6 @@ impl Element {
|
|||||||
functions,
|
functions,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => bail!("Table element type is not FuncRef"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -704,8 +712,8 @@ fn read_export_section(reader: ExportSectionReader) -> Result<Vec<(String, u32)>
|
|||||||
for export in reader {
|
for export in reader {
|
||||||
let export = export?;
|
let export = export?;
|
||||||
match export.kind {
|
match export.kind {
|
||||||
ExternalKind::Func => {
|
ExternalKind::Function => {
|
||||||
function_exports.push((export.name.to_string(), export.index));
|
function_exports.push((export.field.to_string(), export.index));
|
||||||
}
|
}
|
||||||
_ => (), // just ignore all other kinds since MicroW8 doesn't expect any exports other than functions
|
_ => (), // just ignore all other kinds since MicroW8 doesn't expect any exports other than functions
|
||||||
}
|
}
|
||||||
@@ -726,11 +734,13 @@ fn remap_function(
|
|||||||
}
|
}
|
||||||
let mut function = enc::Function::new(locals);
|
let mut function = enc::Function::new(locals);
|
||||||
|
|
||||||
let block_type = |ty: wasmparser::BlockType| -> Result<enc::BlockType> {
|
let block_type = |ty: wasmparser::TypeOrFuncType| -> Result<enc::BlockType> {
|
||||||
Ok(match ty {
|
Ok(match ty {
|
||||||
wasmparser::BlockType::Empty => enc::BlockType::Empty,
|
wasmparser::TypeOrFuncType::Type(wasmparser::Type::EmptyBlockType) => {
|
||||||
wasmparser::BlockType::Type(ty) => enc::BlockType::Result(to_val_type(&ty)?),
|
enc::BlockType::Empty
|
||||||
wasmparser::BlockType::FuncType(ty) => enc::BlockType::FunctionType(
|
}
|
||||||
|
wasmparser::TypeOrFuncType::Type(ty) => enc::BlockType::Result(to_val_type(&ty)?),
|
||||||
|
wasmparser::TypeOrFuncType::FuncType(ty) => enc::BlockType::FunctionType(
|
||||||
*type_map
|
*type_map
|
||||||
.get(&ty)
|
.get(&ty)
|
||||||
.ok_or_else(|| anyhow!("Function type index out of range: {}", ty))?,
|
.ok_or_else(|| anyhow!("Function type index out of range: {}", ty))?,
|
||||||
@@ -744,7 +754,7 @@ fn remap_function(
|
|||||||
.ok_or_else(|| anyhow!("Global index out of range: {}", idx))?)
|
.ok_or_else(|| anyhow!("Global index out of range: {}", idx))?)
|
||||||
};
|
};
|
||||||
|
|
||||||
fn mem(m: wasmparser::MemArg) -> enc::MemArg {
|
fn mem(m: wasmparser::MemoryImmediate) -> enc::MemArg {
|
||||||
enc::MemArg {
|
enc::MemArg {
|
||||||
offset: m.offset,
|
offset: m.offset,
|
||||||
align: m.align as u32,
|
align: m.align as u32,
|
||||||
@@ -759,31 +769,24 @@ fn remap_function(
|
|||||||
function.instruction(&match op? {
|
function.instruction(&match op? {
|
||||||
De::Unreachable => En::Unreachable,
|
De::Unreachable => En::Unreachable,
|
||||||
De::Nop => En::Nop,
|
De::Nop => En::Nop,
|
||||||
De::Block { blockty } => En::Block(block_type(blockty)?),
|
De::Block { ty } => En::Block(block_type(ty)?),
|
||||||
De::Loop { blockty } => En::Loop(block_type(blockty)?),
|
De::Loop { ty } => En::Loop(block_type(ty)?),
|
||||||
De::If { blockty } => En::If(block_type(blockty)?),
|
De::If { ty } => En::If(block_type(ty)?),
|
||||||
De::Else => En::Else,
|
De::Else => En::Else,
|
||||||
De::Try { .. } | De::Catch { .. } | De::Throw { .. } | De::Rethrow { .. } => todo!(),
|
De::Try { .. } | De::Catch { .. } | De::Throw { .. } | De::Rethrow { .. } => todo!(),
|
||||||
De::End => En::End,
|
De::End => En::End,
|
||||||
De::Br { relative_depth } => En::Br(relative_depth),
|
De::Br { relative_depth } => En::Br(relative_depth),
|
||||||
De::BrIf { relative_depth } => En::BrIf(relative_depth),
|
De::BrIf { relative_depth } => En::BrIf(relative_depth),
|
||||||
De::BrTable { targets } => En::BrTable(
|
De::BrTable { .. } => todo!(),
|
||||||
targets.targets().collect::<Result<Vec<u32>, _>>()?.into(),
|
|
||||||
targets.default(),
|
|
||||||
),
|
|
||||||
De::Return => En::Return,
|
De::Return => En::Return,
|
||||||
De::Call { function_index } => En::Call(
|
De::Call { function_index } => En::Call(
|
||||||
*function_map
|
*function_map
|
||||||
.get(&function_index)
|
.get(&function_index)
|
||||||
.ok_or_else(|| anyhow!("Function index out of range: {}", function_index))?,
|
.ok_or_else(|| anyhow!("Function index out of range: {}", function_index))?,
|
||||||
),
|
),
|
||||||
De::CallIndirect {
|
De::CallIndirect { index, table_index } => En::CallIndirect {
|
||||||
type_index,
|
|
||||||
table_index,
|
|
||||||
table_byte: _, // what is this supposed to be?
|
|
||||||
} => En::CallIndirect {
|
|
||||||
ty: *type_map
|
ty: *type_map
|
||||||
.get(&type_index)
|
.get(&index)
|
||||||
.ok_or_else(|| anyhow!("Unknown function type in call indirect"))?,
|
.ok_or_else(|| anyhow!("Unknown function type in call indirect"))?,
|
||||||
table: table_index,
|
table: table_index,
|
||||||
},
|
},
|
||||||
@@ -803,16 +806,16 @@ fn remap_function(
|
|||||||
De::I64Load { memarg } => En::I64Load(mem(memarg)),
|
De::I64Load { memarg } => En::I64Load(mem(memarg)),
|
||||||
De::F32Load { memarg } => En::F32Load(mem(memarg)),
|
De::F32Load { memarg } => En::F32Load(mem(memarg)),
|
||||||
De::F64Load { memarg } => En::F64Load(mem(memarg)),
|
De::F64Load { memarg } => En::F64Load(mem(memarg)),
|
||||||
De::I32Load8S { memarg } => En::I32Load8S(mem(memarg)),
|
De::I32Load8S { memarg } => En::I32Load8_S(mem(memarg)),
|
||||||
De::I32Load8U { memarg } => En::I32Load8U(mem(memarg)),
|
De::I32Load8U { memarg } => En::I32Load8_U(mem(memarg)),
|
||||||
De::I32Load16S { memarg } => En::I32Load16S(mem(memarg)),
|
De::I32Load16S { memarg } => En::I32Load16_S(mem(memarg)),
|
||||||
De::I32Load16U { memarg } => En::I32Load16U(mem(memarg)),
|
De::I32Load16U { memarg } => En::I32Load16_U(mem(memarg)),
|
||||||
De::I64Load8S { memarg } => En::I64Load8S(mem(memarg)),
|
De::I64Load8S { memarg } => En::I64Load8_S(mem(memarg)),
|
||||||
De::I64Load8U { memarg } => En::I64Load8U(mem(memarg)),
|
De::I64Load8U { memarg } => En::I64Load8_U(mem(memarg)),
|
||||||
De::I64Load16S { memarg } => En::I64Load16S(mem(memarg)),
|
De::I64Load16S { memarg } => En::I64Load16_S(mem(memarg)),
|
||||||
De::I64Load16U { memarg } => En::I64Load16U(mem(memarg)),
|
De::I64Load16U { memarg } => En::I64Load16_U(mem(memarg)),
|
||||||
De::I64Load32S { memarg } => En::I64Load32S(mem(memarg)),
|
De::I64Load32S { memarg } => En::I64Load32_S(mem(memarg)),
|
||||||
De::I64Load32U { memarg } => En::I64Load32U(mem(memarg)),
|
De::I64Load32U { memarg } => En::I64Load32_U(mem(memarg)),
|
||||||
De::I32Store { memarg } => En::I32Store(mem(memarg)),
|
De::I32Store { memarg } => En::I32Store(mem(memarg)),
|
||||||
De::I64Store { memarg } => En::I64Store(mem(memarg)),
|
De::I64Store { memarg } => En::I64Store(mem(memarg)),
|
||||||
De::F32Store { memarg } => En::F32Store(mem(memarg)),
|
De::F32Store { memarg } => En::F32Store(mem(memarg)),
|
||||||
@@ -831,7 +834,7 @@ fn remap_function(
|
|||||||
De::RefNull { .. } | De::RefIsNull { .. } | De::RefFunc { .. } => todo!(),
|
De::RefNull { .. } | De::RefIsNull { .. } | De::RefFunc { .. } => todo!(),
|
||||||
De::I32Eqz => En::I32Eqz,
|
De::I32Eqz => En::I32Eqz,
|
||||||
De::I32Eq => En::I32Eq,
|
De::I32Eq => En::I32Eq,
|
||||||
De::I32Ne => En::I32Ne,
|
De::I32Ne => En::I32Neq,
|
||||||
De::I32LtS => En::I32LtS,
|
De::I32LtS => En::I32LtS,
|
||||||
De::I32LtU => En::I32LtU,
|
De::I32LtU => En::I32LtU,
|
||||||
De::I32GtS => En::I32GtS,
|
De::I32GtS => En::I32GtS,
|
||||||
@@ -842,7 +845,7 @@ fn remap_function(
|
|||||||
De::I32GeU => En::I32GeU,
|
De::I32GeU => En::I32GeU,
|
||||||
De::I64Eqz => En::I64Eqz,
|
De::I64Eqz => En::I64Eqz,
|
||||||
De::I64Eq => En::I64Eq,
|
De::I64Eq => En::I64Eq,
|
||||||
De::I64Ne => En::I64Ne,
|
De::I64Ne => En::I64Neq,
|
||||||
De::I64LtS => En::I64LtS,
|
De::I64LtS => En::I64LtS,
|
||||||
De::I64LtU => En::I64LtU,
|
De::I64LtU => En::I64LtU,
|
||||||
De::I64GtS => En::I64GtS,
|
De::I64GtS => En::I64GtS,
|
||||||
@@ -852,13 +855,13 @@ fn remap_function(
|
|||||||
De::I64GeS => En::I64GeS,
|
De::I64GeS => En::I64GeS,
|
||||||
De::I64GeU => En::I64GeU,
|
De::I64GeU => En::I64GeU,
|
||||||
De::F32Eq => En::F32Eq,
|
De::F32Eq => En::F32Eq,
|
||||||
De::F32Ne => En::F32Ne,
|
De::F32Ne => En::F32Neq,
|
||||||
De::F32Lt => En::F32Lt,
|
De::F32Lt => En::F32Lt,
|
||||||
De::F32Gt => En::F32Gt,
|
De::F32Gt => En::F32Gt,
|
||||||
De::F32Le => En::F32Le,
|
De::F32Le => En::F32Le,
|
||||||
De::F32Ge => En::F32Ge,
|
De::F32Ge => En::F32Ge,
|
||||||
De::F64Eq => En::F64Eq,
|
De::F64Eq => En::F64Eq,
|
||||||
De::F64Ne => En::F64Ne,
|
De::F64Ne => En::F64Neq,
|
||||||
De::F64Lt => En::F64Lt,
|
De::F64Lt => En::F64Lt,
|
||||||
De::F64Gt => En::F64Gt,
|
De::F64Gt => En::F64Gt,
|
||||||
De::F64Le => En::F64Le,
|
De::F64Le => En::F64Le,
|
||||||
@@ -965,7 +968,7 @@ fn remap_function(
|
|||||||
De::I64TruncSatF32U => En::I64TruncSatF32U,
|
De::I64TruncSatF32U => En::I64TruncSatF32U,
|
||||||
De::I64TruncSatF64S => En::I64TruncSatF64S,
|
De::I64TruncSatF64S => En::I64TruncSatF64S,
|
||||||
De::I64TruncSatF64U => En::I64TruncSatF64U,
|
De::I64TruncSatF64U => En::I64TruncSatF64U,
|
||||||
De::MemoryCopy { src_mem, dst_mem } => En::MemoryCopy { src_mem, dst_mem },
|
De::MemoryCopy { src, dst } => En::MemoryCopy { src, dst },
|
||||||
De::MemoryFill { mem } => En::MemoryFill(mem),
|
De::MemoryFill { mem } => En::MemoryFill(mem),
|
||||||
other => bail!("Unsupported instruction {:?}", other),
|
other => bail!("Unsupported instruction {:?}", other),
|
||||||
});
|
});
|
||||||
|
|||||||
1651
uw8-window/Cargo.lock
generated
1651
uw8-window/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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.26.1"
|
||||||
env_logger = "0.11.3"
|
env_logger = "0.9"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pico-args = "0.5"
|
pico-args = "0.4"
|
||||||
wgpu = "0.19.3"
|
wgpu = "0.13.1"
|
||||||
pollster = "0.3.0"
|
pollster = "0.2"
|
||||||
bytemuck = { version = "1.15", features = [ "derive" ] }
|
bytemuck = { version = "1.4", 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 = "0.3.9"
|
||||||
|
|||||||
@@ -36,36 +36,36 @@ fn sample_pixel(coords: vec2<i32>, offset: vec4<f32>) -> vec3<f32> {
|
|||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
let pixelf = floor(in.tex_coords);
|
let pixel = floor(in.tex_coords);
|
||||||
let o = vec2<f32>(0.5) - (in.tex_coords - pixelf);
|
let o = vec2<f32>(0.5) - (in.tex_coords - pixel);
|
||||||
let pixel = vec2<i32>(pixelf);
|
let pixel = vec2<i32>(pixel);
|
||||||
|
|
||||||
let offset_x = o.xxxx + vec4<f32>(-0.125, 0.375, 0.125, -0.375) * uniforms.texture_scale.z;
|
let offset_x = o.xxxx + vec4<f32>(-0.125, 0.375, 0.125, -0.375) * uniforms.texture_scale.z;
|
||||||
let offset_y = o.yyyy + vec4<f32>(-0.375, -0.125, 0.375, 0.125) * uniforms.texture_scale.z;
|
let offset_y = o.yyyy + vec4<f32>(-0.375, -0.125, 0.375, 0.125) * uniforms.texture_scale.z;
|
||||||
|
|
||||||
var offset_x0 = max(abs(offset_x + vec4<f32>(-1.0)) - vec4<f32>(0.5), vec4<f32>(0.0));
|
let offset_x0 = max(abs(offset_x + vec4<f32>(-1.0)) - vec4<f32>(0.5), vec4<f32>(0.0));
|
||||||
var offset_x1 = max(abs(offset_x) - vec4<f32>(0.5), vec4<f32>(0.0));
|
let offset_x1 = max(abs(offset_x) - vec4<f32>(0.5), vec4<f32>(0.0));
|
||||||
var offset_x2 = max(abs(offset_x + vec4<f32>(1.0)) - vec4<f32>(0.5), vec4<f32>(0.0));
|
let offset_x2 = max(abs(offset_x + vec4<f32>(1.0)) - vec4<f32>(0.5), vec4<f32>(0.0));
|
||||||
|
|
||||||
offset_x0 = offset_x0 * offset_x0;
|
let offset_x0 = offset_x0 * offset_x0;
|
||||||
offset_x1 = offset_x1 * offset_x1;
|
let offset_x1 = offset_x1 * offset_x1;
|
||||||
offset_x2 = offset_x2 * offset_x2;
|
let offset_x2 = offset_x2 * offset_x2;
|
||||||
|
|
||||||
var offset_yr = offset_y + vec4<f32>(-1.0);
|
let offset_yr = offset_y + vec4<f32>(-1.0);
|
||||||
offset_yr = vec4<f32>(0.02) + offset_yr * offset_yr;
|
let offset_yr = vec4<f32>(0.02) + offset_yr * offset_yr;
|
||||||
|
|
||||||
var acc = sample_pixel(pixel + vec2<i32>(-1, -1), offset_x0 + offset_yr);
|
var acc = sample_pixel(pixel + vec2<i32>(-1, -1), offset_x0 + offset_yr);
|
||||||
acc = acc + sample_pixel(pixel + vec2<i32>(0, -1), offset_x1 + offset_yr);
|
acc = acc + sample_pixel(pixel + vec2<i32>(0, -1), offset_x1 + offset_yr);
|
||||||
acc = acc + sample_pixel(pixel + vec2<i32>(1, -1), offset_x2 + offset_yr);
|
acc = acc + sample_pixel(pixel + vec2<i32>(1, -1), offset_x2 + offset_yr);
|
||||||
|
|
||||||
offset_yr = vec4<f32>(0.02) + offset_y * offset_y;
|
let offset_yr = vec4<f32>(0.02) + offset_y * offset_y;
|
||||||
|
|
||||||
acc = acc + sample_pixel(pixel + vec2<i32>(-1, 0), offset_x0 + offset_yr);
|
acc = acc + sample_pixel(pixel + vec2<i32>(-1, 0), offset_x0 + offset_yr);
|
||||||
acc = acc + sample_pixel(pixel, offset_x1 + offset_yr);
|
acc = acc + sample_pixel(pixel, offset_x1 + offset_yr);
|
||||||
acc = acc + sample_pixel(pixel + vec2<i32>(1, 0), offset_x2 + offset_yr);
|
acc = acc + sample_pixel(pixel + vec2<i32>(1, 0), offset_x2 + offset_yr);
|
||||||
|
|
||||||
offset_yr = offset_y + vec4<f32>(1.0);
|
let offset_yr = offset_y + vec4<f32>(1.0);
|
||||||
offset_yr = vec4<f32>(0.02) + offset_yr * offset_yr;
|
let offset_yr = vec4<f32>(0.02) + offset_yr * offset_yr;
|
||||||
|
|
||||||
acc = acc + sample_pixel(pixel + vec2<i32>(-1, 1), offset_x0 + offset_yr);
|
acc = acc + sample_pixel(pixel + vec2<i32>(-1, 1), offset_x0 + offset_yr);
|
||||||
acc = acc + sample_pixel(pixel + vec2<i32>(0, 1), offset_x1 + offset_yr);
|
acc = acc + sample_pixel(pixel + vec2<i32>(0, 1), offset_x1 + offset_yr);
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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(wgpu::Backends::all());
|
||||||
|
let surface = unsafe { instance.create_surface(&window) };
|
||||||
let instance = wgpu::Instance::new(Default::default());
|
|
||||||
let surface = instance.create_surface(window.clone())?;
|
|
||||||
let adapter = instance
|
let adapter = instance
|
||||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||||
power_preference: wgpu::PowerPreference::LowPower,
|
power_preference: wgpu::PowerPreference::LowPower,
|
||||||
@@ -76,14 +71,11 @@ impl Window {
|
|||||||
let palette_screen_mode = PaletteScreenMode::new(&device);
|
let palette_screen_mode = PaletteScreenMode::new(&device);
|
||||||
|
|
||||||
let surface_config = wgpu::SurfaceConfiguration {
|
let surface_config = wgpu::SurfaceConfiguration {
|
||||||
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||||
|
format: surface.get_supported_formats(&adapter)[0],
|
||||||
|
width: window.inner_size().width,
|
||||||
|
height: window.inner_size().height,
|
||||||
present_mode: wgpu::PresentMode::AutoNoVsync,
|
present_mode: wgpu::PresentMode::AutoNoVsync,
|
||||||
..surface
|
|
||||||
.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,11 +113,8 @@ 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 timeout = self.next_frame.saturating_duration_since(Instant::now());
|
|
||||||
let status = self.event_loop.pump_events(Some(timeout), |event, elwt| {
|
|
||||||
let mut new_filter = None;
|
let mut new_filter = None;
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event, .. } => match event {
|
Event::WindowEvent { event, .. } => match event {
|
||||||
@@ -136,31 +125,32 @@ impl WindowImpl for Window {
|
|||||||
self.filter.resize(&self.queue, new_size);
|
self.filter.resize(&self.queue, new_size);
|
||||||
}
|
}
|
||||||
WindowEvent::CloseRequested => {
|
WindowEvent::CloseRequested => {
|
||||||
elwt.exit();
|
self.is_open = false;
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
WindowEvent::KeyboardInput { event, .. } => {
|
WindowEvent::KeyboardInput { input, .. } => {
|
||||||
fn gamepad_button(input: &winit::event::KeyEvent) -> u8 {
|
fn gamepad_button(input: &winit::event::KeyboardInput) -> u8 {
|
||||||
match input.physical_key {
|
match input.scancode {
|
||||||
PhysicalKey::Code(KeyCode::KeyZ) => 16,
|
44 => 16,
|
||||||
PhysicalKey::Code(KeyCode::KeyX) => 32,
|
45 => 32,
|
||||||
PhysicalKey::Code(KeyCode::KeyA) => 64,
|
30 => 64,
|
||||||
PhysicalKey::Code(KeyCode::KeyS) => 128,
|
31 => 128,
|
||||||
_ => match input.logical_key {
|
_ => match input.virtual_keycode {
|
||||||
Key::Named(NamedKey::ArrowUp) => 1,
|
Some(VirtualKeyCode::Up) => 1,
|
||||||
Key::Named(NamedKey::ArrowDown) => 2,
|
Some(VirtualKeyCode::Down) => 2,
|
||||||
Key::Named(NamedKey::ArrowLeft) => 4,
|
Some(VirtualKeyCode::Left) => 4,
|
||||||
Key::Named(NamedKey::ArrowRight) => 8,
|
Some(VirtualKeyCode::Right) => 8,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if event.state == winit::event::ElementState::Pressed {
|
if input.state == winit::event::ElementState::Pressed {
|
||||||
match event.logical_key {
|
match input.virtual_keycode {
|
||||||
Key::Named(NamedKey::Escape) => {
|
Some(VirtualKeyCode::Escape) => {
|
||||||
elwt.exit();
|
self.is_open = false;
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
Key::Character(ref c) => match c.as_str() {
|
Some(VirtualKeyCode::F) => {
|
||||||
"f" => {
|
|
||||||
let fullscreen = if self.window.fullscreen().is_some() {
|
let fullscreen = if self.window.fullscreen().is_some() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@@ -169,24 +159,30 @@ impl WindowImpl for Window {
|
|||||||
self.is_fullscreen = fullscreen.is_some();
|
self.is_fullscreen = fullscreen.is_some();
|
||||||
self.window.set_fullscreen(fullscreen);
|
self.window.set_fullscreen(fullscreen);
|
||||||
}
|
}
|
||||||
"r" => reset = true,
|
Some(VirtualKeyCode::R) => reset = true,
|
||||||
"1" => new_filter = Some(1),
|
Some(VirtualKeyCode::Key1) => new_filter = Some(1),
|
||||||
"2" => new_filter = Some(2),
|
Some(VirtualKeyCode::Key2) => new_filter = Some(2),
|
||||||
"3" => new_filter = Some(3),
|
Some(VirtualKeyCode::Key3) => new_filter = Some(3),
|
||||||
"4" => new_filter = Some(4),
|
Some(VirtualKeyCode::Key4) => new_filter = Some(4),
|
||||||
"5" => new_filter = Some(5),
|
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 {
|
if let Some(new_filter) = new_filter {
|
||||||
@@ -199,15 +195,6 @@ impl WindowImpl for Window {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
match status {
|
|
||||||
PumpStatus::Exit(_) => self.is_open = false,
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
if Instant::now() >= self.next_frame {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Input {
|
Input {
|
||||||
gamepads: self.gamepads,
|
gamepads: self.gamepads,
|
||||||
reset,
|
reset,
|
||||||
@@ -243,12 +230,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 +357,6 @@ 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: &[],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let palette_texture = device.create_texture(&wgpu::TextureDescriptor {
|
let palette_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
@@ -387,7 +371,6 @@ 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: &[],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let screen_texture = device.create_texture(&wgpu::TextureDescriptor {
|
let screen_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
@@ -402,7 +385,6 @@ 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: &[],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="uw8">
|
<div id="uw8">
|
||||||
<a href="https://exoticorn.github.io/microw8">MicroW8</a> 0.2.2
|
<a href="https://exoticorn.github.io/microw8">MicroW8</a> 0.2.1
|
||||||
</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">
|
||||||
|
|||||||
Reference in New Issue
Block a user