From a1fa4a16e28ff99df2a936bbacd2a16f8c559dd3 Mon Sep 17 00:00:00 2001 From: ipc Date: Mon, 7 Aug 2023 23:14:18 +0200 Subject: [PATCH] initial commit --- Cargo.lock | 2296 +++++++++++++++++++++++++ Cargo.toml | 15 + LICENSE | 19 + README.md | 5 + give/.cargo/config.toml | 9 + give/Cargo.toml | 6 + give/README.md | 4 + give/examples/grid/.cargo/config.toml | 9 + give/examples/grid/Cargo.lock | 14 + give/examples/grid/Cargo.toml | 7 + give/examples/grid/data/tile | Bin 0 -> 1024 bytes give/examples/grid/entry.ld | 10 + give/examples/grid/src/main.rs | 50 + give/src/lib.rs | 42 + img/ive.png | Bin 0 -> 113427 bytes src/cpu.rs | 417 +++++ src/elf.rs | 116 ++ src/gpu.rs | 137 ++ src/lib.rs | 372 ++++ src/main.rs | 11 + 20 files changed, 3539 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 give/.cargo/config.toml create mode 100644 give/Cargo.toml create mode 100644 give/README.md create mode 100644 give/examples/grid/.cargo/config.toml create mode 100644 give/examples/grid/Cargo.lock create mode 100644 give/examples/grid/Cargo.toml create mode 100644 give/examples/grid/data/tile create mode 100644 give/examples/grid/entry.ld create mode 100644 give/examples/grid/src/main.rs create mode 100644 give/src/lib.rs create mode 100644 img/ive.png create mode 100644 src/cpu.rs create mode 100644 src/elf.rs create mode 100644 src/gpu.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..f1db64b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2296 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ab_glyph" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5110f1c78cf582855d895ecd0746b653db010cec6d9f5575293f27934d980a39" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-activity" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" +dependencies = [ + "android-properties", + "bitflags 1.3.2", + "cc", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum 0.6.1", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" + +[[package]] +name = "arboard" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6041616acea41d67c4a984709ddab1587fd0b10efe5cc563fee954d2f011854" +dependencies = [ + "clipboard-win", + "log", + "objc", + "objc-foundation", + "objc_id", + "once_cell", + "parking_lot", + "thiserror", + "winapi", + "x11rb", +] + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ash" +version = "0.37.3+1.3.251" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +dependencies = [ + "libloading 0.7.4", +] + +[[package]] +name = "atomic_refcell" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79d6dc922a2792b006573f60b2648076355daeae5ce9cb59507e5908c9625d31" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-sys" +version = "0.1.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.2.0-alpha.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" +dependencies = [ + "block-sys", + "objc2-encode", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "calloop" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" +dependencies = [ + "bitflags 1.3.2", + "log", + "nix 0.25.1", + "slotmap", + "thiserror", + "vec_map", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "clipboard-win" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "com-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "d3d12" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8f0de2f5a8e7bd4a9eec0e3c781992a4ce1724f68aec7d7a3715344de8b39da" +dependencies = [ + "bitflags 1.3.2", + "libloading 0.7.4", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading 0.8.0", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "ecolor" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e479a7fa3f23d4e794f8b2f8b3568dd4e47886ad1b12c9c095e141cb591eb63" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "egui" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3aef8ec3ae1b772f340170c65bf27d5b8c28f543a0116c844d2ac08d01123e7" +dependencies = [ + "ahash 0.8.3", + "epaint", + "log", + "nohash-hasher", +] + +[[package]] +name = "egui-wgpu" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33caaedd8283779c787298af23d8754a7e88421ff32e89ad0040c855fc0b0224" +dependencies = [ + "bytemuck", + "epaint", + "log", + "thiserror", + "type-map", + "wgpu", +] + +[[package]] +name = "egui-winit" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a49155fd4a0a4fb21224407a91de0030847972ef90fc64edb63621caea61cb2" +dependencies = [ + "arboard", + "egui", + "instant", + "log", + "raw-window-handle", + "smithay-clipboard", + "webbrowser", + "winit", +] + +[[package]] +name = "emath" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3857d743a6e0741cdd60b622a74c7a36ea75f5f8f11b793b41d905d2c9721a4b" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "epaint" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09333964d4d57f40a85338ba3ca5ed4716070ab184dcfed966b35491c5c64f3b" +dependencies = [ + "ab_glyph", + "ahash 0.8.3", + "atomic_refcell", + "bytemuck", + "ecolor", + "emath", + "log", + "nohash-hasher", + "parking_lot", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "error-code" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" +dependencies = [ + "libc", + "str-buf", +] + +[[package]] +name = "fdeflate" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "glow" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca0fe580e4b60a8ab24a868bc08e2f03cbcb20d3d676601fa909386713333728" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gpu-alloc" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22beaafc29b38204457ea030f6fb7a84c9e4dd1b86e311ba0542533453d87f62" +dependencies = [ + "bitflags 1.3.2", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "gpu-allocator" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce95f9e2e11c2c6fadfce42b5af60005db06576f231f5c92550fdded43c423e8" +dependencies = [ + "backtrace", + "log", + "thiserror", + "winapi", + "windows", +] + +[[package]] +name = "gpu-descriptor" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0c02e1ba0bdb14e965058ca34e09c020f8e507a760df1121728e0aef68d57a" +dependencies = [ + "bitflags 1.3.2", + "gpu-descriptor-types", + "hashbrown 0.12.3", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "hassle-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1397650ee315e8891a0df210707f0fc61771b0cc518c3023896064c5407cb3b0" +dependencies = [ + "bitflags 1.3.2", + "com-rs", + "libc", + "libloading 0.7.4", + "thiserror", + "widestring", + "winapi", +] + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "ive" +version = "0.1.0" +dependencies = [ + "anyhow", + "byteorder", + "egui", + "egui-wgpu", + "egui-winit", + "env_logger", + "pixels", + "winit", + "winit_input_helper", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" +dependencies = [ + "libc", + "libloading 0.7.4", + "pkg-config", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libloading" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metal" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de11355d1f6781482d027a3b4d4de7825dcedb197bf573e0596d00008402d060" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "naga" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbcc2e0513220fd2b598e6068608d4462db20322c0e77e47f6f488dfcfc279cb" +dependencies = [ + "bit-set", + "bitflags 1.3.2", + "codespan-reporting", + "hexf-parse", + "indexmap 1.9.3", + "log", + "num-traits", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum 0.5.11", + "raw-window-handle", + "thiserror", +] + +[[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.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc-sys" +version = "0.2.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" + +[[package]] +name = "objc2" +version = "0.3.0-beta.3.patch-leaks.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" +dependencies = [ + "block2", + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "2.0.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "orbclient" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221d488cd70617f1bd599ed8ceb659df2147d9393717954d82a0f5e8032a6ab1" +dependencies = [ + "redox_syscall", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pixels" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ba8189b31db4f12fbf0d4a8eab2d7d7343a504a8d8a7ea4b14ffb2e6129136a" +dependencies = [ + "bytemuck", + "pollster", + "raw-window-handle", + "thiserror", + "ultraviolet", + "wgpu", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "png" +version = "0.17.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332cd62e95873ea4f41f3dfd6bbbfc5b52aec892d7e8d534197c4720a0bbbab2" + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "range-alloc" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "renderdoc-sys" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "safe_arch" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +dependencies = [ + "bytemuck", +] + +[[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.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "smithay-client-toolkit" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454" +dependencies = [ + "bitflags 1.3.2", + "calloop", + "dlib", + "lazy_static", + "log", + "memmap2", + "nix 0.24.3", + "pkg-config", + "wayland-client", + "wayland-cursor", + "wayland-protocols", +] + +[[package]] +name = "smithay-clipboard" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +dependencies = [ + "smithay-client-toolkit", + "wayland-client", +] + +[[package]] +name = "spirv" +version = "0.2.0+1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" +dependencies = [ + "bitflags 1.3.2", + "num-traits", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "str-buf" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "tiny-skia" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "png", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "ttf-parser" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33" + +[[package]] +name = "type-map" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" +dependencies = [ + "rustc-hash", +] + +[[package]] +name = "ultraviolet" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca0b28b9a6ce66d47e3c5666aa738c5ec5223fcdd4c263f3edc98ab6fef618b3" +dependencies = [ + "wide", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wayland-client" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +dependencies = [ + "bitflags 1.3.2", + "downcast-rs", + "libc", + "nix 0.24.3", + "scoped-tls", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +dependencies = [ + "nix 0.24.3", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-cursor" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +dependencies = [ + "nix 0.24.3", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +dependencies = [ + "bitflags 1.3.2", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd222aa310eb7532e3fd427a5d7db7e44bc0b0cf1c1e21139c345325511a85b6" +dependencies = [ + "core-foundation", + "home", + "jni", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + +[[package]] +name = "wgpu" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "480c965c9306872eb6255fa55e4b4953be55a8b64d57e61d7ff840d3dcc051cd" +dependencies = [ + "arrayvec", + "cfg-if", + "js-sys", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f478237b4bf0d5b70a39898a66fa67ca3a007d79f2520485b8b0c3dfc46f8c2" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.3.3", + "codespan-reporting", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecb3258078e936deee14fd4e0febe1cfe9bbb5ffef165cb60218d2ee5eb4448" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.3.3", + "block", + "core-graphics-types", + "d3d12", + "foreign-types", + "glow", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading 0.8.0", + "log", + "metal", + "naga", + "objc", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c153280bb108c2979eb5c7391cb18c56642dd3c072e55f52065e13e2a1252a" +dependencies = [ + "bitflags 2.3.3", + "js-sys", + "web-sys", +] + +[[package]] +name = "wide" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f" +dependencies = [ + "bytemuck", + "safe_arch", +] + +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-wsapoll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winit" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "866db3f712fffba75d31bf0cdecf357c8aeafd158c5b7ab51dba2a2b2d47f196" +dependencies = [ + "android-activity", + "bitflags 1.3.2", + "cfg_aliases", + "core-foundation", + "core-graphics", + "dispatch", + "instant", + "libc", + "log", + "mio", + "ndk", + "objc2", + "once_cell", + "orbclient", + "percent-encoding", + "raw-window-handle", + "redox_syscall", + "sctk-adwaita", + "smithay-client-toolkit", + "wasm-bindgen", + "wayland-client", + "wayland-commons", + "wayland-protocols", + "wayland-scanner", + "web-sys", + "windows-sys 0.45.0", + "x11-dl", +] + +[[package]] +name = "winit_input_helper" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de0485e86aa2ee87d2d4c373a908c9548357bc65c5bce19fd884c8ea9eac4d7" +dependencies = [ + "winit", +] + +[[package]] +name = "winnow" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd122eb777186e60c3fdf765a58ac76e41c582f1f535fbf3314434c6b58f3f7" +dependencies = [ + "memchr", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" +dependencies = [ + "gethostname", + "nix 0.24.3", + "winapi", + "winapi-wsapoll", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +dependencies = [ + "nix 0.24.3", +] + +[[package]] +name = "xcursor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] + +[[package]] +name = "xml-rs" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47430998a7b5d499ccee752b41567bc3afc57e1327dc855b1a2aa44ce29b5fa1" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0d2e37d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "ive" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.72" +byteorder = "1.4.3" +egui = "0.22.0" +egui-wgpu = "0.22.0" +egui-winit = "0.22.0" +env_logger = "0.10.0" +pixels = "0.13.0" +winit = "0.28.6" +winit_input_helper = "0.14.1" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ffe83ac --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 ipc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..aefb203 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# ive + +risc-v emulator with display + +![ive](img/ive.png) diff --git a/give/.cargo/config.toml b/give/.cargo/config.toml new file mode 100644 index 0000000..2ec05cf --- /dev/null +++ b/give/.cargo/config.toml @@ -0,0 +1,9 @@ +[build] +target = "riscv32i-unknown-none-elf" + +[profile.dev] +panic = "abort" + +[profile.release] +opt-level = 1 +panic = "abort" diff --git a/give/Cargo.toml b/give/Cargo.toml new file mode 100644 index 0000000..4a8af8e --- /dev/null +++ b/give/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "give" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/give/README.md b/give/README.md new file mode 100644 index 0000000..98d0dac --- /dev/null +++ b/give/README.md @@ -0,0 +1,4 @@ +# give + +give is a library for interfacing with the ive display. To use give +you must have the riscv32i-unknown-none-elf toolchain installed. diff --git a/give/examples/grid/.cargo/config.toml b/give/examples/grid/.cargo/config.toml new file mode 100644 index 0000000..2ec05cf --- /dev/null +++ b/give/examples/grid/.cargo/config.toml @@ -0,0 +1,9 @@ +[build] +target = "riscv32i-unknown-none-elf" + +[profile.dev] +panic = "abort" + +[profile.release] +opt-level = 1 +panic = "abort" diff --git a/give/examples/grid/Cargo.lock b/give/examples/grid/Cargo.lock new file mode 100644 index 0000000..a329f60 --- /dev/null +++ b/give/examples/grid/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "give" +version = "0.1.0" + +[[package]] +name = "grid" +version = "0.1.0" +dependencies = [ + "give", +] diff --git a/give/examples/grid/Cargo.toml b/give/examples/grid/Cargo.toml new file mode 100644 index 0000000..4c88b0e --- /dev/null +++ b/give/examples/grid/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "grid" +version = "0.1.0" +edition = "2021" + +[dependencies.give] +path = "../../" diff --git a/give/examples/grid/data/tile b/give/examples/grid/data/tile new file mode 100644 index 0000000000000000000000000000000000000000..85ca5877138aad911af1db11999ed578bd32d297 GIT binary patch literal 1024 zcmY+Dv2MaZ42C;UiAYo;l|V|QWTp=QGwiU#TcjJEU?Lk#%~qzq=k@=5zN8r}`|SJA z_HSQ(`V6(CIyI)vK5|ZekI6@DkjC#cq1c~YzD9OA^2b=YAMTK|(!0gs92UE4lx@_@ z-6bsCCblHLmCyZ!-mx0N%O;+$Z{b~n&e!cA8@Em0>|=b7HgH{`#nXW^Yw_@h_q2A>Ht$$!FR{)}2S zKEvw{xvYQ3m+)u!*6w6=XSkQw-+)Z!34d39)lYus4-RAfx2BA^+u0N@dxK=$NK!LjUMSWN@rXehxD)7z{mcT-}jN7 zGXBLavm4Kl*=d%-60`Xw{)8X;kMkow7VVPW9d^p+=lrn)F@M@$b~Np<`~2MRukwTW tzdvxmPT2p@JWbpGk&m;){+aIBUGP5t$V2=~qkruDa4&Jif5S$T{|_sp(%S$4 literal 0 HcmV?d00001 diff --git a/give/examples/grid/entry.ld b/give/examples/grid/entry.ld new file mode 100644 index 0000000..c3521c4 --- /dev/null +++ b/give/examples/grid/entry.ld @@ -0,0 +1,10 @@ +ENTRY(_start); + +SECTIONS +{ + . = 0x80000000; + .text : { *(.text .text.*) } + . = 0x0; + .data : { *(.data) } + .bss : { *(.bss) } +} diff --git a/give/examples/grid/src/main.rs b/give/examples/grid/src/main.rs new file mode 100644 index 0000000..bfc81c9 --- /dev/null +++ b/give/examples/grid/src/main.rs @@ -0,0 +1,50 @@ +#![no_std] +#![no_main] + +fn draw_grid(grid: &[u8], data: &[u8], w: u32, h: u32, x: u32, y: u32) { + for (i, c) in grid.iter().enumerate() { + let cx = (x + (i as u32 % w)) * 16; + let cy = (y + (i as u32 / h)) * 16; + + match c { + 0 => give::draw_rect_color(0x000000ff, cx, cy), + 1 => give::draw_rect(data.as_ptr(), cx, cy), + _ => unreachable!(), + } + } +} + +#[no_mangle] +pub extern "C" fn _start() -> ! { + let tile = include_bytes!("../data/tile"); + + #[rustfmt::skip] + let formation = [ + 0, 1, 0, + 1, 0, 1, + 0, 1, 0, + + 1, 1, 1, + 1, 0, 1, + 1, 1, 1, + + 1, 0, 1, + 0, 1, 0, + 1, 0, 1, + ]; + + let mut n = 0; + let mut timer = 0; + loop { + draw_grid(&formation[n * 9..(n * 9) + 9], tile, 3, 3, 400, 300); + timer += 1; + if timer == 16 { + n += 1; + timer = 0; + } + if n == 3 { + n = 0; + } + give::redraw(); + } +} diff --git a/give/src/lib.rs b/give/src/lib.rs new file mode 100644 index 0000000..9aa3127 --- /dev/null +++ b/give/src/lib.rs @@ -0,0 +1,42 @@ +#![no_std] + +use core::panic::PanicInfo; +use core::ptr; + +const CTRL_DRAW_ADDR: *mut u32 = 0x60000000 as *mut u32; +const DRAW_ADDR: *mut u32 = 0x60000001 as *mut u32; + +pub const TILE_SIZE: usize = 16; + +#[panic_handler] +pub fn panic(_panic: &PanicInfo<'_>) -> ! { + loop {} +} + +extern "C" fn ctrl_draw_write(val: u32) { + unsafe { + ptr::write_volatile(CTRL_DRAW_ADDR, val); + } +} + +extern "C" fn draw_write(val: u32) { + unsafe { + ptr::write_volatile(DRAW_ADDR, val); + } +} + +pub extern "C" fn redraw() { + ctrl_draw_write(1); +} + +pub extern "C" fn draw_rect_color(color: u32, x: u32, y: u32) { + draw_write(0); + draw_write((x << 16) | y); + draw_write(color); +} + +pub extern "C" fn draw_rect(data: *const u8, x: u32, y: u32) { + draw_write(1); + draw_write((x << 16) | y); + draw_write(data as u32); +} diff --git a/img/ive.png b/img/ive.png new file mode 100644 index 0000000000000000000000000000000000000000..ef52c80181c03edd1e2f12ce3e116addd378d3b8 GIT binary patch literal 113427 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 dFw(%?F$mg=-Te&ofl%Gn2%&yT_1?d^YD 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 sa_fs-m7?E1Fu0wYg, +} + +struct Bus { + ram: Box, + gpu: Gpu, +} + +pub struct Cpu { + pub reg: [u32; 31], + pub pc: u32, + bus: Bus, +} + +struct Instruction { + op: Format, + rd: u8, + f3: u8, + f7: u8, + rs1: u8, + rs2: u8, + imm: u32, + simm: u32, + uimm: u32, + bimm: u32, + jimm: u32, +} + +impl Ram { + fn new() -> Self { + let mut mem = Vec::new(); + mem.resize((RAM_SIZE - RAM_BASE) as usize, 0); + Self { mem } + } +} + +impl Memory for Ram { + fn read(&self, addr: u32) -> u32 { + let addr = addr as usize; + // should check for unaligned reads + LittleEndian::read_u32(&self.mem[addr..addr + 4]) + } + + fn write(&mut self, addr: u32, val: Store) { + let addr = addr as usize; + + match val { + Store::Byte(b) => self.mem[addr] = b, + Store::Half(h) => LittleEndian::write_u16(&mut self.mem[addr..addr + 2], h), + Store::Word(w) => LittleEndian::write_u32(&mut self.mem[addr..addr + 4], w), + } + } +} + +impl Format { + fn new(ins: u32) -> Self { + match ins & 0x7f { + 0x33 => Self::R, + 0x13 => Self::I, + 0x03 => Self::IL, + 0x23 => Self::S, + 0x63 => Self::B, + 0x6f => Self::J, + 0x67 => Self::JI, + 0x37 => Self::U, + 0x17 => Self::UI, + 0x73 => Self::E, + _ => panic!(), + } + } +} + +macro_rules! op { + ($op: ident) => { + Instruction { + op: Format::$op, + .. + } + }; +} + +macro_rules! f3f7 { + ($op: ident, $f3: expr, $f7: expr) => { + Instruction { + op: Format::$op, + f3: $f3, + f7: $f7, + .. + } + }; +} + +macro_rules! f3 { + ($op: ident, $f3: expr) => { + Instruction { + op: Format::$op, + f3: $f3, + .. + } + }; +} + +impl Opcode { + fn new(ins: &Instruction) -> Self { + match ins { + f3f7!(R, 0x00, 0x00) => Self::Add, + f3f7!(R, 0x00, 0x20) => Self::Sub, + f3f7!(R, 0x04, 0x00) => Self::Xor, + f3f7!(R, 0x06, 0x00) => Self::Or, + f3f7!(R, 0x07, 0x00) => Self::And, + f3f7!(R, 0x01, 0x00) => Self::Sll, + f3f7!(R, 0x05, 0x00) => Self::Srl, + f3f7!(R, 0x05, 0x20) => Self::Sra, + f3f7!(R, 0x02, 0x00) => Self::Slt, + f3f7!(R, 0x03, 0x00) => Self::Sltu, + f3!(I, 0x00) => Self::Addi, + f3!(I, 0x04) => Self::Xori, + f3!(I, 0x06) => Self::Ori, + f3!(I, 0x07) => Self::Andi, + f3!(I, 0x01) => Self::Slli, + f3f7!(I, 0x05, 0x00) => Self::Srli, + f3f7!(I, 0x05, 0x20) => Self::Srai, + f3!(I, 0x02) => Self::Slti, + f3!(I, 0x03) => Self::Sltiu, + f3!(IL, 0x00) => Self::Lb, + f3!(IL, 0x01) => Self::Lh, + f3!(IL, 0x02) => Self::Lw, + f3!(IL, 0x04) => Self::Lbu, + f3!(IL, 0x05) => Self::Lhu, + f3!(S, 0x00) => Self::Sb, + f3!(S, 0x01) => Self::Sh, + f3!(S, 0x02) => Self::Sw, + f3!(B, 0x00) => Self::Beq, + f3!(B, 0x01) => Self::Bne, + f3!(B, 0x04) => Self::Blt, + f3!(B, 0x05) => Self::Bge, + f3!(B, 0x06) => Self::Bltu, + f3!(B, 0x07) => Self::Bgeu, + op!(J) => Self::Jal, + f3!(JI, 0x0) => Self::Jalr, + op!(U) => Self::Lui, + op!(UI) => Self::Auipc, + op!(E) => match ins.imm { + 0x0 => Self::Ecall, + _ => Self::Ebreak, + }, + _ => panic!("bad instruction"), + } + } +} + +impl Instruction { + fn new(ins: u32) -> Self { + Self { + op: Format::new(ins), + rd: ((ins >> 7) & 0x1f) as u8, + f3: ((ins >> 12) & 0x7) as u8, + f7: ((ins >> 25) & 0x7f) as u8, + rs1: ((ins >> 15) & 0x1f) as u8, + rs2: ((ins >> 20) & 0x1f) as u8, + imm: ((ins & 0xfff00000) as i64 as i32 >> 20) as u32, + simm: (((ins & 0xfe000000) as i64 as i32 >> 20) as u32 | ((ins >> 7) & 0x1f)), + uimm: ins >> 12, + bimm: ((ins & 0x80000000) as i64 as i32 >> 19) as u32 + | ((ins & 0x80) << 4) + | ((ins >> 20) & 0x7e0) + | ((ins >> 7) & 0x1e), + jimm: ((ins & 0x80000000) as i64 as i32 >> 11) as u32 + | (ins & 0xff000) + | ((ins >> 9) & 0x800) + | ((ins >> 20) & 0x7fe), + } + } + + fn exec_r(&self, cpu: &mut Cpu, op: fn(u32, u32) -> u32) { + let rs1 = cpu.reg_read(self.rs1); + let rs2 = cpu.reg_read(self.rs2); + cpu.reg_write(self.rd, op(rs1, rs2)); + } + + fn exec_i(&self, cpu: &mut Cpu, op: fn(u32, u32) -> u32) { + let rs1 = cpu.reg_read(self.rs1); + cpu.reg_write(self.rd, op(rs1, self.imm)); + } + + fn exec_il(&self, cpu: &mut Cpu, op: fn(u32) -> u32) { + let rs1 = cpu.reg_read(self.rs1); + let load = cpu.read(rs1.wrapping_add_signed(self.imm as i32)); + cpu.reg_write(self.rd, op(load)); + } + + fn exec_s(&self, cpu: &mut Cpu, op: fn(u32) -> Store) { + let rs1 = cpu.reg_read(self.rs1); + let rs2 = cpu.reg_read(self.rs2); + cpu.write(rs1.wrapping_add_signed(self.simm as i32), op(rs2)) + } + + fn exec_b(&self, cpu: &mut Cpu, op: fn(u32, u32) -> bool) { + let rs1 = cpu.reg_read(self.rs1); + let rs2 = cpu.reg_read(self.rs2); + if op(rs1, rs2) { + cpu.pc = cpu.pc.wrapping_add_signed(self.bimm as i32) - 4; + } + } + + fn execute(&self, cpu: &mut Cpu) { + match Opcode::new(self) { + Opcode::Add => self.exec_r(cpu, |r1, r2| r1.wrapping_add_signed(r2 as i32)), + Opcode::Sub => self.exec_r(cpu, |r1, r2| r1.wrapping_sub(r2)), + Opcode::Xor => self.exec_r(cpu, |r1, r2| r1 ^ r2), + Opcode::Or => self.exec_r(cpu, |r1, r2| r1 | r2), + Opcode::And => self.exec_r(cpu, |r1, r2| r1 & r2), + Opcode::Sll => self.exec_r(cpu, |r1, r2| r1.wrapping_shl(r2)), + Opcode::Srl => self.exec_r(cpu, |r1, r2| r1.wrapping_shr(r2)), + Opcode::Sra => self.exec_r(cpu, |r1, r2| r1.wrapping_shr(r2)), + Opcode::Slt => self.exec_r(cpu, |r1, r2| (r1 < (r2 as i32) as u32) as u32), + Opcode::Sltu => self.exec_r(cpu, |r1, r2| (r1 < r2) as u32), + + Opcode::Addi => self.exec_i(cpu, |r1, imm| r1.wrapping_add_signed(imm as i32)), + Opcode::Xori => self.exec_i(cpu, |r1, imm| r1 ^ imm), + Opcode::Ori => self.exec_i(cpu, |r1, imm| r1 | imm), + Opcode::Andi => self.exec_i(cpu, |r1, imm| r1 & imm), + Opcode::Slli => self.exec_i(cpu, |r1, imm| r1.wrapping_shl(imm & 0x1f)), + Opcode::Srli => self.exec_i(cpu, |r1, imm| r1.wrapping_shr(imm & 0x1f)), + Opcode::Srai => self.exec_i(cpu, |r1, imm| r1.wrapping_shr(imm & 0x1f) as i32 as u32), + Opcode::Slti => self.exec_i(cpu, |r1, imm| (r1 < (imm as i32) as u32) as u32), + Opcode::Sltiu => self.exec_i(cpu, |r1, imm| (r1 < imm) as u32), + + Opcode::Lb => self.exec_il(cpu, |imm| imm as u8 as u32), + Opcode::Lh => self.exec_il(cpu, |imm| imm as u16 as u32), + Opcode::Lw => self.exec_il(cpu, |imm| imm), + Opcode::Lbu => self.exec_il(cpu, |imm| imm as u8 as u32), + Opcode::Lhu => self.exec_il(cpu, |imm| imm as u16 as u32), + + Opcode::Sb => self.exec_s(cpu, |r1| Store::Byte(r1 as u8)), + Opcode::Sh => self.exec_s(cpu, |r1| Store::Half(r1 as u16)), + Opcode::Sw => self.exec_s(cpu, Store::Word), + + Opcode::Beq => self.exec_b(cpu, |r1, r2| (r1 as i32) == (r2 as i32)), + Opcode::Bne => self.exec_b(cpu, |r1, r2| (r1 as i32) != (r2 as i32)), + Opcode::Blt => self.exec_b(cpu, |r1, r2| (r1 as i32) < (r2 as i32)), + Opcode::Bge => self.exec_b(cpu, |r1, r2| (r1 as i32) >= (r2 as i32)), + Opcode::Bltu => self.exec_b(cpu, |r1, r2| r1 < r2), + Opcode::Bgeu => self.exec_b(cpu, |r1, r2| r1 >= r2), + + Opcode::Jal => { + cpu.reg_write(self.rd, cpu.pc); + cpu.pc = cpu.pc.wrapping_add_signed(self.jimm as i32) - 4; + } + Opcode::Jalr => { + let pc = cpu.pc; + let rs1 = cpu.reg_read(self.rs1); + cpu.pc = rs1.wrapping_add_signed(self.imm as i32); + cpu.reg_write(self.rd, pc); + } + + Opcode::Lui => cpu.reg_write(self.rd, self.uimm << 12), + Opcode::Auipc => cpu.reg_write(self.rd, cpu.pc.wrapping_add(self.uimm << 12) - 4), + + Opcode::Ecall | Opcode::Ebreak => (), + } + } +} + +impl Memory for Bus { + fn read(&self, addr: u32) -> u32 { + match addr { + RAM_BASE..=RAM_SIZE => self.ram.read(addr - RAM_BASE), + GPU_BASE..=GPU_SIZE => self.gpu.read(addr - GPU_BASE), + _ => panic!(), + } + } + + fn write(&mut self, addr: u32, val: Store) { + match addr { + RAM_BASE..=RAM_SIZE => self.ram.write(addr - RAM_BASE, val), + GPU_BASE..=GPU_SIZE => self.gpu.write(addr - GPU_BASE, val), + _ => panic!(), + } + } +} + +impl Cpu { + pub fn new(mem: Vec) -> Result { + let mut reg: [u32; 31] = [0; 31]; + let mut ram = Ram::new(); + + // set sp to point to top of ram + reg[2] = RAM_SIZE; + + let pc = elf::load(mem, &mut ram.mem)?; + + Ok(Self { + reg, + pc, + bus: Bus { + ram: Box::new(ram), + gpu: Gpu::new(), + }, + }) + } + + pub fn read(&self, addr: u32) -> u32 { + self.bus.read(addr) + } + + fn write(&mut self, addr: u32, val: Store) { + self.bus.write(addr, val); + } + + fn reg_read(&mut self, reg: u8) -> u32 { + let reg = reg as usize; + if reg > self.reg.len() { + panic!("invalid register read"); + } + self.reg[reg] + } + + fn reg_write(&mut self, reg: u8, val: u32) { + let reg = reg as usize; + if reg > self.reg.len() { + panic!("invalid register write"); + } + self.reg[reg] = val; + self.reg[0] = 0 + } + + pub fn gpu_queue(&self) -> &Vec { + &self.bus.gpu.queue + } + + pub fn gpu_clear(&mut self) { + self.bus.gpu.update = false; + self.bus.gpu.queue.clear(); + } + + pub fn update(&mut self) -> bool { + self.bus.gpu.update + } + + pub fn step(&mut self) -> bool { + let inst = Instruction::new(self.read(self.pc)); + + self.pc += 4; + inst.execute(self); + if self.pc == 0 { + return false; + } + true + } +} diff --git a/src/elf.rs b/src/elf.rs new file mode 100644 index 0000000..724d77e --- /dev/null +++ b/src/elf.rs @@ -0,0 +1,116 @@ +use crate::cpu::RAM_BASE; +use byteorder::{LittleEndian, ReadBytesExt}; +use std::io::Cursor; +use std::io::Read; + +const MAGIC: [u8; 4] = [0x7f, 0x45, 0x4c, 0x46]; +const LOAD: u32 = 1; + +#[derive(Debug)] +pub enum Error { + Eof, + BadMagic, + BadType, + BadMachine, +} + +struct Phdr { + ptype: u32, + offset: u32, + vaddr: u32, + memsz: u32, +} + +fn read_u16(buf: &mut R) -> u16 { + buf.read_u16::().unwrap() +} + +fn read_u32(buf: &mut R) -> u32 { + buf.read_u32::().unwrap() +} + +impl Phdr { + fn new(buf: &mut R) -> Self { + let ptype = read_u32(buf); + let offset = read_u32(buf); + let vaddr = read_u32(buf); + for _ in 0..2 { + read_u32(buf); + } + let memsz = read_u32(buf); + + for _ in 0..2 { + read_u32(buf); + } + + Self { + ptype, + offset, + vaddr, + memsz, + } + } +} + +pub fn load(elf: Vec, mem: &mut [u8]) -> Result { + let mut rdr = Cursor::new(elf); + + let mut ident: [u8; 16] = [0; 16]; + + if rdr.read_exact(&mut ident).is_err() { + return Err(Error::Eof); + } + + if ident[..MAGIC.len()] != MAGIC { + return Err(Error::BadMagic); + } + + let etype = read_u16(&mut rdr); + + if etype != 0x2 { + return Err(Error::BadType); + } + + let machine = read_u16(&mut rdr); + + if machine != 0xf3 { + return Err(Error::BadMachine); + } + + // version + read_u32(&mut rdr); + + let entry = read_u32(&mut rdr); + let phoff = read_u32(&mut rdr); + // shoff + read_u32(&mut rdr); + // flags + read_u32(&mut rdr); + // ehsize + read_u16(&mut rdr); + // phentsize + read_u16(&mut rdr); + let phnum = read_u16(&mut rdr); + + rdr.set_position(phoff as u64); + + for _ in 0..phnum { + let phdr = Phdr::new(&mut rdr); + + if phdr.ptype != LOAD { + continue; + } + + let vaddr = (phdr.vaddr - RAM_BASE) as usize; + let memsz = phdr.memsz as usize; + + let pos = rdr.position(); + rdr.set_position(phdr.offset as u64); + if rdr.read_exact(&mut mem[vaddr..vaddr + memsz]).is_err() { + return Err(Error::Eof); + } + rdr.set_position(pos); + } + + Ok(entry) +} diff --git a/src/gpu.rs b/src/gpu.rs new file mode 100644 index 0000000..d70fd3b --- /dev/null +++ b/src/gpu.rs @@ -0,0 +1,137 @@ +use crate::{Memory, Store}; + +enum Command { + Control, + Draw, +} + +#[derive(PartialEq)] +enum DrawCommand { + Rect, + TexturedRect, + Idle, +} + +pub enum Primitive { + Rect(u32, u32), + TexturedRect(u32, u32), +} + +struct Packet { + cmd: DrawCommand, + len: u32, + count: u32, + args: [u32; 2], +} + +pub struct Gpu { + pub update: bool, + packet: Packet, + pub queue: Vec, +} + +impl Command { + fn new(addr: u32) -> Self { + match addr { + 0x0 => Self::Control, + 0x1 => Self::Draw, + _ => panic!(), + } + } +} + +impl DrawCommand { + fn new(cmd: u32) -> Self { + match cmd { + 0x0 => Self::Rect, + 0x1 => Self::TexturedRect, + _ => panic!(), + } + } +} + +impl Primitive { + fn new(packet: &Packet) -> Self { + let args = packet.args; + + match packet.cmd { + DrawCommand::Rect => Self::Rect(args[0], args[1]), + DrawCommand::TexturedRect => Self::TexturedRect(args[0], args[1]), + _ => unreachable!(), + } + } +} + +impl Packet { + pub fn new(cmd: DrawCommand) -> Self { + let len = match cmd { + DrawCommand::Rect | DrawCommand::TexturedRect => 2, + DrawCommand::Idle => 0, + }; + + Self { + cmd, + len, + count: 0, + args: [0; 2], + } + } + + pub fn idle(&self) -> bool { + self.cmd == DrawCommand::Idle + } + + fn reset(&mut self) { + self.cmd = DrawCommand::Idle; + self.len = 0; + } + + fn transfer(&self) -> bool { + self.len > 0 && self.count == self.len + } + + fn read(&mut self, queue: &mut Vec, arg: u32) { + self.args[self.count as usize] = arg; + self.count += 1; + + if self.transfer() { + queue.push(Primitive::new(self)); + self.reset(); + } + } +} + +impl Gpu { + pub fn new() -> Self { + Self { + update: false, + packet: Packet::new(DrawCommand::Idle), + queue: vec![], + } + } +} + +impl Memory for Gpu { + fn read(&self, addr: u32) -> u32 { + panic!("attempted to read at {:#08x?}", addr); + } + + fn write(&mut self, addr: u32, val: Store) { + if let Store::Word(w) = val { + match Command::new(addr) { + Command::Control => { + self.update = true; + } + Command::Draw => { + if self.packet.idle() { + self.packet = Packet::new(DrawCommand::new(w)); + } else { + self.packet.read(&mut self.queue, w); + } + } + } + } else { + panic!("attempted to store {:#?}", val); + } + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..13b1f56 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,372 @@ +use anyhow::{bail, Result}; +use egui::{ClippedPrimitive, Context, TexturesDelta}; +use egui_wgpu::renderer::{Renderer, ScreenDescriptor}; +use pixels::{wgpu, Pixels, PixelsContext, SurfaceTexture}; +use std::fs; +use std::io::Read; +use winit::dpi::LogicalSize; +use winit::event::{Event, VirtualKeyCode}; +use winit::event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget}; +use winit::window::{Window, WindowBuilder}; +use winit_input_helper::WinitInputHelper; + +mod cpu; +mod elf; +mod gpu; + +use crate::cpu::Cpu; +use crate::gpu::Primitive; + +const FB_WIDTH: u32 = 800; +const FB_HEIGHT: u32 = 600; +const WINDOW_WIDTH: u32 = 1024; +const WINDOW_HEIGHT: u32 = 768; + +const TILE_SIZE: u32 = 16; + +#[derive(Debug)] +enum Store { + Byte(u8), + Half(u16), + Word(u32), +} + +enum Order { + Lsb, + Msb, +} + +trait Memory { + fn read(&self, addr: u32) -> u32; + fn write(&mut self, addr: u32, val: Store); +} + +struct Gui { + window_open: bool, + gpu_log: Vec, +} + +struct State { + egui_ctx: Context, + egui_state: egui_winit::State, + screen_descriptor: ScreenDescriptor, + renderer: Renderer, + paint_jobs: Vec, + textures: TexturesDelta, + gui: Gui, + cpu: Cpu, +} + +impl Gui { + fn new() -> Self { + Self { + window_open: true, + gpu_log: Vec::new(), + } + } + + fn ui(&mut self, ctx: &Context, cpu: &Cpu) { + egui::Window::new("regs") + .open(&mut self.window_open) + .show(ctx, |ui| { + ui.horizontal(|ui| { + ui.monospace("pc:"); + ui.monospace(format!("{:#08x}", cpu.pc)); + }); + for (i, reg) in cpu.reg.iter().enumerate() { + ui.horizontal(|ui| { + ui.monospace(format!("r{}:", i)); + ui.monospace(format!("{:#08x}", reg)); + }); + } + }); + egui::Window::new("gpu") + .open(&mut self.window_open) + .constrain(true) + .show(ctx, |ui| { + let mut log = self.gpu_log.join("\n"); + egui::ScrollArea::vertical() + .stick_to_bottom(true) + .show(ui, |ui| { + ui.add(egui::TextEdit::multiline(&mut log).code_editor()) + }); + }); + } +} + +impl State { + fn new( + event_loop: &EventLoopWindowTarget, + width: u32, + height: u32, + scale_factor: f32, + pixels: &Pixels, + cpu: Cpu, + ) -> Self { + let max_texture_size = pixels.device().limits().max_texture_dimension_2d as usize; + + let egui_ctx = Context::default(); + let mut egui_state = egui_winit::State::new(event_loop); + egui_state.set_max_texture_side(max_texture_size); + egui_state.set_pixels_per_point(scale_factor); + let screen_descriptor = ScreenDescriptor { + size_in_pixels: [width, height], + pixels_per_point: scale_factor, + }; + let renderer = Renderer::new(pixels.device(), pixels.render_texture_format(), None, 1); + let textures = TexturesDelta::default(); + let gui = Gui::new(); + + Self { + egui_ctx, + egui_state, + screen_descriptor, + renderer, + paint_jobs: Vec::new(), + textures, + gui, + cpu, + } + } + + pub fn handle_event(&mut self, event: &winit::event::WindowEvent) { + let _ = self.egui_state.on_event(&self.egui_ctx, event); + } + + pub fn resize(&mut self, width: u32, height: u32) { + if width > 0 && height > 0 { + self.screen_descriptor.size_in_pixels = [width, height]; + } + } + + pub fn scale_factor(&mut self, scale_factor: f64) { + self.screen_descriptor.pixels_per_point = scale_factor as f32; + } + + pub fn prepare(&mut self, window: &Window) { + let raw_input = self.egui_state.take_egui_input(window); + let output = self.egui_ctx.run(raw_input, |egui_ctx| { + self.gui.ui(egui_ctx, &self.cpu); + }); + + self.textures.append(output.textures_delta); + self.egui_state + .handle_platform_output(window, &self.egui_ctx, output.platform_output); + self.paint_jobs = self.egui_ctx.tessellate(output.shapes); + } + + pub fn render( + &mut self, + encoder: &mut wgpu::CommandEncoder, + render_target: &wgpu::TextureView, + context: &PixelsContext, + ) { + for (id, image_delta) in &self.textures.set { + self.renderer + .update_texture(&context.device, &context.queue, *id, image_delta); + } + self.renderer.update_buffers( + &context.device, + &context.queue, + encoder, + &self.paint_jobs, + &self.screen_descriptor, + ); + + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("egui"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: render_target, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: true, + }, + })], + depth_stencil_attachment: None, + }); + + self.renderer + .render(&mut rpass, &self.paint_jobs, &self.screen_descriptor); + } + + let textures = std::mem::take(&mut self.textures); + for id in &textures.free { + self.renderer.free_texture(id); + } + } + + fn draw_rect(frame: &mut [u8], order: Order, offset: u32, color: u32) { + let offset = offset as usize * 4; + + let (r, g, b, a) = match order { + Order::Lsb => ( + (color >> 24) as u8, + (color >> 16) as u8, + (color >> 8) as u8, + color as u8, + ), + Order::Msb => ( + color as u8, + (color >> 8) as u8, + (color >> 16) as u8, + (color >> 24) as u8, + ), + }; + + if a == 0xff { + frame[offset..offset + 4].copy_from_slice(&[r, g, b, a]); + } + } + + fn draw(&mut self, frame: &mut [u8]) { + if !self.update() { + return; + } + + let log: Vec = self + .gpu_queue() + .iter() + .map(|cmd| match cmd { + Primitive::Rect(offset, color) => { + let (x, y) = ((offset >> 16), (offset & 0xff)); + + for i in 0..TILE_SIZE * TILE_SIZE { + let x = x + (i % TILE_SIZE); + let y = (y + (i / TILE_SIZE)) * FB_WIDTH; + Self::draw_rect(frame, Order::Lsb, x + y, *color); + } + + format!("Rect: {:#08x} {:#08x}", offset, color) + } + Primitive::TexturedRect(offset, addr) => { + let (x, y) = ((offset >> 16), (offset & 0xff)); + + for i in 0..TILE_SIZE * TILE_SIZE { + let data = self.read(addr + (i * 4)); + let x = x + (i % TILE_SIZE); + let y = (y + (i / TILE_SIZE)) * FB_WIDTH; + Self::draw_rect(frame, Order::Msb, x + y, data); + } + + format!("TexturedRect: {:#08x} {:#08x}", offset, addr) + } + }) + .collect(); + + self.gui.gpu_log.extend(log); + self.gpu_clear(); + } + + fn read(&self, offset: u32) -> u32 { + self.cpu.read(offset) + } + + fn gpu_queue(&self) -> &Vec { + self.cpu.gpu_queue() + } + + fn gpu_clear(&mut self) { + self.cpu.gpu_clear(); + } + + fn update(&mut self) -> bool { + self.cpu.update() + } + + fn step(&mut self) { + self.cpu.step(); + } +} + +pub fn run(path: String) -> Result<()> { + env_logger::init(); + let mut file = fs::File::open(path)?; + let mut data = Vec::new(); + + file.read_to_end(&mut data)?; + + let cpu = match Cpu::new(data) { + Ok(cpu) => cpu, + Err(e) => match e { + elf::Error::Eof => bail!("eof"), + elf::Error::BadMagic => bail!("bad magic"), + elf::Error::BadType => bail!("invalid executable"), + elf::Error::BadMachine => bail!("foreign elf architecture"), + }, + }; + + let event_loop = EventLoop::new(); + let mut input = WinitInputHelper::new(); + let window = { + let size = LogicalSize::new(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64); + WindowBuilder::new() + .with_title("ive") + .with_inner_size(size) + .with_min_inner_size(size) + .with_resizable(false) + .build(&event_loop) + .unwrap() + }; + + let (mut pixels, mut state) = { + let window_size = window.inner_size(); + let scale_factor = 1.0; + let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window); + let pixels = Pixels::new(FB_WIDTH, FB_HEIGHT, surface_texture).unwrap(); + let state = State::new( + &event_loop, + window_size.width, + window_size.height, + scale_factor, + &pixels, + cpu, + ); + (pixels, state) + }; + + event_loop.run(move |event, _, control_flow| { + if input.update(&event) { + if input.key_pressed(VirtualKeyCode::Escape) || input.close_requested() { + *control_flow = ControlFlow::Exit; + return; + } + + if let Some(scale_factor) = input.scale_factor() { + state.scale_factor(scale_factor); + } + + if let Some(size) = input.window_resized() { + if pixels.resize_surface(size.width, size.height).is_err() { + *control_flow = ControlFlow::Exit; + return; + } + state.resize(size.width, size.height); + } + + window.request_redraw(); + } + + match event { + Event::WindowEvent { event, .. } => { + state.handle_event(&event); + } + Event::RedrawRequested(_) => { + state.draw(pixels.frame_mut()); + state.prepare(&window); + let _ = pixels.render_with(|encoder, target, ctx| { + ctx.scaling_renderer.render(encoder, target); + state.render(encoder, target, ctx); + Ok(()) + }); + } + _ => (), + } + + state.step(); + if state.update() { + window.request_redraw(); + } + }); +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..231d01e --- /dev/null +++ b/src/main.rs @@ -0,0 +1,11 @@ +use std::env; +use std::process; + +fn main() -> anyhow::Result<()> { + if let Some(path) = env::args().nth(1) { + ive::run(path) + } else { + eprintln!("usage: {} ", env::args().next().unwrap()); + process::exit(1); + } +}