perilus

RISC-V processor built with Chisel
git clone https://git.bradleygannon.com/perilus.git
Log | Files | Refs | Submodules | README

commit 1af2b66ae1b64f177c6e56bf0f59942025d1e7be
parent bab30f16e00b59bae6180491fb5bf5defe223709
Author: Bradley Gannon <bradley@bradleygannon.com>
Date:   Thu,  1 Oct 2026 23:04:34 -0400

Replace TUI simulator with desktop version

Diffstat:
Mflake.nix | 9+++++++++
Mjustfile | 6+++---
Msim/Cargo.lock | 4708++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msim/Cargo.toml | 18+++++++++---------
Dsim/build.rs | 42------------------------------------------
Asim/cli/Cargo.toml | 12++++++++++++
Asim/cli/src/main.rs | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asim/core/Cargo.toml | 10++++++++++
Asim/core/build.rs | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asim/core/src/lib.rs | 1+
Asim/core/src/perilus.rs | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsim/src/wrapper.cpp -> sim/core/src/wrapper.cpp | 0
Asim/gui/Cargo.toml | 10++++++++++
Asim/gui/src/app.rs | 672+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asim/gui/src/main.rs | 32++++++++++++++++++++++++++++++++
Asim/gui/src/state.rs | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asim/gui/src/ui/controls.rs | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asim/gui/src/ui/memory.rs | 220+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asim/gui/src/ui/mod.rs | 3+++
Asim/gui/src/ui/registers.rs | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsim/src/main.rs | 469-------------------------------------------------------------------------------
Dsim/src/perilus.rs | 95-------------------------------------------------------------------------------
Mtests/run.sh | 2+-
23 files changed, 5105 insertions(+), 1740 deletions(-)

diff --git a/flake.nix b/flake.nix @@ -22,6 +22,14 @@ }; libInputs = with stable; [ stdenv.cc.cc.lib + libGL + libxkbcommon + wayland + libx11 + libxcursor + libxrandr + libxi + libxcb ]; lib-path = with stable; lib.makeLibraryPath libInputs; in @@ -52,6 +60,7 @@ unstable.sail-riscv uv verilator + zenity ]; shellHook = '' diff --git a/justfile b/justfile @@ -17,7 +17,7 @@ doc: fmt: sbt scalafmtAll - cd sim && cargo fmt && cargo clippy + cd sim && cargo fmt --all && cargo clippy --workspace --all-targets [script] [arg("force", long="force", value="1")] @@ -50,10 +50,10 @@ verilate force='': fi build-sim: chisel verilate - cd sim && cargo build --release + cd sim && cargo build --release -p sim-cli simulate: chisel verilate - cd sim && cargo run --release + cd sim && cargo run --release -p sim-gui clean: sbt clean diff --git a/sim/Cargo.lock b/sim/Cargo.lock @@ -3,12 +3,132 @@ version = 4 [[package]] -name = "addr2line" -version = "0.25.1" +name = "ab_glyph" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" + +[[package]] +name = "accesskit" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b7f7f85a7e5f68090000ed7622545829afd484d210358702ae4cb97dd0c320" +dependencies = [ + "uuid", +] + +[[package]] +name = "accesskit_atspi_common" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8c61bee90b42a772d39d06a740207dc71a4e780004ace1db8d99fb1baaa954" +dependencies = [ + "accesskit", + "accesskit_consumer 0.36.0", + "atspi-common", + "phf", + "serde", + "zvariant", +] + +[[package]] +name = "accesskit_consumer" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53cf47daed85312e763fbf85ceca136e0d7abc68e0a7e12abe11f48172bc3b10" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_consumer" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e0d7e25d06f4dc21d1774d67146e9e80d6789216cbd4d1e88185b0095dba60" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_consumer" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d10a236f96f87d70732e44520046785431ef01d5bcd6b041317bfadd2f88245" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_macos" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce02dc63b43f0c9296af9ac946312a2dc8814427d7a64d2d600971dac55b6076" +dependencies = [ + "accesskit", + "accesskit_consumer 0.38.0", + "hashbrown 0.16.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "accesskit_unix" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b016ca8db0ea0ea2ceff29a9d6240391492d960716aa471967c00e8cc8cb197c" +dependencies = [ + "accesskit", + "accesskit_atspi_common", + "async-channel", + "async-executor", + "async-task", + "atspi", + "futures-lite", + "futures-util", + "serde", + "zbus", +] + +[[package]] +name = "accesskit_windows" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff7009f1a532e917d66970a1e80c965140c6cfbbabbdde3d64e5431e6c78e21" +dependencies = [ + "accesskit", + "accesskit_consumer 0.35.0", + "hashbrown 0.16.1", + "static_assertions", + "windows", + "windows-core", +] + +[[package]] +name = "accesskit_winit" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +checksum = "1fe9a94394896352cc4660ca2288bd4ef883d83238853c038b44070c8f134313" dependencies = [ - "gimli", + "accesskit", + "accesskit_macos", + "accesskit_unix", + "accesskit_windows", + "raw-window-handle", + "winit", ] [[package]] @@ -18,12 +138,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] -name = "aho-corasick" -version = "1.1.4" +name = "ahash" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "memchr", + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", ] [[package]] @@ -33,6 +157,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] +name = "android-activity" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" +dependencies = [ + "android-properties", + "bitflags 2.13.2", + "cc", + "jni", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror 2.0.21", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + +[[package]] name = "anstream" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -68,7 +226,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -79,1977 +237,4285 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] -name = "anyhow" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "atomic" -version = "0.6.1" +name = "arboard" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" dependencies = [ - "bytemuck", + "clipboard-win", + "image", + "log", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", + "parking_lot", + "percent-encoding", + "windows-sys 0.60.2", + "x11rb", ] [[package]] -name = "autocfg" -version = "1.5.0" +name = "arrayref" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] -name = "backtrace" -version = "0.3.76" +name = "arrayvec" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link", -] +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] -name = "base64" -version = "0.22.1" +name = "as-raw-xcb-connection" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] -name = "bit-set" -version = "0.5.3" +name = "ash" +version = "0.38.0+1.3.281" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" dependencies = [ - "bit-vec", + "libloading", ] [[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" +name = "async-broadcast" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] [[package]] -name = "bitflags" -version = "2.11.1" +name = "async-channel" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "async-executor" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" dependencies = [ - "generic-array", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", ] [[package]] -name = "bounded-integer" -version = "0.6.1" +name = "async-io" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfb439fc02606b667a4422a1667bfa6e4574223f7f6062518a41d399697a657" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 1.1.5", + "slab", + "windows-sys 0.61.2", +] [[package]] -name = "bumpalo" -version = "3.20.2" +name = "async-lock" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] [[package]] -name = "bytemuck" -version = "1.25.0" +name = "async-process" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix 1.1.5", +] [[package]] -name = "castaway" -version = "0.2.4" +name = "async-recursion" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ - "rustversion", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "cc" -version = "1.2.60" +name = "async-signal" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" dependencies = [ - "find-msvc-tools", - "shlex", + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 1.1.5", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", ] [[package]] -name = "cfg-if" -version = "1.0.4" +name = "async-task" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] -name = "cfg_aliases" -version = "0.2.1" +name = "async-trait" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] [[package]] -name = "clap" -version = "4.6.2" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd059f9da4f5c36b3787f65d38ccaab1cc315f07b01f89abc8359ee6a8205011" -dependencies = [ - "clap_builder", - "clap_derive", -] +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] -name = "clap_builder" -version = "4.6.2" +name = "atspi" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" +checksum = "c77886257be21c9cd89a4ae7e64860c6f0eefca799bb79127913052bd0eefb3d" dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", + "atspi-common", + "atspi-proxies", ] [[package]] -name = "clap_derive" -version = "4.6.1" +name = "atspi-common" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +checksum = "20c5617155740c98003016429ad13fe43ce7a77b007479350a9f8bf95a29f63d" dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.117", + "enumflags2", + "serde", + "static_assertions", + "zbus", + "zbus-lockstep", + "zbus-lockstep-macros", + "zbus_names", + "zvariant", ] [[package]] -name = "clap_lex" -version = "1.1.0" +name = "atspi-proxies" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc" +dependencies = [ + "atspi-common", + "serde", + "zbus", +] [[package]] -name = "color-eyre" -version = "0.6.5" +name = "autocfg" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d" -dependencies = [ - "backtrace", - "color-spantrace", - "eyre", - "indenter", - "once_cell", - "owo-colors", - "tracing-error", -] +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] -name = "color-spantrace" -version = "0.3.0" +name = "bit-set" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427" +checksum = "09ec2f926cc3060f09db9ebc5b52823d85268d24bb917e472c0c4bea35780a7d" dependencies = [ - "once_cell", - "owo-colors", - "tracing-core", - "tracing-error", + "bit-vec", ] [[package]] -name = "colorchoice" -version = "1.0.5" +name = "bit-vec" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" [[package]] -name = "compact_str" -version = "0.9.0" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "convert_case" -version = "0.10.0" +name = "bitflags" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" -dependencies = [ - "unicode-segmentation", -] +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "block2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "libc", + "objc2 0.5.2", ] [[package]] -name = "crossterm" -version = "0.29.0" +name = "block2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "bitflags 2.11.1", - "crossterm_winapi", - "derive_more", - "document-features", - "mio", - "parking_lot", - "rustix", - "signal-hook", - "signal-hook-mio", - "winapi", + "objc2 0.6.4", ] [[package]] -name = "crossterm_winapi" -version = "0.9.1" +name = "blocking" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" dependencies = [ - "winapi", + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", ] [[package]] -name = "crypto-common" -version = "0.1.7" +name = "bounded-integer" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] +checksum = "67c210ac9fa33f699b394d9a66471402ff987305afd02ab1e3ba7b11bf71a237" [[package]] -name = "csscolorparser" -version = "0.6.2" +name = "bumpalo" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf" -dependencies = [ - "lab", - "phf", -] +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] -name = "darling" -version = "0.23.0" +name = "bytemuck" +version = "1.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" dependencies = [ - "darling_core", - "darling_macro", + "bytemuck_derive", ] [[package]] -name = "darling_core" -version = "0.23.0" +name = "bytemuck_derive" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" dependencies = [ - "ident_case", "proc-macro2", "quote", - "strsim", - "syn 2.0.117", + "syn 3.0.6", ] [[package]] -name = "darling_macro" -version = "0.23.0" +name = "byteorder-lite" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.117", -] +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] -name = "deltae" -version = "0.3.2" +name = "bytes" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] -name = "deranged" -version = "0.5.8" +name = "calloop" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "powerfmt", + "bitflags 2.13.2", + "log", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", ] [[package]] -name = "derive_more" -version = "2.1.1" +name = "calloop" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" dependencies = [ - "derive_more-impl", + "bitflags 2.13.2", + "polling", + "rustix 1.1.5", + "slab", + "tracing", ] [[package]] -name = "derive_more-impl" -version = "2.1.1" +name = "calloop-wayland-source" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.117", + "calloop 0.13.0", + "rustix 0.38.44", + "wayland-backend", + "wayland-client", ] [[package]] -name = "digest" -version = "0.10.7" +name = "calloop-wayland-source" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" dependencies = [ - "block-buffer", - "crypto-common", + "calloop 0.14.4", + "rustix 1.1.5", + "wayland-backend", + "wayland-client", ] [[package]] -name = "document-features" -version = "0.2.12" +name = "cc" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +checksum = "f360145194ee8e21db5ee7f3fcd4fe52210864c75c985dae33218202c8bbe040" dependencies = [ - "litrs", + "find-msvc-tools", + "jobserver", + "libc", + "shlex", ] [[package]] -name = "either" -version = "1.15.0" +name = "cfg-if" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] -name = "equivalent" -version = "1.0.2" +name = "cfg_aliases" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] -name = "errno" -version = "0.3.14" +name = "cgl" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" dependencies = [ "libc", - "windows-sys", ] [[package]] -name = "euclid" -version = "0.22.14" +name = "clap" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" dependencies = [ - "num-traits", -] - -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", + "clap_builder", + "clap_derive", ] [[package]] -name = "fancy-regex" -version = "0.11.0" +name = "clap_builder" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" dependencies = [ - "bit-set", - "regex", + "anstream", + "anstyle", + "clap_lex", + "strsim", ] [[package]] -name = "filedescriptor" -version = "0.8.3" +name = "clap_derive" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" dependencies = [ - "libc", - "thiserror 1.0.69", - "winapi", + "heck", + "proc-macro2", + "quote", + "syn 3.0.6", ] [[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "finl_unicode" -version = "1.4.0" +name = "clap_lex" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9844ddc3a6e533d62bba727eb6c28b5d360921d5175e9ff0f1e621a5c590a4d5" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" [[package]] -name = "fixedbitset" -version = "0.4.2" +name = "clipboard-win" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] [[package]] -name = "fnv" -version = "1.0.7" +name = "codespan-reporting" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] [[package]] -name = "foldhash" -version = "0.1.5" +name = "color" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "2ec7c5eb7a16992b1904d76c517d170ab353b0e0b3d5a0c81a8a0cd1037893cf" +dependencies = [ + "bytemuck", +] [[package]] -name = "foldhash" -version = "0.2.0" +name = "colorchoice" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] -name = "generic-array" -version = "0.14.7" +name = "combine" +version = "4.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" dependencies = [ - "typenum", - "version_check", + "bytes", + "memchr", ] [[package]] -name = "getrandom" -version = "0.3.4" +name = "concurrent-queue" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "cfg-if", - "libc", - "r-efi 5.3.0", - "wasip2", + "crossbeam-utils", ] [[package]] -name = "getrandom" -version = "0.4.2" +name = "core-foundation" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "cfg-if", + "core-foundation-sys", "libc", - "r-efi 6.0.0", - "wasip2", - "wasip3", ] [[package]] -name = "gimli" -version = "0.32.3" +name = "core-foundation-sys" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "hashbrown" -version = "0.15.5" +name = "core-graphics" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ - "foldhash 0.1.5", + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", ] [[package]] -name = "hashbrown" -version = "0.16.1" +name = "core-graphics-types" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ - "allocator-api2", - "equivalent", - "foldhash 0.2.0", + "bitflags 1.3.2", + "core-foundation", + "libc", ] [[package]] -name = "hashbrown" -version = "0.17.0" +name = "crc32fast" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] [[package]] -name = "heck" -version = "0.5.0" +name = "crossbeam-utils" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] -name = "hex" -version = "0.4.3" +name = "crunchy" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] -name = "id-arena" -version = "2.3.0" +name = "cursor-icon" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" [[package]] -name = "ident_case" -version = "1.0.1" +name = "dispatch" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] -name = "indenter" -version = "0.3.4" +name = "dispatch2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.13.2", + "block2 0.6.2", + "libc", + "objc2 0.6.4", +] [[package]] -name = "indexmap" -version = "2.14.0" +name = "displaydoc" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ - "equivalent", - "hashbrown 0.17.0", - "serde", - "serde_core", + "proc-macro2", + "quote", + "syn 3.0.6", ] [[package]] -name = "indoc" -version = "2.0.7" +name = "dlib" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" dependencies = [ - "rustversion", + "libloading", ] [[package]] -name = "instability" -version = "0.3.12" +name = "document-features" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" dependencies = [ - "darling", - "indoc", - "proc-macro2", - "quote", - "syn 2.0.117", + "litrs", ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.2" +name = "downcast-rs" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] -name = "itertools" -version = "0.14.0" +name = "dpi" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" [[package]] -name = "itoa" -version = "1.0.18" +name = "ecolor" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +checksum = "0656a7530b9e2841ee7a5f983965bdd9840c32f4012f759cfd44b912cced6b34" +dependencies = [ + "bytemuck", + "emath", +] [[package]] -name = "js-sys" -version = "0.3.95" +name = "eframe" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "55ad41fac6e3149abb4866e93df37dbd33baa95db525c3368c944584e95a5dc2" dependencies = [ - "once_cell", + "ahash", + "bytemuck", + "document-features", + "egui", + "egui-wgpu", + "egui-winit", + "egui_glow", + "glutin", + "glutin-winit", + "image", + "js-sys", + "log", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "parking_lot", + "percent-encoding", + "pollster 1.0.1", + "profiling", + "raw-window-handle", + "static_assertions", "wasm-bindgen", + "web-sys", + "web-time", + "wgpu", + "windows-sys 0.61.2", + "winit", ] [[package]] -name = "kasuari" -version = "0.4.12" +name = "egui" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde5057d6143cc94e861d90f591b9303d6716c6b9602309150bd068853c10899" +checksum = "dc938cc27cd911415e1e4d151bc56ff9df063d8db081374e87aeb805ea74b2ba" dependencies = [ - "hashbrown 0.16.1", - "portable-atomic", - "thiserror 2.0.18", + "accesskit", + "ahash", + "bitflags 2.13.2", + "emath", + "epaint", + "itertools", + "log", + "nohash-hasher", + "profiling", + "smallvec", + "unicode-segmentation", + "web-sys", ] [[package]] -name = "lab" -version = "0.11.0" +name = "egui-wgpu" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f" +checksum = "5cef1f6d1bba40b09a4d0d62cb822b81030922cfbf65c5373398c3a3caafc5bd" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "epaint", + "log", + "profiling", + "thiserror 2.0.21", + "type-map", + "web-time", + "wgpu", + "winit", +] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "egui-winit" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "98466000559d66ba4db786a30448b01483946add4188e7f10f522a27b4fb89cc" +dependencies = [ + "accesskit_winit", + "arboard", + "bytemuck", + "egui", + "log", + "objc2 0.6.4", + "objc2-foundation 0.3.2", + "objc2-ui-kit 0.3.2", + "profiling", + "raw-window-handle", + "smithay-clipboard", + "web-time", + "webbrowser", + "winit", +] [[package]] -name = "leb128fmt" -version = "0.1.0" +name = "egui_glow" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +checksum = "606ed4167daf341e5753d703285c4c1d562324b2c07aa8f405cd7d066fe58f3b" +dependencies = [ + "bytemuck", + "egui", + "glow", + "log", + "profiling", + "winit", +] [[package]] -name = "libc" -version = "0.2.185" +name = "either" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] -name = "line-clipping" -version = "0.3.7" +name = "emath" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8" +checksum = "52c8d4141cf0f60fb2f7aefaf352d3ffa5171ef0ab09731c64391801e95e48f1" dependencies = [ - "bitflags 2.11.1", + "bytemuck", ] [[package]] -name = "linux-raw-sys" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" - -[[package]] -name = "litrs" -version = "1.0.0" +name = "endi" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" [[package]] -name = "lock_api" -version = "0.4.14" +name = "enumflags2" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" dependencies = [ - "scopeguard", + "enumflags2_derive", + "serde", ] [[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "lru" -version = "0.16.4" +name = "enumflags2_derive" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ - "hashbrown 0.16.1", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "mac_address" -version = "1.1.8" +name = "epaint" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0aeb26bf5e836cc1c341c8106051b573f1766dfa05aa87f0b98be5e51b02303" +checksum = "a0ec0308dc23130fc1a7d4623a8534c2ed069c6dc84e258ee4f3de99615aa1a3" dependencies = [ - "nix", - "winapi", + "ahash", + "bytemuck", + "ecolor", + "emath", + "epaint_default_fonts", + "font-types", + "harfrust", + "log", + "nohash-hasher", + "parking_lot", + "profiling", + "self_cell", + "skrifa", + "smallvec", + "unicode-general-category", + "unicode-segmentation", + "vello_cpu", ] [[package]] -name = "memchr" -version = "2.8.0" +name = "epaint_default_fonts" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "773fa9c96dd0dbef887e39d0ed6177f141cce4d68e6041df77570aa3702dfa13" [[package]] -name = "memmem" -version = "0.1.1" +name = "equivalent" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "memoffset" -version = "0.9.1" +name = "errno" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ - "autocfg", + "libc", + "windows-sys 0.61.2", ] [[package]] -name = "minimal-lexical" -version = "0.2.1" +name = "error-code" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7" [[package]] -name = "miniz_oxide" -version = "0.8.9" +name = "euclid" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" dependencies = [ - "adler2", + "num-traits", ] [[package]] -name = "mio" -version = "1.2.0" +name = "event-listener" +version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" dependencies = [ - "libc", - "log", - "wasi", - "windows-sys", + "parking", + "pin-project-lite", ] [[package]] -name = "nix" -version = "0.29.0" +name = "event-listener-strategy" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "bitflags 2.11.1", - "cfg-if", - "cfg_aliases", - "libc", - "memoffset", + "event-listener", + "pin-project-lite", ] [[package]] -name = "nom" -version = "7.1.3" +name = "fastrand" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] -name = "num-conv" -version = "0.2.1" +name = "fax" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" [[package]] -name = "num-derive" -version = "0.4.2" +name = "fdeflate" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "simd-adler32", ] [[package]] -name = "num-traits" -version = "0.2.19" +name = "fearless_simd" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] +checksum = "b97b65636e5b9ef369943878ac74335ba1c55c1cb6adbf1e2c293c624248d693" [[package]] -name = "num_threads" -version = "0.1.7" +name = "find-msvc-tools" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] +checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" [[package]] -name = "object" -version = "0.37.3" +name = "flate2" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" dependencies = [ - "memchr", + "crc32fast", + "miniz_oxide 0.9.1", + "zlib-rs", ] [[package]] -name = "once_cell" -version = "1.21.4" +name = "foldhash" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] -name = "once_cell_polyfill" -version = "1.70.2" +name = "font-types" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +checksum = "b8eb065f3251655b3c90e22e5e363f310fc5332fb3402e37bbc94752283248f6" +dependencies = [ + "bytemuck", +] [[package]] -name = "ordered-float" -version = "4.6.0" +name = "foreign-types" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ - "num-traits", + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", ] [[package]] -name = "owo-colors" -version = "4.3.0" +name = "foreign-types-shared" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] -name = "parking_lot" -version = "0.12.5" +name = "form_urlencoded" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ - "lock_api", - "parking_lot_core", + "percent-encoding", ] [[package]] -name = "parking_lot_core" -version = "0.9.12" +name = "futures-core" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.5", + "windows-link", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "r-efi 6.0.0", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glifo" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed4a1bb24121291d27230c1b1b44e07d6a9b28cefdb32fe1581dfb84e14f940a" +dependencies = [ + "bytemuck", + "foldhash", + "hashbrown 0.17.1", + "log", + "peniko", + "skrifa", + "smallvec", + "vello_common", +] + +[[package]] +name = "glow" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" +dependencies = [ + "bitflags 2.13.2", + "cfg_aliases", + "cgl", + "dispatch2", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-allocator" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" +dependencies = [ + "ash", + "hashbrown 0.16.1", + "log", + "presser", + "thiserror 2.0.21", + "windows", +] + +[[package]] +name = "guillotiere" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b17e70c989c36bad147b27a58d148c0741c51448aa5653436547323e524d0ab" +dependencies = [ + "euclid", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "num-traits", + "zerocopy", +] + +[[package]] +name = "harfrust" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03d949a14aa089bbb282f7dd76a498a7f684428e4257202efc119ec010376f9" +dependencies = [ + "bitflags 2.13.2", + "bytemuck", + "read-fonts", + "smallvec", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png", + "tiff", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" +dependencies = [ + "either", +] + +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.21", + "walkdir", "windows-link", ] [[package]] -name = "pest" -version = "2.8.6" +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "kurbo" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b60dfc32f652b926df6192e55525b16d186c69d47876c3ead4da5cc9f8450e2" +dependencies = [ + "arrayvec", + "euclid", + "polycool", + "smallvec", +] + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" +dependencies = [ + "bitflags 2.13.2", + "libc", + "plain", + "redox_syscall 0.9.4", +] + +[[package]] +name = "linebender_resource_handle" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memmap2" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "naga" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a616d2fb8c89516ac2723a581f69d6c18576046bed761bd6b305e5618e6ae130" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases", + "codespan-reporting", + "half", + "hashbrown 0.17.1", + "indexmap", + "libm", + "log", + "naga-types", + "num-traits", + "once_cell", + "rustc-hash 1.1.0", + "spirv", + "thiserror 2.0.21", + "unicode-ident", +] + +[[package]] +name = "naga-types" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "590afbf58a6f4f62873cd5cff4468061844bafa1cdf399cc954537c22d768d49" +dependencies = [ + "hashbrown 0.17.1", + "indexmap", + "rustc-hash 1.1.0", + "thiserror 2.0.21", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.13.2", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.13.2", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2 0.6.4", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-contacts", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "dispatch", + "libc", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.13.2", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.4", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" +dependencies = [ + "bitflags 2.13.2", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation 0.2.2", + "objc2-link-presentation", + "objc2-quartz-core 0.2.2", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "orbclient" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" +dependencies = [ + "libc", + "libredox", +] + +[[package]] +name = "ordered-float" +version = "5.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c9e0d9b23589f26070720bac724174bfec1083e82f7854cdd0267518343c0" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.18", + "smallvec", + "windows-link", +] + +[[package]] +name = "peniko" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "839c8299360d2e998bdb106dc0a6cd71dcc5f4df51df1b620361bf50e283cca6" +dependencies = [ + "bytemuck", + "color", + "kurbo", + "linebender_resource_handle", + "smallvec", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "perilus-core" +version = "0.1.0" +dependencies = [ + "bounded-integer", + "cc", +] + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "piper" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.13.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.9", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 1.1.5", + "windows-sys 0.61.2", +] + +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + +[[package]] +name = "pollster" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6355899e1c9462875b6757c79f3caa011a1fdae12bbb1a2e72dd1f234f8336" + +[[package]] +name = "polycool" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50596ddc09eb5ad5f75cacd40209568e66df71baf86e1499a0e99c4cff12a5a6" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "zerovec", +] + +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" + +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "range-alloc" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "raw-window-metal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" +dependencies = [ + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + +[[package]] +name = "read-fonts" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709" +dependencies = [ + "bytemuck", + "font-types", + "once_cell", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "redox_syscall" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "737970939a87c6fa31e7acad13307bccbb017a073b695b6089a2c484f929e20e" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "rfd" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20dafead71c16a34e1ff357ddefc8afc11e7d51d6d2b9fbd07eaa48e3e540220" +dependencies = [ + "block2 0.6.2", + "dispatch2", + "js-sys", + "libc", + "log", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "percent-encoding", + "pollster 0.4.0", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "web-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys 0.12.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit 0.19.2", + "tiny-skia", +] + +[[package]] +name = "self_cell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813" + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "serde_repr" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "sim-cli" +version = "0.1.0" +dependencies = [ + "clap", + "perilus-core", +] + +[[package]] +name = "sim-gui" +version = "0.1.0" +dependencies = [ + "eframe", + "egui", + "perilus-core", + "rfd", +] + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "siphasher" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33f4fe9184a62d842c9ef383018f3306d8ba224fd9d836f56d7288308847c256" + +[[package]] +name = "skrifa" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819ab7d62b1d3e72d9d9dea5650bac30424f9111364bb94928dbf5ecad1baa68" +dependencies = [ + "bytemuck", + "read-fonts", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "slotmap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.13.2", + "calloop 0.13.0", + "calloop-wayland-source 0.3.0", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 0.38.44", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" +dependencies = [ + "bitflags 2.13.2", + "calloop 0.14.4", + "calloop-wayland-source 0.4.1", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 1.1.5", + "thiserror 2.0.21", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-experimental", + "wayland-protocols-misc", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-clipboard" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226" +dependencies = [ + "libc", + "smithay-client-toolkit 0.20.0", + "wayland-backend", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "spirv" +version = "0.4.0+sdk-1.4.341.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9571ea910ebd84c86af4b3ed27f9dbdc6ad06f17c5f96146b2b671e2976744f" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix 1.1.5", + "windows-sys 0.61.2", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" +dependencies = [ + "thiserror-impl 2.0.21", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "tiff" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error", + "weezl", + "zune-jpeg", +] + +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ - "memchr", - "ucd-trie", + "pin-project-lite", ] [[package]] -name = "pest_derive" -version = "2.8.6" +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ - "pest", - "pest_generator", + "serde_core", ] [[package]] -name = "pest_generator" -version = "2.8.6" +name = "toml_edit" +version = "0.25.15+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +checksum = "1340ea94a5856333492c9064b02c778b191dd2c853778d9609debdcdfea3a614" dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.117", + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", ] [[package]] -name = "pest_meta" -version = "2.8.6" +name = "toml_parser" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ - "pest", - "sha2", + "winnow", ] [[package]] -name = "phf" -version = "0.11.3" +name = "tracing" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ - "phf_macros", - "phf_shared", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", ] [[package]] -name = "phf_codegen" -version = "0.11.3" +name = "tracing-attributes" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ - "phf_generator", - "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "phf_generator" -version = "0.11.3" +name = "tracing-core" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ - "phf_shared", - "rand", + "once_cell", ] [[package]] -name = "phf_macros" -version = "0.11.3" +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + +[[package]] +name = "type-map" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 2.0.117", + "rustc-hash 2.1.3", ] [[package]] -name = "phf_shared" -version = "0.11.3" +name = "uds_windows" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ - "siphasher", + "memoffset", + "tempfile", + "windows-sys 0.61.2", ] [[package]] -name = "pin-project-lite" -version = "0.2.17" +name = "unicode-general-category" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" [[package]] -name = "portable-atomic" -version = "1.13.1" +name = "unicode-ident" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] -name = "powerfmt" -version = "0.2.0" +name = "unicode-segmentation" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] -name = "prettyplease" -version = "0.2.37" +name = "unicode-width" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] -name = "proc-macro2" -version = "1.0.106" +name = "url" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ - "unicode-ident", + "form_urlencoded", + "idna", + "percent-encoding", + "serde", ] [[package]] -name = "quote" -version = "1.0.45" +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] -name = "r-efi" -version = "5.3.0" +name = "utf8parse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "r-efi" -version = "6.0.0" +name = "uuid" +version = "1.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" +dependencies = [ + "js-sys", + "serde_core", + "wasm-bindgen", +] [[package]] -name = "rand" -version = "0.8.5" +name = "vello_common" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "b2e9aed918117e8152c9eddfd8362d73c465c23f26c44786aa331707b8a64fa2" dependencies = [ - "rand_core", + "bytemuck", + "fearless_simd", + "guillotiere", + "log", + "peniko", + "smallvec", + "thiserror 2.0.21", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "vello_cpu" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac7349e1f55f6b801c7c277958df4ea53e7f20f21e8014910ad888b2ecda93ea" +dependencies = [ + "bytemuck", + "glifo", + "hashbrown 0.17.1", + "vello_common", +] + +[[package]] +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "ratatui" -version = "0.30.0" +name = "walkdir" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1ce67fb8ba4446454d1c8dbaeda0557ff5e94d39d5e5ed7f10a65eb4c8266bc" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ - "instability", - "ratatui-core", - "ratatui-crossterm", - "ratatui-macros", - "ratatui-termwiz", - "ratatui-widgets", + "same-file", + "winapi-util", ] [[package]] -name = "ratatui-core" -version = "0.1.0" +name = "wasip2" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "bitflags 2.11.1", - "compact_str", - "hashbrown 0.16.1", - "indoc", - "itertools", - "kasuari", - "lru", - "strum", - "thiserror 2.0.18", - "unicode-segmentation", - "unicode-truncate", - "unicode-width", + "wit-bindgen", ] [[package]] -name = "ratatui-crossterm" -version = "0.1.0" +name = "wasm-bindgen" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577c9b9f652b4c121fb25c6a391dd06406d3b092ba68827e6d2f09550edc54b3" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" dependencies = [ "cfg-if", - "crossterm", - "instability", - "ratatui-core", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] -name = "ratatui-macros" -version = "0.7.0" +name = "wasm-bindgen-futures" +version = "0.4.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f1342a13e83e4bb9d0b793d0ea762be633f9582048c892ae9041ef39c936f4" +checksum = "3cbab34de2d982e9b48e18d216d04c4a6f641066ff19ffb699980f591ee3610e" dependencies = [ - "ratatui-core", - "ratatui-widgets", + "js-sys", + "tokio", + "wasm-bindgen", ] [[package]] -name = "ratatui-termwiz" -version = "0.1.0" +name = "wasm-bindgen-macro" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f76fe0bd0ed4295f0321b1676732e2454024c15a35d01904ddb315afd3d545c" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" dependencies = [ - "ratatui-core", - "termwiz", + "quote", + "wasm-bindgen-macro-support", ] [[package]] -name = "ratatui-widgets" -version = "0.3.0" +name = "wasm-bindgen-macro-support" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" dependencies = [ - "bitflags 2.11.1", - "hashbrown 0.16.1", - "indoc", - "instability", - "itertools", - "line-clipping", - "ratatui-core", - "strum", - "time", - "unicode-segmentation", - "unicode-width", + "bumpalo", + "proc-macro2", + "quote", + "syn 3.0.6", + "wasm-bindgen-shared", ] [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "wasm-bindgen-shared" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" dependencies = [ - "bitflags 2.11.1", + "unicode-ident", ] [[package]] -name = "regex" -version = "1.12.3" +name = "wayland-backend" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "cc", + "downcast-rs", + "rustix 1.1.5", + "scoped-tls", + "smallvec", + "wayland-sys", ] [[package]] -name = "regex-automata" -version = "0.4.14" +name = "wayland-client" +version = "0.31.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "bitflags 2.13.2", + "rustix 1.1.5", + "wayland-backend", + "wayland-scanner", ] [[package]] -name = "regex-syntax" -version = "0.8.10" +name = "wayland-csd-frame" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.13.2", + "cursor-icon", + "wayland-backend", +] [[package]] -name = "rustc-demangle" -version = "0.1.27" +name = "wayland-cursor" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" +dependencies = [ + "rustix 1.1.5", + "wayland-client", + "xcursor", +] [[package]] -name = "rustc_version" -version = "0.4.1" +name = "wayland-protocols" +version = "0.32.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" dependencies = [ - "semver", + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-scanner", ] [[package]] -name = "rustix" -version = "1.1.4" +name = "wayland-protocols-experimental" +version = "20250721.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" dependencies = [ - "bitflags 2.11.1", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] -name = "rustversion" -version = "1.0.22" +name = "wayland-protocols-misc" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" +dependencies = [ + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] [[package]] -name = "ryu" -version = "1.0.23" +name = "wayland-protocols-plasma" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" +dependencies = [ + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "wayland-protocols-wlr" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" +dependencies = [ + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] [[package]] -name = "semver" -version = "1.0.28" +name = "wayland-scanner" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] [[package]] -name = "serde" -version = "1.0.228" +name = "wayland-sys" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" dependencies = [ - "serde_core", - "serde_derive", + "dlib", + "log", + "once_cell", + "pkg-config", ] [[package]] -name = "serde_core" -version = "1.0.228" +name = "web-sys" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "88261b9deccee56594c11a3460c462c41f58d148598fe70ad77070126a68aba4" dependencies = [ - "serde_derive", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "serde_derive" -version = "1.0.228" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "serde_json" -version = "1.0.149" +name = "webbrowser" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "62c35be770821a214dbc362fc26908c853e776c0004294d0b10b8a6bad582f94" dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", + "jni", + "log", + "ndk-context", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "url", + "web-sys", ] [[package]] -name = "sha2" -version = "0.10.9" +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + +[[package]] +name = "wgpu" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "527ccdf43dd5b2e8676eed9984ce00e2bbb0a1b85b70c1969dcb6cd2eb55ab9e" dependencies = [ + "arrayvec", + "bitflags 2.13.2", + "bytemuck", "cfg-if", - "cpufeatures", - "digest", + "cfg_aliases", + "document-features", + "hashbrown 0.17.1", + "js-sys", + "log", + "naga", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "wgpu-core" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "14c018fce9b6270aa203c2fdd56f3cce996713534bd757e4ea58c8560b121f14" dependencies = [ - "lazy_static", + "arrayvec", + "bit-set", + "bit-vec", + "bitflags 2.13.2", + "bytemuck", + "cfg_aliases", + "document-features", + "hashbrown 0.17.1", + "indexmap", + "log", + "naga", + "naga-types", + "once_cell", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.21", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", + "wgpu-core-deps-wasm", + "wgpu-core-deps-windows-linux-android", + "wgpu-hal", + "wgpu-naga-bridge", + "wgpu-types", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "wgpu-core-deps-apple" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "061f3d319a40d39d00b1ecc2c33b89fe21d4e6fe01859df3500a3a8ecccd6b68" +dependencies = [ + "wgpu-hal", +] [[package]] -name = "signal-hook" -version = "0.3.18" +name = "wgpu-core-deps-emscripten" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +checksum = "d98b86cf4abf524a902dd35f18ca6a3f08fc2ae9847c8f10b48e30491b1f0b86" dependencies = [ - "libc", - "signal-hook-registry", + "wgpu-hal", ] [[package]] -name = "signal-hook-mio" -version = "0.2.5" +name = "wgpu-core-deps-wasm" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" +checksum = "d260ca2ca8adc654f513a869bf3cac0b47f5b8d3f87803d6942015f8de597aae" dependencies = [ - "libc", - "mio", - "signal-hook", + "wgpu-hal", ] [[package]] -name = "signal-hook-registry" -version = "1.4.8" +name = "wgpu-core-deps-windows-linux-android" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "7586165fd5f6d881cb9ce4bb71f40d6caab2c0f1837e3fc1d9788a197fb6004f" dependencies = [ - "errno", + "wgpu-hal", +] + +[[package]] +name = "wgpu-hal" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b7fb58561a792bc237628ba0792e332de418fefe145f13b5ed8201e6d52f58" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.13.2", + "block2 0.6.2", + "bytemuck", + "cfg-if", + "cfg_aliases", + "glow", + "glutin_wgl_sys", + "gpu-allocator", + "hashbrown 0.17.1", + "js-sys", + "khronos-egl", "libc", + "libloading", + "log", + "naga", + "naga-types", + "ndk-sys", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", + "objc2-quartz-core 0.3.2", + "once_cell", + "ordered-float", + "parking_lot", + "portable-atomic", + "portable-atomic-util", + "profiling", + "range-alloc", + "raw-window-handle", + "raw-window-metal", + "renderdoc-sys", + "smallvec", + "static_assertions", + "thiserror 2.0.21", + "wasm-bindgen", + "wayland-sys", + "web-sys", + "wgpu-naga-bridge", + "wgpu-types", + "windows", + "windows-core", + "windows-result", ] [[package]] -name = "sim" -version = "0.1.0" +name = "wgpu-naga-bridge" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f62e73117bb7a62bfd9c5a5841438a823f6566c6442a808ee269d2d055c081" dependencies = [ - "bounded-integer", - "cc", - "clap", - "color-eyre", - "crossterm", - "ratatui", + "naga", + "wgpu-types", ] [[package]] -name = "siphasher" -version = "1.0.2" +name = "wgpu-types" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "99dad6f1fbdbbdb4c278a6508b059d44688f5cebddf78d005a46a31340269286" +dependencies = [ + "bitflags 2.13.2", + "bytemuck", + "js-sys", + "log", + "naga-types", + "raw-window-handle", + "static_assertions", + "web-sys", +] [[package]] -name = "smallvec" -version = "1.15.1" +name = "winapi-util" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "windows" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", +] [[package]] -name = "strsim" -version = "0.11.1" +name = "windows-collections" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core", +] [[package]] -name = "strum" -version = "0.27.2" +name = "windows-core" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "strum_macros", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] -name = "strum_macros" -version = "0.27.2" +name = "windows-future" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.117", + "windows-core", + "windows-link", + "windows-threading", ] [[package]] -name = "syn" -version = "1.0.109" +name = "windows-implement" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn 2.0.119", ] [[package]] -name = "syn" -version = "2.0.117" +name = "windows-interface" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn 2.0.119", ] [[package]] -name = "terminfo" -version = "0.9.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662" -dependencies = [ - "fnv", - "nom", - "phf", - "phf_codegen", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "termios" -version = "0.3.3" +name = "windows-numerics" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "libc", + "windows-core", + "windows-link", ] [[package]] -name = "termwiz" -version = "0.23.3" +name = "windows-result" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "anyhow", - "base64", - "bitflags 2.11.1", - "fancy-regex", - "filedescriptor", - "finl_unicode", - "fixedbitset", - "hex", - "lazy_static", - "libc", - "log", - "memmem", - "nix", - "num-derive", - "num-traits", - "ordered-float", - "pest", - "pest_derive", - "phf", - "sha2", - "signal-hook", - "siphasher", - "terminfo", - "termios", - "thiserror 1.0.69", - "ucd-trie", - "unicode-segmentation", - "vtparse", - "wezterm-bidi", - "wezterm-blob-leases", - "wezterm-color-types", - "wezterm-dynamic", - "wezterm-input-types", - "winapi", + "windows-link", ] [[package]] -name = "thiserror" -version = "1.0.69" +name = "windows-strings" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "thiserror-impl 1.0.69", + "windows-link", ] [[package]] -name = "thiserror" -version = "2.0.18" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "thiserror-impl 2.0.18", + "windows-targets 0.52.6", ] [[package]] -name = "thiserror-impl" -version = "1.0.69" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "windows-targets 0.52.6", ] [[package]] -name = "thiserror-impl" -version = "2.0.18" +name = "windows-sys" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "windows-targets 0.53.5", ] [[package]] -name = "thread_local" -version = "1.1.9" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "cfg-if", + "windows-link", ] [[package]] -name = "time" -version = "0.3.47" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "deranged", - "libc", - "num-conv", - "num_threads", - "powerfmt", - "serde_core", - "time-core", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] -name = "time-core" -version = "0.1.8" +name = "windows-targets" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] [[package]] -name = "tracing" -version = "0.1.44" +name = "windows-threading" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "pin-project-lite", - "tracing-core", + "windows-link", ] [[package]] -name = "tracing-core" -version = "0.1.36" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", - "valuable", -] +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "tracing-error" -version = "0.2.1" +name = "windows_aarch64_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" -dependencies = [ - "tracing", - "tracing-subscriber", -] +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] -name = "tracing-subscriber" -version = "0.3.23" +name = "windows_aarch64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" -dependencies = [ - "sharded-slab", - "thread_local", - "tracing-core", -] +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "typenum" -version = "1.19.0" +name = "windows_aarch64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] -name = "ucd-trie" -version = "0.1.7" +name = "windows_i686_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "unicode-ident" -version = "1.0.24" +name = "windows_i686_gnu" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] -name = "unicode-segmentation" -version = "1.13.2" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "unicode-truncate" -version = "2.0.1" +name = "windows_i686_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5" -dependencies = [ - "itertools", - "unicode-segmentation", - "unicode-width", -] +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] -name = "unicode-width" -version = "0.2.2" +name = "windows_i686_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "unicode-xid" -version = "0.2.6" +name = "windows_i686_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] -name = "utf8parse" -version = "0.2.2" +name = "windows_x86_64_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "uuid" -version = "1.23.0" +name = "windows_x86_64_gnu" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" -dependencies = [ - "atomic", - "getrandom 0.4.2", - "js-sys", - "wasm-bindgen", -] +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] -name = "valuable" -version = "0.1.1" +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "version_check" -version = "0.9.5" +name = "windows_x86_64_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] -name = "vtparse" -version = "0.6.2" +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0" -dependencies = [ - "utf8parse", -] +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" +name = "windows_x86_64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] -name = "wasip2" -version = "1.0.2+wasi-0.2.9" +name = "winit" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" dependencies = [ - "wit-bindgen", + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.13.2", + "block2 0.5.1", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases", + "concurrent-queue", + "core-foundation", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit 0.2.2", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix 0.38.44", + "sctk-adwaita", + "smithay-client-toolkit 0.19.2", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", ] [[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +name = "winnow" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ - "wit-bindgen", + "memchr", ] [[package]] -name = "wasm-bindgen" -version = "0.2.118" +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + +[[package]] +name = "x11-dl" +version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" dependencies = [ - "cfg-if", + "libc", "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", + "pkg-config", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.118" +name = "x11rb" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ - "quote", - "wasm-bindgen-macro-support", + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.5", + "x11rb-protocol", ] [[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.118" +name = "x11rb-protocol" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn 2.0.117", - "wasm-bindgen-shared", -] +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" [[package]] -name = "wasm-bindgen-shared" -version = "0.2.118" +name = "xcursor" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" -dependencies = [ - "unicode-ident", -] +checksum = "163b33ed8786455e2fa5d72f554057ce3f3182425434f756cd39c99839d88e23" [[package]] -name = "wasm-encoder" -version = "0.244.0" +name = "xkbcommon-dl" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "leb128fmt", - "wasmparser", + "bitflags 2.13.2", + "dlib", + "log", + "once_cell", + "xkeysym", ] [[package]] -name = "wasm-metadata" -version = "0.244.0" +name = "xkeysym" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" [[package]] -name = "wasmparser" -version = "0.244.0" +name = "yoke" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ - "bitflags 2.11.1", - "hashbrown 0.15.5", - "indexmap", - "semver", + "stable_deref_trait", + "yoke-derive", + "zerofrom", ] [[package]] -name = "wezterm-bidi" -version = "0.2.3" +name = "yoke-derive" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec" +checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78" dependencies = [ - "log", - "wezterm-dynamic", + "proc-macro2", + "quote", + "syn 3.0.6", + "synstructure", ] [[package]] -name = "wezterm-blob-leases" -version = "0.1.1" +name = "zbus" +version = "5.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7" +checksum = "5db4be7c075cb421e4b7ee645541604239bd243ba7c357511f4ff3a74b555907" dependencies = [ - "getrandom 0.3.4", - "mac_address", - "sha2", - "thiserror 1.0.69", + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "libc", + "ordered-stream", + "rustix 1.1.5", + "serde", + "serde_repr", + "tracing", + "uds_windows", "uuid", + "windows-sys 0.61.2", + "winnow", + "zbus_macros", + "zbus_names", + "zvariant", ] [[package]] -name = "wezterm-color-types" -version = "0.3.0" +name = "zbus-lockstep" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296" +checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863" dependencies = [ - "csscolorparser", - "deltae", - "lazy_static", - "wezterm-dynamic", + "zbus_xml", + "zvariant", ] [[package]] -name = "wezterm-dynamic" -version = "0.2.1" +name = "zbus-lockstep-macros" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac" +checksum = "10da05367f3a7b7553c8cdf8fa91aee6b64afebe32b51c95177957efc47ca3a0" dependencies = [ - "log", - "ordered-float", - "strsim", - "thiserror 1.0.69", - "wezterm-dynamic-derive", + "proc-macro2", + "quote", + "syn 2.0.119", + "zbus-lockstep", + "zbus_xml", + "zvariant", ] [[package]] -name = "wezterm-dynamic-derive" -version = "0.1.1" +name = "zbus_macros" +version = "5.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c0cf2d539c645b448eaffec9ec494b8b19bd5077d9e58cb1ae7efece8d575b" +checksum = "2990635d09ade6df1868f72f8cac69a876a90981e8bd3c40b1be413f8dc88f40" dependencies = [ + "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 3.0.6", + "zbus_names", + "zvariant", + "zvariant_utils", ] [[package]] -name = "wezterm-input-types" -version = "0.1.0" +name = "zbus_names" +version = "4.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e" +checksum = "d8bf88b4a3ff53e883001e0e0115b297a9d53c31b9c1edd2bfdd853e3428624e" dependencies = [ - "bitflags 1.3.2", - "euclid", - "lazy_static", "serde", - "wezterm-dynamic", + "winnow", + "zvariant", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "zbus_xml" +version = "5.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "d1586c021a01ca0a9216dcd874e546382e156a5cbab5fab6cb5f10087e22682a" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "serde", + "winnow", + "zbus_names", + "zvariant", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "zcheapstr" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "d1afec51604565183aeb5c54c20aeab286120d4e4460f7f76e3e8bb8c0d99473" +dependencies = [ + "serde", +] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "zerocopy" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "6df92bf3d9227be3d53173901ddbffac2babc27ae50f397776ffd6dc33f800cb" +dependencies = [ + "zerocopy-derive", +] [[package]] -name = "windows-link" -version = "0.2.1" +name = "zerocopy-derive" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +checksum = "ac4f328cf2f05d084e496c3e9c3f33ed0a183656a16e1fcec4d464d8373aec82" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] [[package]] -name = "windows-sys" -version = "0.61.2" +name = "zerofrom" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ - "windows-link", + "zerofrom-derive", ] [[package]] -name = "wit-bindgen" -version = "0.51.0" +name = "zerofrom-derive" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" dependencies = [ - "wit-bindgen-rust-macro", + "proc-macro2", + "quote", + "syn 3.0.6", + "synstructure", ] [[package]] -name = "wit-bindgen-core" -version = "0.51.0" +name = "zerotrie" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ - "anyhow", - "heck", - "wit-parser", + "displaydoc", + "yoke", + "zerofrom", ] [[package]] -name = "wit-bindgen-rust" -version = "0.51.0" +name = "zerovec" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", + "yoke", + "zerofrom", + "zerovec-derive", ] [[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" +name = "zerovec-derive" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ - "anyhow", - "prettyplease", "proc-macro2", "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", + "syn 3.0.6", ] [[package]] -name = "wit-component" -version = "0.244.0" +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + +[[package]] +name = "zune-core" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56377fd46368984a170bc5aac5567e52ca5da874caa60bea39fcbca78fb658b" + +[[package]] +name = "zune-jpeg" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ - "anyhow", - "bitflags 2.11.1", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", + "zune-core", ] [[package]] -name = "wit-parser" -version = "0.244.0" +name = "zvariant" +version = "5.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +checksum = "c1d34c27cc6cdd1f458427519dd6b8612f7b7e3f7b9a0b2355d041dda9869147" dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", + "endi", + "enumflags2", "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", + "winnow", + "zcheapstr", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864155e69b4352db0c7f374917bf45d1e0c8d17659c8b3dbf9795f3673f8c497" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 3.0.6", + "zvariant_utils", ] [[package]] -name = "zmij" -version = "1.0.21" +name = "zvariant_utils" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "bad0294361a320b694a328460dc73add56c306150f5cb6bfafc44446120008a3" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 3.0.6", + "winnow", +] diff --git a/sim/Cargo.toml b/sim/Cargo.toml @@ -1,14 +1,14 @@ -[package] -name = "sim" +[workspace] +resolver = "3" +members = ["core", "cli", "gui"] + +[workspace.package] version = "0.1.0" edition = "2024" -[build-dependencies] -cc = "1.2.60" - -[dependencies] +[workspace.dependencies] bounded-integer = "0.6.1" clap = { version = "4.6.2", features = ["derive"] } -color-eyre = "0.6.5" -crossterm = "0.29.0" -ratatui = "0.30.0" +eframe = "0.36.2" +egui = "0.36.2" +rfd = "0.17.2" diff --git a/sim/build.rs b/sim/build.rs @@ -1,42 +0,0 @@ -use std::{env, error::Error, process::Command}; - -fn main() -> Result<(), Box<dyn Error>> { - let verilator_command_output = Command::new("verilator") - .arg("--getenv") - .arg("VERILATOR_ROOT") - .output()?; - if !verilator_command_output.status.success() { - return Err("Failed to get VERILATOR_ROOT. Is Verilator installed?".into()); - } - let verilator_root = match String::from_utf8(verilator_command_output.stdout) { - Ok(s) => s.trim().to_string(), - Err(e) => { - return Err(format!("Failed to parse Verilator command output as UTF-8: {e}").into()); - } - }; - - unsafe { - env::set_var("CC", "gcc"); - env::set_var("CXX", "g++"); - } - - cc::Build::new() - .cpp(true) - .include(format!("{verilator_root}/include")) - .include(format!("{verilator_root}/include/vltstd")) - .include("../verilated") - .warnings(false) - .file("src/wrapper.cpp") - .compile("wrapper"); - - println!("cargo:rustc-link-search=native=../verilated"); - println!("cargo:rustc-link-lib=static=VPerilus"); - println!("cargo:rustc-link-lib=static=verilated"); - println!("cargo:rustc-link-lib=dylib=stdc++"); - - println!("cargo::rerun-if-changed=./src/wrapper.cpp"); - println!("cargo::rerun-if-changed=../verilated/libverilated.a"); - println!("cargo::rerun-if-changed=../verilated/libVPerilus.a"); - - Ok(()) -} diff --git a/sim/cli/Cargo.toml b/sim/cli/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "sim-cli" +version.workspace = true +edition.workspace = true + +[[bin]] +name = "sim" +path = "src/main.rs" + +[dependencies] +perilus-core = { path = "../core" } +clap.workspace = true diff --git a/sim/cli/src/main.rs b/sim/cli/src/main.rs @@ -0,0 +1,58 @@ +use std::{error::Error, path::PathBuf}; + +use clap::{Parser, Subcommand}; +use perilus_core::perilus::Perilus; + +#[derive(Parser)] +struct Cli { + #[command(subcommand)] + command: Command, +} + +#[derive(Subcommand)] +enum Command { + /// Run a raw binary program to completion and report pass/fail + Test { file: PathBuf }, +} + +const EBREAK_INSTRUCTION: u32 = 0x00100073; +const TEST_MAX_CYCLES: u32 = 1_000_000; +const TEST_PASS_VALUE: u32 = 0xebbb3689; +const TEST_FAIL_VALUE: u32 = 0xd02a545a; + +fn main() -> Result<(), Box<dyn Error>> { + let cli = Cli::parse(); + let perilus = Perilus::init(); + + match cli.command { + Command::Test { file } => { + perilus.load_file(file)?; + let mut cycles = 0; + loop { + perilus.pulse_clock(); + cycles += 1; + if cycles > TEST_MAX_CYCLES { + return Err("Test execution hit maximum cycle count limit".into()); + } + if perilus.get_control_unit_state() == 0 { + let pc = perilus.get_pc(); + let instr = perilus.get_memory().get((pc / 4) as usize); + if instr.is_none() { + return Err(format!( + "Program counter diverged to an address outside memory: 0x{pc:08x}" + ) + .into()); + } + if let Some(&EBREAK_INSTRUCTION) = instr { + let result = perilus.get_registers()[1]; + match result { + TEST_PASS_VALUE => return Ok(()), + TEST_FAIL_VALUE => return Err("Test failed".into()), + v => return Err(format!("Got unexpected test result 0x{v:08x}").into()), + } + } + } + } + } + } +} diff --git a/sim/core/Cargo.toml b/sim/core/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "perilus-core" +version.workspace = true +edition.workspace = true + +[build-dependencies] +cc = "1.2.60" + +[dependencies] +bounded-integer.workspace = true diff --git a/sim/core/build.rs b/sim/core/build.rs @@ -0,0 +1,51 @@ +use std::{env, error::Error, path::PathBuf, process::Command}; + +fn main() -> Result<(), Box<dyn Error>> { + let verilator_command_output = Command::new("verilator") + .arg("--getenv") + .arg("VERILATOR_ROOT") + .output()?; + if !verilator_command_output.status.success() { + return Err("Failed to get VERILATOR_ROOT. Is Verilator installed?".into()); + } + let verilator_root = match String::from_utf8(verilator_command_output.stdout) { + Ok(s) => s.trim().to_string(), + Err(e) => { + return Err(format!("Failed to parse Verilator command output as UTF-8: {e}").into()); + } + }; + + let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?); + let verilated_dir = manifest_dir.join("../../verilated"); + + unsafe { + env::set_var("CC", "gcc"); + env::set_var("CXX", "g++"); + } + + cc::Build::new() + .cpp(true) + .include(format!("{verilator_root}/include")) + .include(format!("{verilator_root}/include/vltstd")) + .include(&verilated_dir) + .warnings(false) + .file("src/wrapper.cpp") + .compile("wrapper"); + + println!("cargo:rustc-link-search=native={}", verilated_dir.display()); + println!("cargo:rustc-link-lib=static=VPerilus"); + println!("cargo:rustc-link-lib=static=verilated"); + println!("cargo:rustc-link-lib=dylib=stdc++"); + + println!("cargo::rerun-if-changed=./src/wrapper.cpp"); + println!( + "cargo::rerun-if-changed={}", + verilated_dir.join("libverilated.a").display() + ); + println!( + "cargo::rerun-if-changed={}", + verilated_dir.join("libVPerilus.a").display() + ); + + Ok(()) +} diff --git a/sim/core/src/lib.rs b/sim/core/src/lib.rs @@ -0,0 +1 @@ +pub mod perilus; diff --git a/sim/core/src/perilus.rs b/sim/core/src/perilus.rs @@ -0,0 +1,132 @@ +use bounded_integer::BoundedU32; +use std::{io, path::PathBuf, slice}; + +unsafe extern "C" { + fn perilus_init(); + fn perilus_eval(); + fn perilus_drop(); + fn perilus_increment_time(); + fn perilus_set_clock(new_clock: u32); + fn perilus_get_pc() -> u32; + fn perilus_set_pc(new_pc: u32); + fn perilus_set_reset(new_reset: u32); + fn perilus_get_control_unit_state() -> u32; + fn perilus_get_register_file() -> *const u32; + fn perilus_set_register(reg: u32, value: u32); + fn perilus_get_memory() -> *const u32; + fn perilus_set_memory(address: u32, value: u32); +} + +pub type Register = BoundedU32<0, 31>; +pub type MemoryIndex = BoundedU32<0, { Perilus::MEMORY_SIZE_WORDS as u32 }>; + +pub struct Perilus; + +impl Perilus { + pub const NUM_REGISTERS: usize = 32; + pub const MEMORY_SIZE_WORDS: usize = 1_048_576; + pub const MEMORY_SIZE_BYTES: usize = Self::MEMORY_SIZE_WORDS * 4; + + pub fn init() -> Perilus { + unsafe { perilus_init() }; + Perilus + } + pub fn pulse_clock(&self) { + unsafe { + perilus_set_clock(0); + perilus_eval(); + perilus_increment_time(); + perilus_set_clock(1); + perilus_eval(); + perilus_increment_time(); + } + } + pub fn reset(&self) { + unsafe { + perilus_set_reset(1); + self.pulse_clock(); + perilus_set_reset(0); + } + } + pub fn get_pc(&self) -> u32 { + unsafe { perilus_get_pc() } + } + pub fn set_pc(&self, new_pc: u32) { + unsafe { perilus_set_pc(new_pc) }; + } + pub fn get_control_unit_state(&self) -> u32 { + unsafe { perilus_get_control_unit_state() } + } + pub fn get_registers(&self) -> &'static [u32] { + unsafe { slice::from_raw_parts(perilus_get_register_file(), Perilus::NUM_REGISTERS) } + } + pub fn set_register(&self, register: Register, value: u32) { + unsafe { perilus_set_register(register.get(), value) }; + } + pub fn get_memory(&self) -> &'static [u32] { + unsafe { slice::from_raw_parts(perilus_get_memory(), Perilus::MEMORY_SIZE_WORDS) } + } + pub fn set_memory(&self, address: u32, value: u32) { + unsafe { perilus_set_memory(address, value) }; + } + pub fn get_memory_byte(&self, address_bytes: u32) -> u8 { + let word = self.get_memory()[(address_bytes / 4) as usize]; + (word >> ((address_bytes % 4) * 8)) as u8 + } + pub fn set_memory_byte(&self, address_bytes: u32, value: u8) { + let address_words = address_bytes / 4; + let shift = (address_bytes % 4) * 8; + let current = self.get_memory()[address_words as usize]; + let mask = !(0xffu32 << shift); + self.set_memory(address_words, (current & mask) | ((value as u32) << shift)); + } + pub fn memory_bytes(&self) -> Vec<u8> { + self.get_memory() + .iter() + .flat_map(|word| word.to_le_bytes()) + .collect() + } + pub fn load_bytes(&self, bytes: &[u8]) -> io::Result<()> { + if bytes.len() > Self::MEMORY_SIZE_BYTES { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Provided file is too large to fit in simulated memory", + )); + } + for (address_bytes, value) in bytes.iter().enumerate() { + self.set_memory_byte(address_bytes as u32, *value); + } + Ok(()) + } + pub fn load_file(&self, file: PathBuf) -> io::Result<()> { + self.load_bytes(&std::fs::read(file)?) + } + pub fn save_file(&self, file: PathBuf) -> io::Result<()> { + std::fs::write(file, self.memory_bytes()) + } +} + +impl Drop for Perilus { + fn drop(&mut self) { + unsafe { perilus_drop() }; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn memory_roundtrip() { + let perilus = Perilus::init(); + let data = [0xde, 0xad, 0xbe, 0xef, 0x01, 0x02, 0x03]; + perilus.load_bytes(&data).unwrap(); + assert_eq!(&perilus.memory_bytes()[..data.len()], &data); + + perilus.set_memory_byte(0, 0xaa); + assert_eq!(perilus.get_memory_byte(0), 0xaa); + + let oversized = vec![0u8; Perilus::MEMORY_SIZE_BYTES + 1]; + assert!(perilus.load_bytes(&oversized).is_err()); + } +} diff --git a/sim/src/wrapper.cpp b/sim/core/src/wrapper.cpp diff --git a/sim/gui/Cargo.toml b/sim/gui/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sim-gui" +version.workspace = true +edition.workspace = true + +[dependencies] +perilus-core = { path = "../core" } +eframe.workspace = true +egui.workspace = true +rfd.workspace = true diff --git a/sim/gui/src/app.rs b/sim/gui/src/app.rs @@ -0,0 +1,672 @@ +use std::ops::Range; +use std::time::{Duration, Instant}; + +use eframe::egui; +use egui::{Color32, FontId, Key, Modifiers}; +use perilus_core::perilus::{Perilus, Register}; + +use crate::state::{Focus, RunState, ViewMode, row_digits}; + +pub(crate) const FONT_SIZE: f32 = 16.0; +pub(crate) const ROW_H: f32 = 22.0; +pub(crate) const GROUP_GAP: f32 = 10.0; +pub(crate) const ADDR_W: f32 = 76.0; +pub(crate) const DIVIDER_GAP: f32 = 9.0; +pub(crate) const REG_LABEL_W: f32 = 58.0; +pub(crate) const REG_COL_GAP: f32 = 20.0; +pub(crate) const BYTES_PER_ROW: usize = 32; +pub(crate) const WORDS_PER_ROW: usize = 8; +pub(crate) const REG_COLS: usize = 4; +pub(crate) const REG_ROWS: usize = 8; +pub(crate) const NUM_CELLS: usize = REG_COLS * REG_ROWS; +pub(crate) const PC_COLOR: Color32 = Color32::from_rgb(40, 200, 40); + +const MAX_RUN_CYCLES: u64 = 50_000_000; +const FREE_RUN_BUDGET: Duration = Duration::from_millis(8); +const CTRL_SHIFT: Modifiers = Modifiers { + ctrl: true, + shift: true, + alt: false, + mac_cmd: false, + command: false, +}; + +// Hex keys for the nibble editor. +const HEX_KEYS: [(Key, u8); 16] = [ + (Key::Num0, 0), + (Key::Num1, 1), + (Key::Num2, 2), + (Key::Num3, 3), + (Key::Num4, 4), + (Key::Num5, 5), + (Key::Num6, 6), + (Key::Num7, 7), + (Key::Num8, 8), + (Key::Num9, 9), + (Key::A, 10), + (Key::B, 11), + (Key::C, 12), + (Key::D, 13), + (Key::E, 14), + (Key::F, 15), +]; + +#[derive(Clone, Copy)] +pub(crate) enum Direction { + Left, + Right, + Up, + Down, +} + +#[derive(Default)] +struct Actions { + step: bool, + next_instruction: bool, + reset: bool, + free_run: bool, + run_to_cursor: bool, + stop: bool, + focus_registers: bool, + focus_memory: bool, + focus_address: bool, + follow: bool, + names: bool, + view: bool, + set_pc_cursor: bool, + clear: bool, + group_left: bool, + group_right: bool, + page_up: bool, + page_down: bool, + left: bool, + right: bool, + up: bool, + down: bool, + backspace: bool, + nibble: Option<u8>, +} + +pub(crate) struct SimApp { + pub(crate) perilus: Perilus, + pub(crate) current_pc: u32, + pub(crate) run_state: RunState, + pub(crate) view: ViewMode, + pub(crate) show_aliases: bool, + pub(crate) focus: Focus, + /// Memory cursor: byte address and nibble (0 = high, 1 = low). + pub(crate) mem_addr: u32, + pub(crate) mem_nib: u8, + /// Register-grid cursor: cell index (0 = PC, 1..=31 = x1..x31) and nibble. + pub(crate) reg_index: u8, + pub(crate) reg_nib: u8, + pub(crate) address_input: String, + pub(crate) follow_pc: bool, + pub(crate) follow_pc_last: u32, + pub(crate) focus_address: bool, + pub(crate) scroll_to_row: Option<usize>, + pub(crate) mem_viewport: Range<usize>, + pub(crate) status: String, + run_cycles: u64, +} + +impl SimApp { + pub(crate) fn new() -> SimApp { + let perilus = Perilus::init(); + let current_pc = perilus.get_pc(); + SimApp { + perilus, + current_pc, + run_state: RunState::Idle, + view: ViewMode::Word, + show_aliases: true, + focus: Focus::Registers, + mem_addr: 3, + mem_nib: 0, + reg_index: 0, + reg_nib: 0, + address_input: String::new(), + follow_pc: false, + follow_pc_last: current_pc, + focus_address: false, + scroll_to_row: None, + mem_viewport: 0..0, + status: "Ready".into(), + run_cycles: 0, + } + } + + /// Captures the model PC once the control unit is back at an instruction boundary. + pub(crate) fn sync_pc(&mut self) { + if self.perilus.get_control_unit_state() == 0 { + self.current_pc = self.perilus.get_pc(); + } + } + + pub(crate) fn reset(&mut self) { + self.perilus.reset(); + self.run_state = RunState::Idle; + self.sync_pc(); + self.status = "Reset".into(); + } + + /// Pulse the clock exactly once. + pub(crate) fn step_cycle(&mut self) { + self.perilus.pulse_clock(); + self.sync_pc(); + self.status = "Stepped one cycle".into(); + } + + /// Run until the control unit returns to an instruction boundary. + pub(crate) fn next_instruction(&mut self) { + const MAX_STATES_PER_INSTRUCTION: u32 = 64; + self.perilus.pulse_clock(); + let mut states = 1; + while self.perilus.get_control_unit_state() != 0 && states < MAX_STATES_PER_INSTRUCTION { + self.perilus.pulse_clock(); + states += 1; + } + self.sync_pc(); + if self.perilus.get_control_unit_state() == 0 { + self.status = "Stepped one instruction".into(); + } else { + self.status = "Stopped: control unit did not return to fetch".into(); + } + } + + pub(crate) fn run_to_pc(&mut self, target: u32) { + self.run_cycles = 0; + self.run_state = RunState::RunToPc(target); + } + + pub(crate) fn run_to_input_pc(&mut self) { + match parse_hex(&self.address_input) { + Some(target) => self.run_to_pc(target), + None => self.status = format!("Invalid PC target {:?}", self.address_input), + } + } + + pub(crate) fn toggle_free_run(&mut self) { + self.run_state = match self.run_state { + RunState::FreeRun => RunState::Idle, + _ => RunState::FreeRun, + }; + } + + pub(crate) fn toggle_follow(&mut self) { + self.follow_pc = !self.follow_pc; + self.follow_pc_last = self.current_pc; + self.status = format!("Follow PC {}", if self.follow_pc { "on" } else { "off" }); + } + + pub(crate) fn stop(&mut self) { + if self.run_state != RunState::Idle { + self.status = "Stopped".into(); + } + self.run_state = RunState::Idle; + } + + pub(crate) fn save_memory(&mut self) { + if let Some(path) = rfd::FileDialog::new() + .set_file_name("memory.bin") + .save_file() + { + self.status = match self.perilus.save_file(path.clone()) { + Ok(()) => format!("Saved memory to {}", path.display()), + Err(e) => format!("Save failed: {e}"), + }; + } + } + + pub(crate) fn load_memory(&mut self) { + if let Some(path) = rfd::FileDialog::new().pick_file() { + self.load_path(path); + } + } + + pub(crate) fn load_path(&mut self, path: std::path::PathBuf) { + self.status = match self.perilus.load_file(path.clone()) { + Ok(()) => format!("Loaded memory from {}", path.display()), + Err(e) => format!("Load failed: {e}"), + }; + self.sync_pc(); + } + + pub(crate) fn jump_to_address(&mut self) { + match parse_hex(&self.address_input) { + Some(addr) => { + let addr = addr & (Perilus::MEMORY_SIZE_BYTES as u32 - 1); + self.mem_addr = addr; + self.mem_nib = 0; + self.scroll_to_row = Some(addr as usize / BYTES_PER_ROW); + self.focus = Focus::Memory; + self.status = format!("Selection moved to 0x{addr:08x}"); + } + None => self.status = format!("Invalid address {:?}", self.address_input), + } + } + + /// Word containing the memory cursor. + pub(crate) fn cursor_word(&self) -> u32 { + self.mem_addr & !3 + } + + pub(crate) fn set_pc_to_cursor(&mut self) { + let pc = self.cursor_word(); + self.perilus.set_pc(pc); + self.current_pc = pc; + self.status = format!("Set PC to 0x{pc:08x}"); + } + + pub(crate) fn run_to_cursor(&mut self) { + self.run_to_pc(self.cursor_word()); + } + + fn move_cursor(&mut self, direction: Direction) { + match self.focus { + Focus::Memory => self.move_memory(direction), + Focus::Registers => self.move_register(direction), + } + } + + fn move_memory(&mut self, direction: Direction) { + let order = row_digits(self.view); + let row = (self.mem_addr / BYTES_PER_ROW as u32) as usize; + let offset = self.mem_addr % BYTES_PER_ROW as u32; + let col = order + .iter() + .position(|&(o, n)| o == offset && n == self.mem_nib) + .unwrap_or(0); + let total_rows = Perilus::MEMORY_SIZE_WORDS / WORDS_PER_ROW; + let (row, col) = match direction { + Direction::Left if col == 0 && row > 0 => (row - 1, 63), + Direction::Left if col > 0 => (row, col - 1), + Direction::Right if col == 63 && row + 1 < total_rows => (row + 1, 0), + Direction::Right if col < 63 => (row, col + 1), + Direction::Up if row > 0 => (row - 1, col), + Direction::Down if row + 1 < total_rows => (row + 1, col), + _ => (row, col), + }; + self.mem_addr = row as u32 * BYTES_PER_ROW as u32 + order[col].0; + self.mem_nib = order[col].1; + } + + /// Move to the first digit of the previous/next word (word view) or byte + /// (byte view). + fn move_memory_group(&mut self, forward: bool) { + let order = row_digits(self.view); + let row = (self.mem_addr / BYTES_PER_ROW as u32) as usize; + let offset = self.mem_addr % BYTES_PER_ROW as u32; + let col = order + .iter() + .position(|&(o, n)| o == offset && n == self.mem_nib) + .unwrap_or(0); + let group = match self.view { + ViewMode::Word => 8, + ViewMode::Byte => 2, + }; + let groups_per_row = 64 / group; + let index = col / group; + let total_rows = Perilus::MEMORY_SIZE_WORDS / WORDS_PER_ROW; + let (row, col) = if forward { + if index + 1 < groups_per_row { + (row, (index + 1) * group) + } else if row + 1 < total_rows { + (row + 1, 0) + } else { + (row, col) + } + } else if index > 0 { + (row, (index - 1) * group) + } else if row > 0 { + (row - 1, (groups_per_row - 1) * group) + } else { + (row, col) + }; + self.mem_addr = row as u32 * BYTES_PER_ROW as u32 + order[col].0; + self.mem_nib = order[col].1; + } + + fn move_register(&mut self, direction: Direction) { + match direction { + Direction::Left if self.reg_nib == 0 && self.reg_index > 0 => { + self.reg_index -= 1; + self.reg_nib = 7; + } + Direction::Left if self.reg_nib > 0 => self.reg_nib -= 1, + Direction::Right if self.reg_nib == 7 && (self.reg_index as usize) < NUM_CELLS - 1 => { + self.reg_index += 1; + self.reg_nib = 0; + } + Direction::Right if self.reg_nib < 7 => self.reg_nib += 1, + Direction::Up if self.reg_index > 0 => self.reg_index -= 1, + Direction::Down if (self.reg_index as usize) < NUM_CELLS - 1 => self.reg_index += 1, + _ => {} + } + } + + fn edit_nibble(&mut self, nibble: u8) { + match self.focus { + Focus::Memory => { + let addr = self.mem_addr; + let byte = self.perilus.get_memory_byte(addr); + let byte = if self.mem_nib == 0 { + (byte & 0x0f) | (nibble << 4) + } else { + (byte & 0xf0) | nibble + }; + self.perilus.set_memory_byte(addr, byte); + self.move_memory(Direction::Right); + } + Focus::Registers => { + let shift = (7 - self.reg_nib as u32) * 4; + if self.reg_index == 0 { + let value = (self.current_pc & !(0xf << shift)) | ((nibble as u32) << shift); + self.perilus.set_pc(value); + self.current_pc = value; + } else { + let index = self.reg_index as usize; + let value = self.perilus.get_registers()[index]; + let value = (value & !(0xf << shift)) | ((nibble as u32) << shift); + if let Some(reg) = Register::new(index as u32) { + self.perilus.set_register(reg, value); + } + } + self.move_register(Direction::Right); + } + } + } + + fn backspace(&mut self) { + match self.focus { + Focus::Memory => { + let order = row_digits(self.view); + let offset = self.mem_addr % BYTES_PER_ROW as u32; + let col = order + .iter() + .position(|&(o, n)| o == offset && n == self.mem_nib) + .unwrap_or(0); + if self.mem_addr < BYTES_PER_ROW as u32 && col == 0 { + return; + } + let addr = self.mem_addr; + let byte = self.perilus.get_memory_byte(addr); + let byte = if self.mem_nib == 0 { + byte & 0x0f + } else { + byte & 0xf0 + }; + self.perilus.set_memory_byte(addr, byte); + self.move_memory(Direction::Left); + } + Focus::Registers => { + if self.reg_index == 0 && self.reg_nib == 0 { + return; + } + let shift = (7 - self.reg_nib as u32) * 4; + if self.reg_index == 0 { + let value = self.current_pc & !(0xf << shift); + self.perilus.set_pc(value); + self.current_pc = value; + } else { + let index = self.reg_index as usize; + let value = self.perilus.get_registers()[index] & !(0xf << shift); + if let Some(reg) = Register::new(index as u32) { + self.perilus.set_register(reg, value); + } + } + self.move_register(Direction::Left); + } + } + } + + fn clear_cursor(&mut self) { + match self.focus { + Focus::Memory => match self.view { + ViewMode::Word => { + let word = self.mem_addr / 4; + self.perilus.set_memory(word, 0); + self.status = format!("Cleared word 0x{:08x}", word * 4); + } + ViewMode::Byte => { + self.perilus.set_memory_byte(self.mem_addr, 0); + self.status = format!("Cleared byte 0x{:08x}", self.mem_addr); + } + }, + Focus::Registers => { + if self.reg_index == 0 { + self.perilus.set_pc(0); + self.current_pc = 0; + self.status = "Cleared PC".into(); + } else if let Some(reg) = Register::new(self.reg_index as u32) { + self.perilus.set_register(reg, 0); + self.status = format!("Cleared x{}", self.reg_index); + } + } + } + } + + fn scroll_page(&mut self, down: bool) { + let total_rows = Perilus::MEMORY_SIZE_WORDS / WORDS_PER_ROW; + let page = self.mem_viewport.len().max(1) as isize; + let top = self.mem_viewport.start as isize; + let new_top = if down { + (top + page).min(total_rows as isize - 1) + } else { + (top - page).max(0) + }; + self.scroll_to_row = Some(new_top as usize); + } + + fn handle_keys(&mut self, ui: &egui::Ui) { + let ctx = ui.ctx(); + if ctx.text_edit_focused() { + return; + } + let actions = ctx.input_mut(|i| { + let mut actions = Actions { + step: i.consume_key(Modifiers::NONE, Key::Space), + stop: i.consume_key(Modifiers::NONE, Key::Escape), + backspace: i.consume_key(Modifiers::NONE, Key::Backspace), + next_instruction: i.consume_key(Modifiers::NONE, Key::N), + focus_address: i.consume_key(Modifiers::NONE, Key::G), + names: i.consume_key(Modifiers::NONE, Key::X), + view: i.consume_key(Modifiers::NONE, Key::V), + clear: i.consume_key(Modifiers::SHIFT, Key::C), + follow: i.consume_key(Modifiers::SHIFT, Key::P), + set_pc_cursor: i.consume_key(Modifiers::NONE, Key::P), + ..Default::default() + }; + actions.run_to_cursor = i.consume_key(CTRL_SHIFT, Key::Space); + actions.free_run = i.consume_key(Modifiers::CTRL, Key::Space); + actions.reset = i.consume_key(Modifiers::CTRL, Key::R); + actions.focus_registers = i.consume_key(Modifiers::NONE, Key::R); + actions.focus_memory = i.consume_key(Modifiers::NONE, Key::M); + actions.group_left = i.consume_key(Modifiers::CTRL, Key::ArrowLeft) + || i.consume_key(Modifiers::CTRL, Key::H); + actions.group_right = i.consume_key(Modifiers::CTRL, Key::ArrowRight) + || i.consume_key(Modifiers::CTRL, Key::L); + actions.page_up = i.consume_key(Modifiers::NONE, Key::PageUp) + || i.consume_key(Modifiers::CTRL, Key::U); + actions.page_down = i.consume_key(Modifiers::NONE, Key::PageDown) + || i.consume_key(Modifiers::CTRL, Key::D); + actions.left = i.consume_key(Modifiers::NONE, Key::ArrowLeft) + || i.consume_key(Modifiers::NONE, Key::H); + actions.right = i.consume_key(Modifiers::NONE, Key::ArrowRight) + || i.consume_key(Modifiers::NONE, Key::L); + actions.up = i.consume_key(Modifiers::NONE, Key::ArrowUp) + || i.consume_key(Modifiers::NONE, Key::K); + actions.down = i.consume_key(Modifiers::NONE, Key::ArrowDown) + || i.consume_key(Modifiers::NONE, Key::J); + for (key, value) in HEX_KEYS { + if i.consume_key(Modifiers::NONE, key) { + actions.nibble = Some(value); + } + } + actions + }); + + if actions.run_to_cursor { + self.run_to_cursor(); + } + if actions.free_run { + self.toggle_free_run(); + } + if actions.step { + self.step_cycle(); + } + if actions.next_instruction { + self.next_instruction(); + } + if actions.reset { + self.reset(); + } + if actions.focus_registers { + self.focus = Focus::Registers; + } + if actions.focus_memory { + self.focus = Focus::Memory; + } + if actions.set_pc_cursor { + self.set_pc_to_cursor(); + } + if actions.stop { + self.stop(); + } + if actions.focus_address { + self.focus_address = true; + } + if actions.follow { + self.toggle_follow(); + } + if actions.names { + self.show_aliases = !self.show_aliases; + } + if actions.view { + self.view = match self.view { + ViewMode::Word => ViewMode::Byte, + ViewMode::Byte => ViewMode::Word, + }; + } + if actions.clear { + self.clear_cursor(); + } + if actions.group_left && self.focus == Focus::Memory { + self.move_memory_group(false); + } + if actions.group_right && self.focus == Focus::Memory { + self.move_memory_group(true); + } + if actions.page_up { + self.scroll_page(false); + } + if actions.page_down { + self.scroll_page(true); + } + let direction = if actions.left { + Some(Direction::Left) + } else if actions.right { + Some(Direction::Right) + } else if actions.up { + Some(Direction::Up) + } else if actions.down { + Some(Direction::Down) + } else { + None + }; + if let Some(direction) = direction { + self.move_cursor(direction); + } + if let Some(nibble) = actions.nibble { + self.edit_nibble(nibble); + } + if actions.backspace { + self.backspace(); + } + } +} + +impl eframe::App for SimApp { + fn logic(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + match self.run_state { + RunState::Idle => {} + RunState::FreeRun => { + let start = Instant::now(); + while start.elapsed() < FREE_RUN_BUDGET { + self.perilus.pulse_clock(); + } + self.sync_pc(); + ctx.request_repaint(); + } + RunState::RunToPc(target) => { + let start = Instant::now(); + loop { + if self.perilus.get_control_unit_state() == 0 && self.perilus.get_pc() == target + { + self.status = format!("Reached PC 0x{target:08x}"); + self.run_state = RunState::Idle; + break; + } + self.perilus.pulse_clock(); + self.run_cycles += 1; + if self.run_cycles >= MAX_RUN_CYCLES { + self.status = format!( + "Stopped: did not reach PC 0x{target:08x} after {MAX_RUN_CYCLES} cycles" + ); + self.run_state = RunState::Idle; + break; + } + if start.elapsed() >= FREE_RUN_BUDGET { + ctx.request_repaint(); + break; + } + } + self.sync_pc(); + } + } + } + + fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { + self.handle_keys(ui); + let top_frame = egui::Frame::side_top_panel(ui.style()).shadow(egui::Shadow::NONE); + egui::Panel::top("registers_panel") + .frame(top_frame) + .show_separator_line(false) + .show(ui, |ui| { + ui.add_space(4.0); + self.registers_ui(ui); + ui.add_space(4.0); + }); + let bottom_frame = egui::Frame::side_top_panel(ui.style()).shadow(egui::Shadow::NONE); + egui::Panel::bottom("controls_panel") + .frame(bottom_frame) + .show_separator_line(false) + .show(ui, |ui| { + ui.add_space(4.0); + self.controls_ui(ui); + ui.add_space(4.0); + }); + egui::CentralPanel::default().show(ui, |ui| { + self.memory_ui(ui); + }); + } +} + +pub(crate) fn char_width(ui: &egui::Ui, font: &FontId) -> f32 { + ui.painter() + .layout_no_wrap("0".to_owned(), font.clone(), Color32::WHITE) + .size() + .x +} + +fn parse_hex(text: &str) -> Option<u32> { + let trimmed = text.trim(); + let digits = trimmed + .strip_prefix("0x") + .or_else(|| trimmed.strip_prefix("0X")) + .unwrap_or(trimmed); + if digits.is_empty() { + return None; + } + u32::from_str_radix(digits, 16).ok() +} diff --git a/sim/gui/src/main.rs b/sim/gui/src/main.rs @@ -0,0 +1,32 @@ +mod app; +mod state; +mod ui; + +use std::path::PathBuf; + +use app::{FONT_SIZE, SimApp}; + +fn main() -> eframe::Result { + let file = std::env::args_os().nth(1).map(PathBuf::from); + let options = eframe::NativeOptions { + viewport: eframe::egui::ViewportBuilder::default() + .with_inner_size([1420.0, 900.0]) + .with_min_inner_size([900.0, 480.0]) + .with_title("perilus"), + ..Default::default() + }; + eframe::run_native( + "perilus", + options, + Box::new(move |cc| { + cc.egui_ctx.all_styles_mut(|style| { + style.override_font_id = Some(eframe::egui::FontId::monospace(FONT_SIZE)); + }); + let mut app = SimApp::new(); + if let Some(file) = file { + app.load_path(file); + } + Ok(Box::new(app)) + }), + ) +} diff --git a/sim/gui/src/state.rs b/sim/gui/src/state.rs @@ -0,0 +1,143 @@ +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) enum RunState { + Idle, + FreeRun, + RunToPc(u32), +} + +impl std::fmt::Display for RunState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RunState::Idle => write!(f, "Idle"), + RunState::FreeRun => write!(f, "Running"), + RunState::RunToPc(pc) => write!(f, "Run to 0x{pc:08x}"), + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) enum ViewMode { + Word, + Byte, +} + +/// Which pane receives keyboard editing. +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) enum Focus { + Registers, + Memory, +} + +pub(crate) fn register_alias(index: usize) -> &'static str { + match index { + 0 => "zero", + 1 => "ra", + 2 => "sp", + 3 => "gp", + 4 => "tp", + 5 => "t0", + 6 => "t1", + 7 => "t2", + 8 => "s0/fp", + 9 => "s1", + 10 => "a0", + 11 => "a1", + 12 => "a2", + 13 => "a3", + 14 => "a4", + 15 => "a5", + 16 => "a6", + 17 => "a7", + 18 => "s2", + 19 => "s3", + 20 => "s4", + 21 => "s5", + 22 => "s6", + 23 => "s7", + 24 => "s8", + 25 => "s9", + 26 => "s10", + 27 => "s11", + 28 => "t3", + 29 => "t4", + 30 => "t5", + 31 => "t6", + _ => "??", + } +} + +pub(crate) fn printable(byte: u8) -> char { + if (b' '..=b'~').contains(&byte) { + byte as char + } else { + '.' + } +} + +pub(crate) fn hex_char(nibble: u8) -> char { + std::char::from_digit(nibble as u32, 16).unwrap_or('?') +} + +/// Screen order of the 64 hex digits in one memory row, as +/// `(byte offset within the row, nibble index)` where nibble 0 is the high +/// nibble of the byte and 1 is the low nibble. +/// +/// Word view prints each 32-bit word big-endian, so the bytes within a word +/// appear in descending address order. Byte view prints bytes in ascending +/// memory order. +pub(crate) fn row_digits(view: ViewMode) -> [(u32, u8); 64] { + let mut out = [(0u32, 0u8); 64]; + let mut i = 0; + match view { + ViewMode::Word => { + for word in 0..8u32 { + for byte in (0..4u32).rev() { + out[i] = (word * 4 + byte, 0); + i += 1; + out[i] = (word * 4 + byte, 1); + i += 1; + } + } + } + ViewMode::Byte => { + for byte in 0..32u32 { + out[i] = (byte, 0); + i += 1; + out[i] = (byte, 1); + i += 1; + } + } + } + out +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn aliases_cover_register_file() { + assert_eq!(register_alias(0), "zero"); + assert_eq!(register_alias(8), "s0/fp"); + assert_eq!(register_alias(17), "a7"); + assert_eq!(register_alias(31), "t6"); + } + + #[test] + fn printable_only_decodes_ascii() { + assert_eq!(printable(b'A'), 'A'); + assert_eq!(printable(b' '), ' '); + assert_eq!(printable(0), '.'); + assert_eq!(printable(0x7f), '.'); + } + + #[test] + fn row_digit_order() { + let word = row_digits(ViewMode::Word); + assert_eq!(word[0], (3, 0)); + assert_eq!(word[7], (0, 1)); + let byte = row_digits(ViewMode::Byte); + assert_eq!(byte[0], (0, 0)); + assert_eq!(byte[63], (31, 1)); + } +} diff --git a/sim/gui/src/ui/controls.rs b/sim/gui/src/ui/controls.rs @@ -0,0 +1,47 @@ +use eframe::egui; +use egui::Ui; + +use crate::app::SimApp; +use crate::state::RunState; + +impl SimApp { + pub(crate) fn controls_ui(&mut self, ui: &mut Ui) { + // Two rows keep the controls within the width of the memory view. + ui.horizontal_wrapped(|ui| { + if ui.button("Reset [ctrl+r]").clicked() { + self.reset(); + } + if ui.button("Step cycle [space]").clicked() { + self.step_cycle(); + } + if ui.button("Next instruction [n]").clicked() { + self.next_instruction(); + } + let free_run_label = if self.run_state == RunState::FreeRun { + "Stop [ctrl+space]" + } else { + "Free run [ctrl+space]" + }; + if ui.button(free_run_label).clicked() { + self.toggle_free_run(); + } + }); + ui.horizontal_wrapped(|ui| { + if ui.button("Set PC to cursor [p]").clicked() { + self.set_pc_to_cursor(); + } + if ui.button("Run to cursor [ctrl+shift+space]").clicked() { + self.run_to_cursor(); + } + if ui.button("Run to PC").clicked() { + self.run_to_input_pc(); + } + if ui.button("Load memory").clicked() { + self.load_memory(); + } + if ui.button("Save memory").clicked() { + self.save_memory(); + } + }); + } +} diff --git a/sim/gui/src/ui/memory.rs b/sim/gui/src/ui/memory.rs @@ -0,0 +1,220 @@ +use eframe::egui; +use egui::{Align2, FontId, Key, Rect, Sense, Stroke, TextEdit, Ui, pos2, vec2}; +use perilus_core::perilus::Perilus; + +use crate::app::{ + ADDR_W, BYTES_PER_ROW, DIVIDER_GAP, FONT_SIZE, GROUP_GAP, PC_COLOR, ROW_H, SimApp, + WORDS_PER_ROW, char_width, +}; +use crate::state::{Focus, ViewMode, hex_char, printable, row_digits}; + +fn divider(ui: &mut Ui) { + let (rect, _) = ui.allocate_exact_size(vec2(DIVIDER_GAP * 2.0, ROW_H), Sense::hover()); + let color = ui.visuals().weak_text_color(); + let spacing = ui.spacing().item_spacing.y; + ui.painter().line_segment( + [ + pos2(rect.center().x, rect.top() - spacing * 0.5), + pos2(rect.center().x, rect.bottom() + spacing * 0.5), + ], + Stroke::new(1.0, color), + ); +} + +impl SimApp { + pub(crate) fn memory_ui(&mut self, ui: &mut Ui) { + let font = FontId::monospace(FONT_SIZE); + let nib_w = char_width(ui, &font); + + ui.horizontal_wrapped(|ui| { + ui.strong("Memory"); + ui.toggle_value(&mut self.show_aliases, "ABI names [x]"); + let mut byte_view = self.view == ViewMode::Byte; + if ui.toggle_value(&mut byte_view, "Byte view [v]").changed() { + self.view = if byte_view { + ViewMode::Byte + } else { + ViewMode::Word + }; + } + let mut follow = self.follow_pc; + if ui + .toggle_value(&mut follow, "Follow PC [shift+p]") + .changed() + { + self.follow_pc = follow; + self.follow_pc_last = self.current_pc; + self.status = format!("Follow PC {}", if follow { "on" } else { "off" }); + } + ui.separator(); + ui.label("addr"); + let response = ui.add( + TextEdit::singleline(&mut self.address_input) + .desired_width(90.0) + .hint_text("hex"), + ); + if std::mem::take(&mut self.focus_address) { + response.request_focus(); + } + if response.lost_focus() && ui.input(|i| i.key_pressed(Key::Enter)) { + self.jump_to_address(); + } + if ui.button("Go [g]").clicked() { + self.jump_to_address(); + } + ui.separator(); + ui.label(format!("selected 0x{:08x}", self.mem_addr)); + }); + ui.separator(); + + if self.follow_pc && self.current_pc != self.follow_pc_last { + self.follow_pc_last = self.current_pc; + let pc_row = self.current_pc as usize / BYTES_PER_ROW; + if !self.mem_viewport.contains(&pc_row) { + self.scroll_to_row = Some(pc_row); + } + } + + let row_pitch = ROW_H + ui.spacing().item_spacing.y; + let mut area = egui::ScrollArea::both().auto_shrink([false, false]); + if let Some(row) = self.scroll_to_row.take() { + area = area.vertical_scroll_offset(row as f32 * row_pitch); + } + let total_rows = Perilus::MEMORY_SIZE_WORDS / WORDS_PER_ROW; + area.show_rows(ui, ROW_H, total_rows, |ui, rows| { + self.mem_viewport = rows.clone(); + for row in rows { + self.memory_row(ui, row, nib_w, &font); + } + }); + } + + fn memory_row(&mut self, ui: &mut Ui, row: usize, nib_w: f32, font: &FontId) { + let row_addr = (row * BYTES_PER_ROW) as u32; + ui.horizontal(|ui| { + let text_color = ui.visuals().text_color(); + let background = ui.visuals().panel_fill; + let pc = self.current_pc; + let focus_memory = self.focus == Focus::Memory; + let cursor_in_row = + focus_memory && (self.mem_addr / BYTES_PER_ROW as u32) as usize == row; + let cursor_index = (self.mem_addr % BYTES_PER_ROW as u32) as usize; + + let (addr_rect, _) = ui.allocate_exact_size(vec2(ADDR_W, ROW_H), Sense::hover()); + ui.painter().text( + addr_rect.left_center(), + Align2::LEFT_CENTER, + format!("{row_addr:08x}"), + font.clone(), + text_color, + ); + divider(ui); + + let group = match self.view { + ViewMode::Word => 8, + ViewMode::Byte => 2, + }; + let gaps = (64 / group - 1) as f32; + let digit_w = 64.0 * nib_w + gaps * GROUP_GAP; + let (digits_rect, digits_response) = + ui.allocate_exact_size(vec2(digit_w, ROW_H), Sense::click()); + + let order = row_digits(self.view); + let cursor = (self.mem_addr, self.mem_nib); + let mut cells: Vec<(Rect, u32, u8)> = Vec::with_capacity(64); + let mut x = digits_rect.left(); + for (i, &(offset, nib)) in order.iter().enumerate() { + if i > 0 && i % group == 0 { + x += GROUP_GAP; + } + let cell = Rect::from_min_size(pos2(x, digits_rect.top()), vec2(nib_w, ROW_H)); + let addr = row_addr + offset; + let byte = self.perilus.get_memory_byte(addr); + let digit = if nib == 0 { byte >> 4 } else { byte & 0xf }; + if focus_memory && (addr, nib) == cursor { + ui.painter().rect_filled(cell, 0.0, text_color); + ui.painter().text( + cell.center(), + Align2::CENTER_CENTER, + hex_char(digit), + font.clone(), + background, + ); + } else { + let color = if (addr & !3) == (pc & !3) { + PC_COLOR + } else { + text_color + }; + ui.painter().text( + cell.center(), + Align2::CENTER_CENTER, + hex_char(digit), + font.clone(), + color, + ); + } + cells.push((cell, addr, nib)); + x += nib_w; + } + + if let Some(pos) = digits_response.interact_pointer_pos() + && (digits_response.clicked() || digits_response.double_clicked()) + && let Some(&(_, addr, nib)) = cells.iter().find(|(rect, _, _)| rect.contains(pos)) + { + self.mem_addr = addr; + self.mem_nib = nib; + self.focus = Focus::Memory; + if digits_response.double_clicked() { + self.set_pc_to_cursor(); + } + } + + divider(ui); + + let ascii: Vec<char> = match self.view { + ViewMode::Word => (0..WORDS_PER_ROW) + .flat_map(|word| { + self.perilus.get_memory()[row * WORDS_PER_ROW + word].to_le_bytes() + }) + .map(printable) + .collect(), + ViewMode::Byte => (0..BYTES_PER_ROW) + .map(|i| printable(self.perilus.get_memory_byte(row_addr + i as u32))) + .collect(), + }; + let ascii_width = ascii.len() as f32 * nib_w; + let (ascii_rect, _) = ui.allocate_exact_size(vec2(ascii_width, ROW_H), Sense::hover()); + let painter = ui.painter(); + for (i, ch) in ascii.iter().enumerate() { + let cell = Rect::from_min_size( + pos2(ascii_rect.left() + i as f32 * nib_w, ascii_rect.top()), + vec2(nib_w, ROW_H), + ); + if cursor_in_row && i == cursor_index { + painter.rect_filled(cell, 0.0, text_color); + painter.text( + cell.center(), + Align2::CENTER_CENTER, + *ch, + font.clone(), + background, + ); + } else { + let color = if (row_addr + i as u32) & !3 == pc & !3 { + PC_COLOR + } else { + text_color + }; + painter.text( + cell.center(), + Align2::CENTER_CENTER, + *ch, + font.clone(), + color, + ); + } + } + }); + } +} diff --git a/sim/gui/src/ui/mod.rs b/sim/gui/src/ui/mod.rs @@ -0,0 +1,3 @@ +mod controls; +mod memory; +mod registers; diff --git a/sim/gui/src/ui/registers.rs b/sim/gui/src/ui/registers.rs @@ -0,0 +1,105 @@ +use eframe::egui; +use egui::{Align2, FontId, Rect, Sense, Ui, pos2, vec2}; + +use crate::app::{ + FONT_SIZE, NUM_CELLS, PC_COLOR, REG_COL_GAP, REG_COLS, REG_LABEL_W, REG_ROWS, ROW_H, SimApp, + char_width, +}; +use crate::state::{Focus, hex_char, register_alias}; + +impl SimApp { + pub(crate) fn registers_ui(&mut self, ui: &mut Ui) { + ui.horizontal_wrapped(|ui| { + ui.label(format!("state: {}", self.run_state)); + ui.separator(); + ui.label(format!("cu: {}", self.perilus.get_control_unit_state())); + ui.separator(); + ui.label(self.status.as_str()); + }); + ui.add_space(4.0); + + let font = FontId::monospace(FONT_SIZE); + let nib_w = char_width(ui, &font); + let cell_w = REG_LABEL_W + 8.0 * nib_w + REG_COL_GAP; + let grid_size = vec2(cell_w * REG_COLS as f32, ROW_H * REG_ROWS as f32); + let (grid_rect, response) = ui.allocate_exact_size(grid_size, Sense::click()); + + let text_color = ui.visuals().text_color(); + let background = ui.visuals().panel_fill; + let painter = ui.painter(); + let registers = self.perilus.get_registers(); + let focus_registers = self.focus == Focus::Registers; + for col in 0..REG_COLS { + for row in 0..REG_ROWS { + let cell_index = col * REG_ROWS + row; + let origin = pos2( + grid_rect.left() + col as f32 * cell_w, + grid_rect.top() + row as f32 * ROW_H, + ); + let (label, value, color) = if cell_index == 0 { + ("pc".to_string(), self.current_pc, PC_COLOR) + } else { + let label = if self.show_aliases { + register_alias(cell_index).to_string() + } else { + format!("x{cell_index}") + }; + (label, registers[cell_index], text_color) + }; + painter.text( + pos2(origin.x, origin.y + ROW_H * 0.5), + Align2::LEFT_CENTER, + label, + font.clone(), + text_color, + ); + for nib in 0..8u8 { + let digit = ((value >> ((7 - nib as u32) * 4)) & 0xf) as u8; + let cell = Rect::from_min_size( + pos2(origin.x + REG_LABEL_W + nib as f32 * nib_w, origin.y), + vec2(nib_w, ROW_H), + ); + let selected = focus_registers + && cell_index as u8 == self.reg_index + && nib == self.reg_nib; + if selected { + painter.rect_filled(cell, 0.0, text_color); + painter.text( + cell.center(), + Align2::CENTER_CENTER, + hex_char(digit), + font.clone(), + background, + ); + } else { + painter.text( + cell.center(), + Align2::CENTER_CENTER, + hex_char(digit), + font.clone(), + color, + ); + } + } + } + } + + if response.clicked() + && let Some(pos) = response.interact_pointer_pos() + { + let x = pos.x - grid_rect.left(); + let y = pos.y - grid_rect.top(); + if x >= 0.0 && y >= 0.0 { + let col = (x / cell_w) as usize; + let row = (y / ROW_H) as usize; + let x_in_cell = x - col as f32 * cell_w; + if col < REG_COLS && row < REG_ROWS && x_in_cell >= REG_LABEL_W { + let nib = (((x_in_cell - REG_LABEL_W) / nib_w) as usize).min(7); + self.reg_index = (col * REG_ROWS + row).min(NUM_CELLS - 1) as u8; + self.reg_nib = nib as u8; + self.focus = Focus::Registers; + } + } + } + } +} diff --git a/sim/src/main.rs b/sim/src/main.rs @@ -1,469 +0,0 @@ -use std::{error::Error, fmt::Display, path::PathBuf, time::Duration}; - -use clap::{Parser, Subcommand}; -use crossterm::event::{self, Event, KeyCode, KeyEvent}; -use ratatui::{ - DefaultTerminal, Frame, - buffer::Buffer, - layout::Rect, - style::{Color, Style}, - widgets::{Paragraph, Widget}, -}; - -use crate::perilus::{MemoryIndex, Perilus, Register}; - -mod perilus; - -#[derive(Parser)] -struct Cli { - #[command(subcommand)] - command: Option<Command>, -} - -#[derive(Subcommand)] -enum Command { - Interactive { - /// File to load verbatim into memory starting at 0x0 - file: Option<PathBuf>, - }, - Test { - file: PathBuf, - }, -} - -enum Mode { - Normal, - EditPc, - EditRegister, - EditMemory, -} - -#[derive(PartialEq)] -enum RunState { - Idle, - Step { ignore_current_state: bool }, - RunTo { index: u32 }, - Run, -} - -impl Display for RunState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - RunState::Idle => write!(f, "Idle"), - RunState::Step { .. } => write!(f, "Step"), - RunState::RunTo { index } => write!(f, "Run to 0x{:08x}", index * 4), - RunState::Run => write!(f, "Run"), - } - } -} - -struct App { - perilus: Perilus, - current_pc: u32, - show_register_aliases: bool, - register_cursor: Register, - memory_cursor: MemoryIndex, - memory_top: MemoryIndex, - memory_bottom: MemoryIndex, - mode: Mode, - run_state: RunState, - exit: bool, -} - -impl App { - fn new(perilus: Perilus) -> App { - let current_pc = perilus.get_pc(); - App { - perilus, - current_pc, - show_register_aliases: true, - register_cursor: Register::const_new::<0>(), - memory_cursor: MemoryIndex::const_new::<0>(), - memory_top: MemoryIndex::const_new::<0>(), - memory_bottom: MemoryIndex::const_new::<0>(), - mode: Mode::Normal, - run_state: RunState::Idle, - exit: false, - } - } - fn run(&mut self, terminal: &mut DefaultTerminal) -> std::io::Result<()> { - while !self.exit { - let num_visible_memory_words = terminal - .get_frame() - .area() - .height - .saturating_sub(9) - .saturating_mul(8); - self.memory_bottom = self.memory_top + num_visible_memory_words as u32; - if self.memory_cursor <= self.memory_top { - self.memory_top = self.memory_cursor; - self.memory_bottom = self.memory_top + num_visible_memory_words as u32; - } else if self.memory_cursor >= self.memory_bottom { - self.memory_bottom = self.memory_cursor.saturating_add(8); - self.memory_top = self - .memory_bottom - .saturating_sub(num_visible_memory_words as u32); - } - self.memory_top -= self.memory_top % 8; - self.memory_bottom -= self.memory_bottom % 8; - terminal.draw(|frame| self.draw(frame))?; - self.handle_events(self.run_state != RunState::Idle)?; - self.run_state = match self.run_state { - RunState::Idle => RunState::Idle, - RunState::Step { - ignore_current_state, - } => { - if self.perilus.get_control_unit_state() == 0 && !ignore_current_state { - RunState::Idle - } else { - self.perilus.pulse_clock(); - RunState::Step { - ignore_current_state: false, - } - } - } - RunState::RunTo { index } => { - if let Mode::EditMemory = self.mode - && self.current_pc != index.saturating_mul(4) - { - self.perilus.pulse_clock(); - RunState::RunTo { index } - } else { - RunState::Idle - } - } - RunState::Run => { - self.perilus.pulse_clock(); - RunState::Run - } - }; - if self.perilus.get_control_unit_state() == 0 { - self.current_pc = self.perilus.get_pc(); - } - } - Ok(()) - } - fn draw(&self, frame: &mut Frame) { - frame.render_widget(self, frame.area()); - } - fn handle_events(&mut self, poll: bool) -> std::io::Result<()> { - let event_ready = event::poll(Duration::from_millis(15))?; - if (!poll || event_ready) - && let Event::Key(k) = event::read()? - { - self.handle_key_event(k) - } - Ok(()) - } - fn handle_key_event(&mut self, key_event: KeyEvent) { - match key_event.code { - KeyCode::Char('q') => { - self.exit = true; - } - KeyCode::Char('R') => self.perilus.reset(), - KeyCode::Char('n') => { - self.show_register_aliases = !self.show_register_aliases; - } - KeyCode::Char(' ') => self.perilus.pulse_clock(), - KeyCode::Char('F') => { - self.run_state = RunState::Step { - ignore_current_state: true, - }; - } - KeyCode::Char('T') => { - if let Mode::EditMemory = self.mode { - self.run_state = RunState::RunTo { - index: self.memory_cursor.get(), - }; - } - } - KeyCode::Char('G') => { - self.run_state = RunState::Run; - } - - KeyCode::Esc => { - self.mode = Mode::Normal; - self.run_state = RunState::Idle; - } - KeyCode::Char('r') => { - if self.register_cursor == 0 { - self.mode = Mode::EditPc; - } else { - self.mode = Mode::EditRegister; - } - } - KeyCode::Char('m') => { - self.mode = Mode::EditMemory; - } - - KeyCode::Char('k') | KeyCode::Up => match self.mode { - Mode::Normal | Mode::EditPc => (), - Mode::EditRegister => { - if self.register_cursor % 8 != 0 { - self.register_cursor = self.register_cursor.saturating_sub(1) - } - if self.register_cursor == 0 { - self.mode = Mode::EditPc; - } - } - Mode::EditMemory => { - if self.memory_cursor >= 8 { - self.memory_cursor = self.memory_cursor.saturating_sub(8); - } - } - }, - KeyCode::Char('j') | KeyCode::Down => match self.mode { - Mode::Normal => (), - Mode::EditPc => { - self.mode = Mode::EditRegister; - self.register_cursor = Register::const_new::<1>() - } - Mode::EditRegister => { - if self.register_cursor % 8 != 7 { - self.register_cursor = self.register_cursor.saturating_add(1); - } - } - Mode::EditMemory => { - if self.memory_cursor <= 1016 { - self.memory_cursor = self.memory_cursor.saturating_add(8); - } - } - }, - KeyCode::Char('h') | KeyCode::Left => match self.mode { - Mode::Normal | Mode::EditPc => (), - Mode::EditRegister => { - if self.register_cursor > 7 { - self.register_cursor = self.register_cursor.saturating_sub(8); - } - if self.register_cursor == 0 { - self.mode = Mode::EditPc; - } - } - Mode::EditMemory => { - if self.memory_cursor % 8 != 0 { - self.memory_cursor = self.memory_cursor.saturating_sub(1); - } - } - }, - KeyCode::Char('l') | KeyCode::Right => match self.mode { - Mode::Normal => (), - Mode::EditPc => { - self.mode = Mode::EditRegister; - self.register_cursor = Register::const_new::<8>(); - } - Mode::EditRegister => { - if self.register_cursor < 24 { - self.register_cursor = - (self.register_cursor + 8).min(Register::const_new::<31>()); - } - } - Mode::EditMemory => { - if self.memory_cursor % 8 != 7 { - self.memory_cursor = self.memory_cursor.saturating_add(1); - } - } - }, - KeyCode::Char(n) - if [ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', - ] - .contains(&n) => - { - let new_nibble = n.to_digit(16).unwrap(); - match self.mode { - Mode::Normal => (), - Mode::EditPc => { - let current_value = self.perilus.get_pc(); - let new_value = (current_value << 4) + new_nibble; - self.perilus.set_pc(new_value); - self.current_pc = self.perilus.get_pc(); - } - Mode::EditRegister => { - let current_value = - self.perilus.get_registers()[self.register_cursor.get() as usize]; - let new_value = (current_value << 4) + new_nibble; - self.perilus.set_register(self.register_cursor, new_value); - } - Mode::EditMemory => { - let current_value = - self.perilus.get_memory()[self.memory_cursor.get() as usize]; - let new_value = (current_value << 4) + new_nibble; - self.perilus.set_memory(self.memory_cursor.get(), new_value); - } - } - } - KeyCode::Char('C') => match self.mode { - Mode::Normal => (), - Mode::EditPc => self.perilus.set_pc(0), - Mode::EditRegister => self.perilus.set_register(self.register_cursor, 0), - Mode::EditMemory => self.perilus.set_memory(self.memory_cursor.get(), 0), - }, - KeyCode::Char('J') => { - if let Mode::EditMemory = self.mode { - self.perilus.set_pc(self.memory_cursor.get() * 4); - } - } - _ => (), - } - } - // TODO move this method to Register - fn register_alias(reg: Register) -> String { - match reg.get() { - 0 => "zero".into(), - 1 => "ra".into(), - 2 => "sp".into(), - 3 => "gp".into(), - 4 => "tp".into(), - r if (5..=7).contains(&r) => format!("t{}", r - 5), - 8 => "s0/fp".into(), - 9 => "s1".into(), - r if (10..=17).contains(&r) => format!("a{}", r - 10), - r if (18..=27).contains(&r) => format!("s{}", r - 16), - r if (28..=31).contains(&r) => format!("t{}", r - 25), - r => unreachable!("got invalid register '{r}'"), - } - } -} - -impl Widget for &App { - fn render(self, _area: Rect, buf: &mut Buffer) { - let run_state_area = Rect::new(72, 6, 27, 1); - Paragraph::new(format!("run state {}", self.run_state)).render(run_state_area, buf); - let control_unit_state_area = Rect::new(72, 7, 27, 1); - Paragraph::new(format!( - " cu state {:<2}", - self.perilus.get_control_unit_state() - )) - .render(control_unit_state_area, buf); - let pc_area = Rect::new(0, 0, 17, 1); - let mut pc_style = Style::default().fg(Color::Green); - if let Mode::EditPc = self.mode { - pc_style = pc_style.fg(Color::Black).bg(Color::Gray); - } - Paragraph::new(format!(" pc {:08x}", self.current_pc)) - .style(pc_style) - .render(pc_area, buf); - let register_file = self.perilus.get_registers(); - for (r, reg) in register_file.iter().enumerate() { - if r == 0 { - continue; - } - let reg_area = Rect::new(r as u16 / 8 * 18, r as u16 % 8, 17, 1); - let mut reg_style = Style::default(); - if let Mode::EditRegister = self.mode - && self.register_cursor.get() == r as u32 - { - reg_style = reg_style.fg(Color::Black).bg(Color::Gray); - } - let reg_name = if self.show_register_aliases { - App::register_alias(Register::new(r as u32).unwrap()) - } else { - format!("x{r}") - }; - Paragraph::new(format!("{reg_name:>8} {reg:08x}")) - .style(reg_style) - .render(reg_area, buf); - } - let memory = self.perilus.get_memory(); - for offset in self.memory_top.get() as u16..self.memory_bottom.get() as u16 { - let row = (offset - self.memory_top.get() as u16) / 8 + 9; - if offset % 8 == 0 { - let label_area = Rect::new(0, row, 8, 1); - Paragraph::new(format!("{:08x}", offset * 4)).render(label_area, buf); - } - let mem_area = Rect::new(offset % 8 * 9 + 9, row, 8, 1); - let mut mem_style = Style::default(); - if self.current_pc == offset as u32 * 4 { - mem_style = mem_style.fg(Color::Green); - } - if let Mode::EditMemory = self.mode - && self.memory_cursor.get() == offset as u32 - { - if self.memory_cursor.get() * 4 == self.current_pc { - mem_style = mem_style.fg(Color::White).bg(Color::Green); - } else { - mem_style = mem_style.fg(Color::Black).bg(Color::White); - } - } - Paragraph::new(format!("{:08x}", memory[offset as usize])) - .style(mem_style) - .render(mem_area, buf); - let ascii_area = Rect::new(82 + (offset % 8) * 4, row, 4, 1); - let ascii: String = memory[offset as usize] - .to_le_bytes() - .map(|b| { - if (b' '..=b'~').contains(&b) { - char::from_u32(b as u32).unwrap_or('.') - } else { - '.' - } - }) - .iter() - .collect(); - Paragraph::new(ascii) - .style(mem_style) - .render(ascii_area, buf); - } - } -} - -fn run_interactive(mut app: App) -> color_eyre::Result<()> { - color_eyre::install()?; - ratatui::run(|terminal| app.run(terminal))?; - Ok(()) -} - -const EBREAK_INSTRUCTION: u32 = 0x00100073; -const TEST_MAX_CYCLES: u32 = 1_000_000; -const TEST_PASS_VALUE: u32 = 0xebbb3689; -const TEST_FAIL_VALUE: u32 = 0xd02a545a; - -fn main() -> Result<(), Box<dyn Error>> { - let cli = Cli::parse(); - let perilus = Perilus::init(); - - match cli.command { - Some(Command::Interactive { file }) => { - if let Some(file) = file { - perilus.load_file(file)?; - } - let app = App::new(perilus); - run_interactive(app).map_err(|e| -> Box<dyn Error> { e.to_string().into() })?; - Ok(()) - } - Some(Command::Test { file }) => { - perilus.load_file(file)?; - let mut cycles = 0; - loop { - perilus.pulse_clock(); - cycles += 1; - if cycles > TEST_MAX_CYCLES { - return Err("Test execution hit maximum cycle count limit".into()); - } - if perilus.get_control_unit_state() == 0 { - let pc = perilus.get_pc(); - let instr = perilus.get_memory().get((pc / 4) as usize); - if instr.is_none() { - return Err(format!( - "Program counter diverged to an address outside memory: 0x{pc:08x}" - ) - .into()); - } - if let Some(&EBREAK_INSTRUCTION) = instr { - let result = perilus.get_registers()[1]; - match result { - TEST_PASS_VALUE => return Ok(()), - TEST_FAIL_VALUE => return Err("Test failed".into()), - v => return Err(format!("Got unexpected test result 0x{v:08x}").into()), - } - } - } - } - } - None => { - let app = App::new(perilus); - run_interactive(app).map_err(|e| -> Box<dyn Error> { e.to_string().into() })?; - Ok(()) - } - } -} diff --git a/sim/src/perilus.rs b/sim/src/perilus.rs @@ -1,95 +0,0 @@ -use bounded_integer::BoundedU32; -use std::{io, path::PathBuf, slice}; - -unsafe extern "C" { - fn perilus_init(); - fn perilus_eval(); - fn perilus_drop(); - fn perilus_increment_time(); - fn perilus_set_clock(new_clock: u32); - fn perilus_get_pc() -> u32; - fn perilus_set_pc(new_pc: u32); - fn perilus_set_reset(new_reset: u32); - fn perilus_get_control_unit_state() -> u32; - fn perilus_get_register_file() -> *const u32; - fn perilus_set_register(reg: u32, value: u32); - fn perilus_get_memory() -> *const u32; - fn perilus_set_memory(address: u32, value: u32); -} - -pub(crate) type Register = BoundedU32<0, 31>; -pub(crate) type MemoryIndex = BoundedU32<0, { Perilus::MEMORY_SIZE_WORDS as u32 }>; - -pub(crate) struct Perilus; - -impl Perilus { - const NUM_REGISTERS: usize = 32; - const MEMORY_SIZE_WORDS: usize = 1_048_576; - - pub(crate) fn init() -> Perilus { - unsafe { perilus_init() }; - Perilus - } - pub(crate) fn pulse_clock(&self) { - unsafe { - perilus_set_clock(0); - perilus_eval(); - perilus_increment_time(); - perilus_set_clock(1); - perilus_eval(); - perilus_increment_time(); - } - } - pub(crate) fn reset(&self) { - unsafe { - perilus_set_reset(1); - self.pulse_clock(); - perilus_set_reset(0); - } - } - pub(crate) fn get_pc(&self) -> u32 { - unsafe { perilus_get_pc() } - } - pub(crate) fn set_pc(&self, new_pc: u32) { - unsafe { perilus_set_pc(new_pc) }; - } - pub(crate) fn get_control_unit_state(&self) -> u32 { - unsafe { perilus_get_control_unit_state() } - } - pub(crate) fn get_registers(&self) -> &'static [u32] { - unsafe { slice::from_raw_parts(perilus_get_register_file(), Perilus::NUM_REGISTERS) } - } - pub(crate) fn set_register(&self, register: Register, value: u32) { - unsafe { perilus_set_register(register.get(), value) }; - } - pub(crate) fn get_memory(&self) -> &'static [u32] { - unsafe { slice::from_raw_parts(perilus_get_memory(), Perilus::MEMORY_SIZE_WORDS) } - } - pub(crate) fn set_memory(&self, address: u32, value: u32) { - unsafe { perilus_set_memory(address, value) }; - } - pub(crate) fn load_file(&self, file: PathBuf) -> io::Result<()> { - let bytes = std::fs::read(file)?; - if bytes.len() > Self::MEMORY_SIZE_WORDS * 4 { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "Provided file is too large to fit in simulated memory", - )); - } - for (address_bytes, value) in bytes.iter().enumerate() { - let address_words = address_bytes / 4; - let shift = (address_bytes % 4) * 8; - let current = self.get_memory()[address_words]; - let mask = !(0xffu32 << shift); - let new = (current & mask) | ((*value as u32) << shift); - self.set_memory(address_words as u32, new); - } - Ok(()) - } -} - -impl Drop for Perilus { - fn drop(&mut self) { - unsafe { perilus_drop() }; - } -} diff --git a/tests/run.sh b/tests/run.sh @@ -15,7 +15,7 @@ for test_stem in $test_stems do echo -en "$test_stem:\t" riscv64-none-elf-objcopy -O binary "$test_dir/$test_stem.elf" "$tmp_dir/$test_stem.bin" - if cd "$script_dir/../sim" && cargo run --release -q -- test "$tmp_dir/$test_stem.bin" + if cd "$script_dir/../sim" && cargo run --release -q -p sim-cli -- test "$tmp_dir/$test_stem.bin" then echo -e "PASS" else