commit 74bde02cfa576cf0ce0ca4a48d1531faf13c3c9f Author: shadow cat Date: Mon Oct 28 01:31:16 2024 -0400 arst diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..1abf289 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2410 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ab_glyph" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +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 = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.6.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys 0.6.0+11769913", + "num_enum", + "thiserror", +] + +[[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 = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bit-set" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.6.0", + "log", + "polling", + "rustix", + "slab", + "thiserror", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cc" +version = "1.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[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 = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[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" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + +[[package]] +name = "d3d12" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdbd1f579714e3c809ebd822c81ef148b1ceaeb3d535352afc73fd0c4c6a0017" +dependencies = [ + "bitflags 2.6.0", + "libloading", + "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", +] + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.84", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "fractal" +version = "0.1.0" +dependencies = [ + "bytemuck", + "nalgebra", + "num-traits", + "pollster", + "wgpu", + "winit", +] + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[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 = "glow" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.6.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "gpu-allocator" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd4240fc91d3433d5e5b0fc5b67672d771850dc19bbee03c1381e19322803d7" +dependencies = [ + "log", + "presser", + "thiserror", + "winapi", + "windows", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" +dependencies = [ + "bitflags 2.6.0", + "gpu-descriptor-types", + "hashbrown 0.14.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "hassle-rs" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" +dependencies = [ + "bitflags 2.6.0", + "com", + "libc", + "libloading", + "thiserror", + "widestring", + "winapi", +] + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.0", +] + +[[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.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "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 = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall 0.5.7", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] + +[[package]] +name = "metal" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +dependencies = [ + "bitflags 2.6.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "naga" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.6.0", + "cfg_aliases 0.1.1", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "nalgebra" +version = "0.33.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf139e93ad757869338ad85239cb1d6c067b23b94e5846e637ca6328ee4be60" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.84", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.6.0", + "jni-sys", + "log", + "ndk-sys 0.6.0+11769913", + "num_enum", + "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.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.84", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[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-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "orbclient" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +dependencies = [ + "libredox", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.7", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.84", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + +[[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.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" + +[[package]] +name = "quick-xml" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[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.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "safe_arch" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a" +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.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + +[[package]] +name = "serde" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.84", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simba" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.6.0", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix", + "thiserror", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[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.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.6.0", +] + +[[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 = "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.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a2c4efbc0b0670e3d41f388e3cb936ff364bf681703b4c92ae26ca509966111" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[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.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.84", +] + +[[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 = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" + +[[package]] +name = "ttf-parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5902c5d130972a0000f60860bfbf46f7ca3db5391eddfedd1b8728bd9dc96c0e" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +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.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.84", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.84", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "wayland-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +dependencies = [ + "bitflags 2.6.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.6.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" +dependencies = [ + "rustix", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wgpu" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d1c4ba43f80542cf63a0a6ed3134629ae73e8ab51e4b765a67f3aa062eb433" +dependencies = [ + "arrayvec", + "cfg_aliases 0.1.1", + "document-features", + "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 = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0348c840d1051b8e86c3bcd31206080c5e71e5933dabd79be1ce732b0b2f089a" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.6.0", + "cfg_aliases 0.1.1", + "document-features", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash", + "smallvec", + "thiserror", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6bbf4b4de8b2a83c0401d9e5ae0080a2792055f25859a02bf9be97952bbed4f" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.6.0", + "block", + "cfg_aliases 0.1.1", + "core-graphics-types", + "d3d12", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "once_cell", + "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 = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9d91f0e2c4b51434dfa6db77846f2793149d8e73f800fa2e41f52b8eac3c5d" +dependencies = [ + "bitflags 2.6.0", + "js-sys", + "web-sys", +] + +[[package]] +name = "wide" +version = "0.7.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b828f995bf1e9622031f8009f8481a85406ce1f4d4588ff746d872043e855690" +dependencies = [ + "bytemuck", + "safe_arch", +] + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "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 = "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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winit" +version = "0.30.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be9e76a1f1077e04a411f0b989cbd3c93339e1771cb41e71ac4aee95bfd2c67" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.6.0", + "block2", + "bytemuck", + "calloop", + "cfg_aliases 0.2.1", + "concurrent-queue", + "core-foundation", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix", + "sctk-adwaita", + "smithay-client-toolkit", + "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 = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +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.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" + +[[package]] +name = "xcursor" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.6.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.84", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a8f27a7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "fractal" +version = "0.1.0" +edition = "2021" + +[dependencies] +winit = "0.30.5" +wgpu = "22.1.0" +nalgebra = "0.33.1" +pollster = "0.3.0" +bytemuck = "1.19.0" +num-traits = "0.2.19" diff --git a/src/client/app.rs b/src/client/app.rs new file mode 100644 index 0000000..b7515cc --- /dev/null +++ b/src/client/app.rs @@ -0,0 +1,50 @@ +use winit::{application::ApplicationHandler, event_loop::ControlFlow}; + +use super::Client; + +pub struct ClientApp<'a> { + client: Option>, +} + +impl ClientApp<'_> { + pub fn new() -> Self { + Self { client: None } + } +} + +impl ApplicationHandler for ClientApp<'_> { + fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { + if self.client.is_none() { + self.client = Some(Client::new(event_loop)); + } + event_loop.set_control_flow(ControlFlow::Poll); + } + + fn window_event( + &mut self, + _event_loop: &winit::event_loop::ActiveEventLoop, + _window_id: winit::window::WindowId, + event: winit::event::WindowEvent, + ) { + if let Some(c) = self.client.as_mut() { + c.window_event(event) + } + } + + fn device_event( + &mut self, + _event_loop: &winit::event_loop::ActiveEventLoop, + _device_id: winit::event::DeviceId, + event: winit::event::DeviceEvent, + ) { + if let Some(c) = self.client.as_mut() { + c.input.update_device(event) + } + } + + fn about_to_wait(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { + if let Some(c) = self.client.as_mut() { + c.update(event_loop) + } + } +} diff --git a/src/client/camera.rs b/src/client/camera.rs new file mode 100644 index 0000000..b7ad179 --- /dev/null +++ b/src/client/camera.rs @@ -0,0 +1,59 @@ +use nalgebra::Vector2; +use std::ops::AddAssign; + +use crate::util::FixedDec; + +#[derive(Clone, Copy)] +pub struct Zoom { + scale: f32, + mult: f32, +} + +#[derive(Clone)] +pub struct Camera { + pub pos: Vector2, + pub zoom: Zoom, +} + +impl Camera { + pub fn scale(&self, size: &Vector2) -> Vector2 { + let fsize: Vector2 = size.cast(); + if size.x < size.y { + Vector2::new(fsize.x / fsize.y, 1.0) + } else { + Vector2::new(1.0, fsize.y / fsize.x) + } + } +} + +impl Default for Camera { + fn default() -> Self { + Self { + pos: Vector2::zeros(), + zoom: Zoom::new(0.0), + } + } +} + +impl Zoom { + pub fn new(scale: f32) -> Self { + Self { + scale, + mult: mult(scale), + } + } + pub fn mult(&self) -> f32 { + self.mult + } +} + +impl AddAssign for Zoom { + fn add_assign(&mut self, rhs: f32) { + self.scale += rhs; + self.mult = mult(self.scale); + } +} + +pub fn mult(scale: f32) -> f32 { + (-scale).exp2() +} diff --git a/src/client/handle_input.rs b/src/client/handle_input.rs new file mode 100644 index 0000000..41bc93c --- /dev/null +++ b/src/client/handle_input.rs @@ -0,0 +1,32 @@ +use std::time::Duration; + +use winit::keyboard::KeyCode as K; + +use crate::util::FixedDec; + +use super::Client; + +impl Client<'_> { + pub fn handle_input(&mut self, delta: Duration) { + let Client { input, camera, .. } = self; + let per_sec = delta.as_secs_f32(); + + if input.scroll_delta != 0.0 { + // camera.zoom += input.scroll_delta / 5.0; + } + + let speed = FixedDec::from(per_sec * 0.5); + if input.pressed(K::KeyW) { + camera.pos.y += &speed; + } + if input.pressed(K::KeyA) { + camera.pos.x -= &speed; + } + if input.pressed(K::KeyS) { + camera.pos.y -= &speed; + } + if input.pressed(K::KeyD) { + camera.pos.x += &speed; + } + } +} diff --git a/src/client/input.rs b/src/client/input.rs new file mode 100644 index 0000000..2444de7 --- /dev/null +++ b/src/client/input.rs @@ -0,0 +1,134 @@ +use std::collections::HashSet; + +use nalgebra::Vector2; +use winit::{ + event::{DeviceEvent, ElementState, MouseButton, MouseScrollDelta, WindowEvent}, + keyboard::{KeyCode, PhysicalKey}, +}; + +pub struct Input { + pub mouse_pixel_pos: Vector2, + pub mouse_delta: Vector2, + + pressed: HashSet, + just_pressed: HashSet, + + mouse_pressed: HashSet, + mouse_just_pressed: HashSet, + mouse_just_released: HashSet, + + pub scroll_delta: f32, +} + +impl Input { + pub fn new() -> Self { + Self { + mouse_pixel_pos: Vector2::zeros(), + mouse_delta: Vector2::zeros(), + pressed: HashSet::new(), + just_pressed: HashSet::new(), + mouse_pressed: HashSet::new(), + mouse_just_pressed: HashSet::new(), + mouse_just_released: HashSet::new(), + scroll_delta: 0.0, + } + } + pub fn update_device(&mut self, event: DeviceEvent) { + match event { + DeviceEvent::MouseWheel { delta } => { + self.scroll_delta = match delta { + MouseScrollDelta::LineDelta(_, v) => v, + MouseScrollDelta::PixelDelta(v) => (v.y / 2.0) as f32, + }; + } + DeviceEvent::MouseMotion { delta } => { + self.mouse_delta += Vector2::new(delta.0 as f32, delta.1 as f32); + } + _ => (), + } + } + + pub fn update_window(&mut self, event: WindowEvent) { + match event { + WindowEvent::KeyboardInput { event, .. } => { + let code = if let PhysicalKey::Code(code) = event.physical_key { + code + } else { + return; + }; + match event.state { + ElementState::Pressed => { + self.just_pressed.insert(code); + self.pressed.insert(code); + } + ElementState::Released => { + self.pressed.remove(&code); + } + }; + } + WindowEvent::CursorLeft { .. } => { + self.pressed.clear(); + self.mouse_pressed.clear(); + } + WindowEvent::CursorMoved { position, .. } => { + self.mouse_pixel_pos = Vector2::new(position.x as f32, position.y as f32); + } + WindowEvent::MouseInput { button, state, .. } => match state { + ElementState::Pressed => { + self.mouse_just_pressed.insert(button); + self.mouse_pressed.insert(button); + } + ElementState::Released => { + self.mouse_pressed.remove(&button); + self.mouse_just_released.insert(button); + } + }, + WindowEvent::MouseWheel { delta, .. } => { + self.scroll_delta = match delta { + MouseScrollDelta::LineDelta(_, v) => v, + MouseScrollDelta::PixelDelta(v) => (v.y / 2.0) as f32, + }; + } + _ => (), + } + } + + pub fn end(&mut self) { + self.scroll_delta = 0.0; + self.mouse_delta = Vector2::zeros(); + self.just_pressed.clear(); + self.mouse_just_pressed.clear(); + self.mouse_just_released.clear(); + } + + pub fn clear(&mut self) { + self.pressed.clear(); + self.mouse_pressed.clear(); + self.end(); + } + + #[allow(dead_code)] + pub fn pressed(&self, key: KeyCode) -> bool { + self.pressed.contains(&key) + } + + #[allow(dead_code)] + pub fn just_pressed(&self, key: KeyCode) -> bool { + self.just_pressed.contains(&key) + } + + #[allow(dead_code)] + pub fn mouse_pressed(&self, button: MouseButton) -> bool { + self.mouse_pressed.contains(&button) + } + + #[allow(dead_code)] + pub fn mouse_just_pressed(&self, button: MouseButton) -> bool { + self.mouse_just_pressed.contains(&button) + } + + #[allow(dead_code)] + pub fn mouse_just_released(&self, button: MouseButton) -> bool { + self.mouse_just_released.contains(&button) + } +} diff --git a/src/client/mod.rs b/src/client/mod.rs new file mode 100644 index 0000000..5d7e3a1 --- /dev/null +++ b/src/client/mod.rs @@ -0,0 +1,73 @@ +use std::{sync::Arc, time::Instant}; + +use camera::Camera; +use input::Input; +use render::Renderer; +use winit::{ + event::WindowEvent, + window::{Window, WindowAttributes}, +}; + +mod app; +mod camera; +mod handle_input; +mod input; +mod render; + +pub use app::*; + +pub struct Client<'a> { + window: Arc, + camera: Camera, + input: Input, + exit: bool, + prev_update: Instant, + renderer: Renderer<'a>, +} + +impl Client<'_> { + pub fn new(event_loop: &winit::event_loop::ActiveEventLoop) -> Self { + let window = Arc::new( + event_loop + .create_window(WindowAttributes::default()) + .expect("failed to create window"), + ); + let renderer = Renderer::new(window.clone()); + Self { + window, + camera: Camera::default(), + input: Input::new(), + exit: false, + prev_update: Instant::now(), + renderer, + } + } + + pub fn update(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { + if self.exit { + event_loop.exit(); + } + + let now = Instant::now(); + self.handle_input(now - self.prev_update); + self.input.end(); + + self.prev_update = now; + } + + pub fn window_event(&mut self, event: WindowEvent) { + match event { + WindowEvent::CloseRequested => self.exit = true, + WindowEvent::Resized(size) => self.renderer.resize(size), + WindowEvent::RedrawRequested => { + self.renderer.update(&self.camera); + self.renderer.draw(); + self.window.request_redraw(); + } + WindowEvent::CursorLeft { .. } => { + self.input.clear(); + } + _ => self.input.update_window(event), + } + } +} diff --git a/src/client/render/mod.rs b/src/client/render/mod.rs new file mode 100644 index 0000000..0d2a2a7 --- /dev/null +++ b/src/client/render/mod.rs @@ -0,0 +1,164 @@ +mod tile; +mod util; + +use std::sync::Arc; + +use nalgebra::Vector2; +use tile::TilePipeline; +use util::GPUTimer; +use winit::{dpi::PhysicalSize, window::Window}; + +use super::camera::Camera; + +pub struct Renderer<'a> { + size: Vector2, + surface: wgpu::Surface<'a>, + device: wgpu::Device, + queue: wgpu::Queue, + encoder: wgpu::CommandEncoder, + config: wgpu::SurfaceConfiguration, + staging_belt: wgpu::util::StagingBelt, + timer: GPUTimer, + + tile_pipeline: TilePipeline, +} + +impl Renderer<'_> { + pub fn new(window: Arc) -> Self { + let size = window.inner_size(); + + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends: wgpu::Backends::PRIMARY, + ..Default::default() + }); + + let surface = instance + .create_surface(window) + .expect("Could not create window surface!"); + + let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::default(), + compatible_surface: Some(&surface), + force_fallback_adapter: false, + })) + .expect("Could not get adapter!"); + + let buf_size = (10f32.powi(9) * 1.5) as u32; + let (device, queue) = pollster::block_on(adapter.request_device( + &wgpu::DeviceDescriptor { + label: None, + required_features: wgpu::Features::PUSH_CONSTANTS + | wgpu::Features::TIMESTAMP_QUERY + | wgpu::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS + | wgpu::Features::TIMESTAMP_QUERY_INSIDE_PASSES, + required_limits: wgpu::Limits { + max_storage_buffer_binding_size: buf_size, + max_buffer_size: buf_size as u64, + max_push_constant_size: 4, + ..Default::default() + }, + memory_hints: wgpu::MemoryHints::default(), + }, + None, + )) + .expect("Could not get device!"); + + let info = adapter.get_info(); + println!("Adapter: {}", info.name); + println!("Backend: {:?}", info.backend); + + let surface_caps = surface.get_capabilities(&adapter); + let surface_format = surface_caps + .formats + .iter() + .copied() + .find(|f| f.is_srgb()) + .unwrap_or(surface_caps.formats[0]); + + let config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + format: surface_format, + width: size.width, + height: size.height, + present_mode: wgpu::PresentMode::AutoNoVsync, + alpha_mode: surface_caps.alpha_modes[0], + view_formats: vec![], + desired_maximum_frame_latency: 2, + }; + + surface.configure(&device, &config); + let staging_belt = wgpu::util::StagingBelt::new(1024); + let timer = GPUTimer::new(&device, queue.get_timestamp_period(), 1); + + Self { + tile_pipeline: TilePipeline::init(&device, &config), + size: Vector2::new(size.width, size.height), + staging_belt, + surface, + encoder: Self::create_encoder(&device), + timer, + device, + config, + queue, + } + } + + pub fn update(&mut self, camera: &Camera) { + self.tile_pipeline.update( + &self.device, + &mut self.encoder, + &mut self.staging_belt, + camera, + &self.size, + ); + } + + pub fn draw(&mut self) { + let mut encoder = std::mem::replace(&mut self.encoder, Self::create_encoder(&self.device)); + let output = self.surface.get_current_texture().unwrap(); + let view = output + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + + self.timer.start(&mut encoder, 0); + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("Render Pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::BLACK), + store: wgpu::StoreOp::Store, + }, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + self.tile_pipeline.draw(&mut render_pass); + drop(render_pass); + self.timer.stop(&mut encoder, 0); + + self.timer.resolve(&mut encoder); + + self.staging_belt.finish(); + self.queue.submit(std::iter::once(encoder.finish())); + output.present(); + self.staging_belt.recall(); + + self.timer.finish(&self.device); + } + + pub fn resize(&mut self, size: PhysicalSize) { + self.size = Vector2::new(size.width, size.height); + self.config.width = size.width; + self.config.height = size.height; + self.surface.configure(&self.device, &self.config); + } + + fn create_encoder(device: &wgpu::Device) -> wgpu::CommandEncoder { + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("Render Encoder"), + }) + } +} diff --git a/src/client/render/tile/data.rs b/src/client/render/tile/data.rs new file mode 100644 index 0000000..93730a5 --- /dev/null +++ b/src/client/render/tile/data.rs @@ -0,0 +1,30 @@ +use nalgebra::Vector2; + +#[repr(C, align(8))] +#[derive(Clone, Copy)] +pub struct View { + pub scale: Vector2, +} + +impl Default for View { + fn default() -> Self { + Self { + scale: Vector2::zeros(), + } + } +} + +impl View { + pub fn new(size: &Vector2) -> Self { + let fsize: Vector2 = size.cast(); + let scale = if size.x < size.y { + Vector2::new(fsize.x / fsize.y, 1.0) + } else { + Vector2::new(1.0, fsize.y / fsize.x) + }; + View { scale } + } +} + +unsafe impl bytemuck::Pod for View {} +unsafe impl bytemuck::Zeroable for View {} diff --git a/src/client/render/tile/layout.rs b/src/client/render/tile/layout.rs new file mode 100644 index 0000000..446b17a --- /dev/null +++ b/src/client/render/tile/layout.rs @@ -0,0 +1,86 @@ +use super::{util::Uniform, View}; + +pub struct TileLayout { + render_bind_layout: wgpu::BindGroupLayout, + render_pipeline_layout: wgpu::PipelineLayout, + format: wgpu::TextureFormat, + pub view: Uniform, +} + +impl TileLayout { + pub fn init(device: &wgpu::Device, config: &wgpu::SurfaceConfiguration) -> Self { + let view = Uniform::init(device, "view"); + + let render_bind_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + entries: &[view.bind_group_layout_entry(0)], + label: Some("voxel render"), + }); + + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Tile Pipeline Layout"), + bind_group_layouts: &[&render_bind_layout], + push_constant_ranges: &[], + }); + + Self { + view, + render_bind_layout, + render_pipeline_layout, + format: config.format, + } + } + + pub fn render_bind_group(&self, device: &wgpu::Device) -> wgpu::BindGroup { + device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &self.render_bind_layout, + entries: &[self.view.bind_group_entry(0)], + label: Some("voxel render"), + }) + } + + pub fn render_pipeline( + &self, + device: &wgpu::Device, + shader: wgpu::ShaderModule, + ) -> wgpu::RenderPipeline { + device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Voxel Pipeline"), + layout: Some(&self.render_pipeline_layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vs_main", + buffers: &[], + compilation_options: wgpu::PipelineCompilationOptions::default(), + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_main", + targets: &[Some(wgpu::ColorTargetState { + format: self.format, + blend: Some(wgpu::BlendState::REPLACE), + write_mask: wgpu::ColorWrites::ALL, + })], + compilation_options: wgpu::PipelineCompilationOptions::default(), + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleStrip, + strip_index_format: None, + front_face: wgpu::FrontFace::Ccw, + cull_mode: None, + polygon_mode: wgpu::PolygonMode::Fill, + unclipped_depth: false, + conservative: false, + }, + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: true, + }, + multiview: None, + cache: None, + }) + } +} diff --git a/src/client/render/tile/mod.rs b/src/client/render/tile/mod.rs new file mode 100644 index 0000000..b0e9cfc --- /dev/null +++ b/src/client/render/tile/mod.rs @@ -0,0 +1,61 @@ +use std::ops::{Deref, DerefMut}; + +use wgpu::include_wgsl; + +mod data; +mod layout; + +use super::*; +pub use data::*; +use layout::*; + +pub struct TilePipeline { + layout: TileLayout, + render_pipeline: wgpu::RenderPipeline, + render_bind_group: wgpu::BindGroup, +} + +const RENDER_SHADER: wgpu::ShaderModuleDescriptor<'_> = include_wgsl!("render.wgsl"); + +impl TilePipeline { + pub fn init(device: &wgpu::Device, config: &wgpu::SurfaceConfiguration) -> Self { + let layout = TileLayout::init(device, config); + let render_shader = device.create_shader_module(RENDER_SHADER); + Self { + render_pipeline: layout.render_pipeline(device, render_shader), + render_bind_group: layout.render_bind_group(device), + layout, + } + } + + pub fn update( + &mut self, + device: &wgpu::Device, + encoder: &mut wgpu::CommandEncoder, + belt: &mut wgpu::util::StagingBelt, + camera: &Camera, + size: &Vector2, + ) { + self.view.update(device, encoder, belt, View::new(size)); + } + + pub fn draw<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) { + render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_bind_group(0, &self.render_bind_group, &[]); + render_pass.draw(0..4, 0..1); + } +} + +impl Deref for TilePipeline { + type Target = TileLayout; + + fn deref(&self) -> &Self::Target { + &self.layout + } +} + +impl DerefMut for TilePipeline { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.layout + } +} diff --git a/src/client/render/tile/render.wgsl b/src/client/render/tile/render.wgsl new file mode 100644 index 0000000..ded747c --- /dev/null +++ b/src/client/render/tile/render.wgsl @@ -0,0 +1,110 @@ +// Vertex shader + +struct VertexOutput { + @builtin(position) vertex_pos: vec4, + @location(0) world_pos: vec2, +}; + +struct View { + scale: vec2, + // x_dec: i32, + // y_dec: i32, + // prec: u32, +} + +@group(0) @binding(0) +var view: View; +// @group(0) @binding(1) +// var vx: array; +// @group(0) @binding(2) +// var vy: array; + +@vertex +fn vs_main( + @builtin(vertex_index) vi: u32, + @builtin(instance_index) ii: u32, +) -> VertexOutput { + var out: VertexOutput; + + let pos = vec2( + f32(vi % 2u), + f32(vi / 2u), + ) * 2.0 - 1.0; + out.vertex_pos = vec4(pos.x, -pos.y, 0.0, 1.0); + out.world_pos = pos; + out.world_pos.y *= -1.0; + out.world_pos *= view.scale; + return out; +} + +// const PREC = 2; + +@fragment +fn fs_main( + in: VertexOutput, +) -> @location(0) vec4 { + let dec = i32(1) << 13; + let c = vec2(in.world_pos * f32(dec)); + let cx = c.x; + let cy = c.y; + var x = 0; + var y = 0; + var i = 0u; + let thresh = 2 * dec; + let thresh2 = thresh * thresh; + let max = 50u; + loop { + let x2 = x * x; + let y2 = y * y; + if x2 + y2 > thresh2 || i >= max { + break; + } + y = (2 * x * y) / dec + c.y; + x = (x2 - y2) / dec + c.x; + i += 1u; + } + var color = vec3(0.0, 0.0, 0.0); + if i != max { + let pi = 3.1415; + let hue = f32(i) / 30.0; + color.r = cos(hue); + color.g = cos(hue - 2.0 * pi / 3.0); + color.b = cos(hue - 4.0 * pi / 3.0); + } + return vec4(color, 1.0); +} + +// @fragment +// fn fs_main( +// in: VertexOutput, +// ) -> @location(0) vec4 { +// let dec = i32(1) << 13; +// let c = vec2(in.world_pos * f32(dec)); +// let cx = c.x; +// let cy = c.y; +// var x = 0; +// var y = 0; +// var i = 0u; +// let thresh = 2 * dec; +// let thresh2 = thresh * thresh; +// let max = 50u + u32(in.zoom); +// loop { +// let x2 = x * x; +// let y2 = y * y; +// if x2 + y2 > thresh2 || i >= max { +// break; +// } +// y = (2 * x * y) / dec + c.y; +// x = (x2 - y2) / dec + c.x; +// i += 1u; +// } +// var color = vec3(0.0, 0.0, 0.0); +// if i != max { +// let pi = 3.1415; +// let hue = f32(i) / 30.0; +// color.r = cos(hue); +// color.g = cos(hue - 2.0 * pi / 3.0); +// color.b = cos(hue - 4.0 * pi / 3.0); +// } +// return vec4(color, 1.0); +// } diff --git a/src/client/render/util/array.rs b/src/client/render/util/array.rs new file mode 100644 index 0000000..74a534d --- /dev/null +++ b/src/client/render/util/array.rs @@ -0,0 +1,146 @@ +use wgpu::{util::DeviceExt, BufferAddress, BufferUsages}; + +pub struct ArrayBuffer { + len: usize, + new_len: usize, + buffer: wgpu::Buffer, + label: String, + usage: BufferUsages, + updates: Vec>, +} + +impl ArrayBuffer { + pub fn update( + &mut self, + device: &wgpu::Device, + encoder: &mut wgpu::CommandEncoder, + belt: &mut wgpu::util::StagingBelt, + ) -> bool { + let mut resized = false; + if self.new_len != self.len { + let new = Self::init_buf(device, &self.label, self.new_len, self.usage); + let cpy_len = self.len.min(self.new_len); + if cpy_len != 0 { + encoder.copy_buffer_to_buffer( + &self.buffer, + 0, + &new, + 0, + (cpy_len * std::mem::size_of::()) as u64, + ); + } + self.len = self.new_len; + resized = true; + self.buffer = new; + } + if self.len == 0 { + return resized; + } + for update in &self.updates { + let mut view = belt.write_buffer( + encoder, + &self.buffer, + (update.offset * std::mem::size_of::()) as BufferAddress, + unsafe { + std::num::NonZeroU64::new_unchecked( + std::mem::size_of_val(&update.data[..]) as u64 + ) + }, + device, + ); + view.copy_from_slice(bytemuck::cast_slice(&update.data)); + } + self.updates.clear(); + resized + } + + pub fn add(&mut self, data: Vec) -> usize { + let data_len = data.len(); + let pos = self.new_len; + self.updates.push(ArrBufUpdate { offset: pos, data }); + self.new_len += data_len; + pos + } + + pub fn set(&mut self, offset: usize, data: Vec) { + self.updates.push(ArrBufUpdate { offset, data }); + } + + pub fn init(device: &wgpu::Device, label: &str, usage: BufferUsages) -> Self { + let label = &(label.to_owned() + " Buffer"); + Self::init_with(device, label, usage, &[]) + } + + pub fn init_with(device: &wgpu::Device, label: &str, usage: BufferUsages, data: &[T]) -> Self { + let label = &(label.to_owned() + " Buffer"); + Self { + len: data.len(), + new_len: data.len(), + buffer: if data.is_empty() { + Self::init_buf(device, label, 0, usage) + } else { + Self::init_buf_with(device, label, usage, data) + }, + label: label.to_string(), + updates: Vec::new(), + usage, + } + } + + fn init_buf( + device: &wgpu::Device, + label: &str, + size: usize, + usage: BufferUsages, + ) -> wgpu::Buffer { + device.create_buffer(&wgpu::BufferDescriptor { + label: Some(label), + usage: usage | BufferUsages::COPY_DST | BufferUsages::COPY_SRC, + size: (size.max(1) * std::mem::size_of::()) as u64, + mapped_at_creation: false, + }) + } + + fn init_buf_with( + device: &wgpu::Device, + label: &str, + usage: BufferUsages, + data: &[T], + ) -> wgpu::Buffer { + device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some(label), + usage: usage | BufferUsages::COPY_DST | BufferUsages::COPY_SRC, + contents: bytemuck::cast_slice(data), + }) + } + + pub fn bind_group_layout_entry( + &self, + binding: u32, + visibility: wgpu::ShaderStages, + ty: wgpu::BufferBindingType, + ) -> wgpu::BindGroupLayoutEntry { + wgpu::BindGroupLayoutEntry { + binding, + visibility, + ty: wgpu::BindingType::Buffer { + ty, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + } + } + + pub fn bind_group_entry(&self, binding: u32) -> wgpu::BindGroupEntry { + wgpu::BindGroupEntry { + binding, + resource: self.buffer.as_entire_binding(), + } + } +} + +pub struct ArrBufUpdate { + pub offset: usize, + pub data: Vec, +} diff --git a/src/client/render/util/mod.rs b/src/client/render/util/mod.rs new file mode 100644 index 0000000..d130511 --- /dev/null +++ b/src/client/render/util/mod.rs @@ -0,0 +1,12 @@ +#![allow(unused_imports)] +#![allow(dead_code)] + +mod texture; +mod timer; +mod uniform; +mod array; + +pub use texture::*; +pub use timer::*; +pub use uniform::*; +pub use array::*; diff --git a/src/client/render/util/texture.rs b/src/client/render/util/texture.rs new file mode 100644 index 0000000..49bd121 --- /dev/null +++ b/src/client/render/util/texture.rs @@ -0,0 +1,91 @@ +pub struct Texture { + texture_desc: wgpu::TextureDescriptor<'static>, + view_desc: wgpu::TextureViewDescriptor<'static>, + sampler_desc: wgpu::SamplerDescriptor<'static>, + pub texture: wgpu::Texture, + pub view: wgpu::TextureView, + pub sampler: wgpu::Sampler, +} + +impl Texture { + pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; + + pub fn init_depth( + device: &wgpu::Device, + config: &wgpu::SurfaceConfiguration, + label: &'static str, + ) -> Self { + let size = wgpu::Extent3d { + width: config.width + 1, + height: config.height + 1, + depth_or_array_layers: 1, + }; + let texture_desc = wgpu::TextureDescriptor { + label: Some(label), + size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: Self::DEPTH_FORMAT, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }; + Self::init( + device, + texture_desc, + wgpu::TextureViewDescriptor::default(), + wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Nearest, + compare: Some(wgpu::CompareFunction::LessEqual), + lod_min_clamp: 0.0, + lod_max_clamp: 100.0, + ..Default::default() + }, + ) + } + + pub fn init( + device: &wgpu::Device, + texture_desc: wgpu::TextureDescriptor<'static>, + view_desc: wgpu::TextureViewDescriptor<'static>, + sampler_desc: wgpu::SamplerDescriptor<'static>, + ) -> Self { + let texture = device.create_texture(&texture_desc); + let view = texture.create_view(&view_desc); + let sampler = device.create_sampler(&sampler_desc); + Self { + texture_desc, + view_desc, + sampler_desc, + texture, + view, + sampler, + } + } + + pub fn resize(&mut self, device: &wgpu::Device, size: wgpu::Extent3d) { + self.texture_desc.size = size; + self.texture = device.create_texture(&self.texture_desc); + self.view = self.texture.create_view(&self.view_desc); + } + pub fn view_bind_group_entry(&self, binding: u32) -> wgpu::BindGroupEntry { + wgpu::BindGroupEntry { + binding, + resource: wgpu::BindingResource::TextureView(&self.view), + } + } + pub fn sampler_bind_group_entry(&self, binding: u32) -> wgpu::BindGroupEntry { + wgpu::BindGroupEntry { + binding, + resource: wgpu::BindingResource::Sampler(&self.sampler), + } + } + pub fn format(&self) -> wgpu::TextureFormat { + self.texture_desc.format + } +} diff --git a/src/client/render/util/timer.rs b/src/client/render/util/timer.rs new file mode 100644 index 0000000..50251a3 --- /dev/null +++ b/src/client/render/util/timer.rs @@ -0,0 +1,89 @@ +use std::time::Duration; + +pub struct GPUTimer { + resolve_buf: wgpu::Buffer, + map_buf: wgpu::Buffer, + query_set: wgpu::QuerySet, + timestamps: Vec, + period: f32, +} + +impl GPUTimer { + pub fn new(device: &wgpu::Device, period: f32, count: u32) -> Self { + let count = count * 2; + let timestamp_set = device.create_query_set(&wgpu::QuerySetDescriptor { + count, + label: Some("voxel timestamp"), + ty: wgpu::QueryType::Timestamp, + }); + let timestamp_resolve_buf = device.create_buffer(&wgpu::BufferDescriptor { + label: Some("voxel timestamp"), + mapped_at_creation: false, + size: 8 * count as u64, + usage: wgpu::BufferUsages::QUERY_RESOLVE | wgpu::BufferUsages::COPY_SRC, + }); + + let timestamp_mapped_buf = device.create_buffer(&wgpu::BufferDescriptor { + label: Some("voxel timestamp"), + mapped_at_creation: false, + size: 8 * count as u64, + usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, + }); + + Self { + query_set: timestamp_set, + resolve_buf: timestamp_resolve_buf, + map_buf: timestamp_mapped_buf, + timestamps: vec![0; count as usize], + period, + } + } + + pub fn resolve(&self, encoder: &mut wgpu::CommandEncoder) { + encoder.resolve_query_set(&self.query_set, 0..2, &self.resolve_buf, 0); + encoder.copy_buffer_to_buffer(&self.resolve_buf, 0, &self.map_buf, 0, self.map_buf.size()); + } + + pub fn duration(&self, i: u32) -> Duration { + let i = i as usize * 2; + let diff = self.timestamps[i + 1] - self.timestamps[i]; + Duration::from_nanos((diff as f32 * self.period) as u64) + } + + pub fn finish(&mut self, device: &wgpu::Device) { + let (s, r) = std::sync::mpsc::channel(); + self.map_buf + .slice(..) + .map_async(wgpu::MapMode::Read, move |v| { + s.send(v).expect("what"); + }); + device.poll(wgpu::Maintain::wait()).panic_on_timeout(); + if let Ok(Ok(())) = r.recv() { + let data = self.map_buf.slice(..).get_mapped_range(); + self.timestamps.copy_from_slice(bytemuck::cast_slice(&data)); + drop(data); + self.map_buf.unmap(); + } + } + + #[allow(dead_code)] + pub fn start(&self, encoder: &mut wgpu::CommandEncoder, i: u32) { + encoder.write_timestamp(&self.query_set, i * 2); + } + + #[allow(dead_code)] + pub fn stop(&self, encoder: &mut wgpu::CommandEncoder, i: u32) { + encoder.write_timestamp(&self.query_set, i * 2 + 1); + } + + #[allow(dead_code)] + pub fn start_compute(&self, pass: &mut wgpu::ComputePass, i: u32) { + pass.write_timestamp(&self.query_set, i * 2); + } + + #[allow(dead_code)] + pub fn stop_compute(&self, pass: &mut wgpu::ComputePass, i: u32) { + pass.write_timestamp(&self.query_set, i * 2 + 1); + } +} + diff --git a/src/client/render/util/uniform.rs b/src/client/render/util/uniform.rs new file mode 100644 index 0000000..e652357 --- /dev/null +++ b/src/client/render/util/uniform.rs @@ -0,0 +1,76 @@ +use std::marker::PhantomData; + +use wgpu::util::DeviceExt; + +pub struct Uniform { + buffer: wgpu::Buffer, + ty: PhantomData, +} + +impl Uniform { + pub fn init(device: &wgpu::Device, name: &str) -> Self { + Self { + buffer: device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some(&(name.to_owned() + " Uniform Buf")), + contents: bytemuck::cast_slice(&[T::default()]), + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }), + ty: PhantomData, + } + } +} + +impl Uniform { + pub fn init_with(device: &wgpu::Device, name: &str, data: &[T]) -> Self { + Self { + buffer: device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some(&(name.to_owned() + " Uniform Buf")), + contents: bytemuck::cast_slice(data), + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }), + ty: PhantomData, + } + } + pub fn update( + &mut self, + device: &wgpu::Device, + encoder: &mut wgpu::CommandEncoder, + belt: &mut wgpu::util::StagingBelt, + data: T, + ) { + let slice = &[data]; + let mut view = belt.write_buffer( + encoder, + &self.buffer, + 0, + unsafe { + std::num::NonZeroU64::new_unchecked((slice.len() * std::mem::size_of::()) as u64) + }, + device, + ); + view.copy_from_slice(bytemuck::cast_slice(slice)); + } +} + +impl Uniform { + pub fn bind_group_layout_entry(&self, binding: u32) -> wgpu::BindGroupLayoutEntry { + wgpu::BindGroupLayoutEntry { + binding, + visibility: wgpu::ShaderStages::VERTEX + | wgpu::ShaderStages::FRAGMENT + | wgpu::ShaderStages::COMPUTE, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + } + } + pub fn bind_group_entry(&self, binding: u32) -> wgpu::BindGroupEntry { + wgpu::BindGroupEntry { + binding, + resource: self.buffer.as_entire_binding(), + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b8ef9e2 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,25 @@ +#![feature(bigint_helper_methods)] + +use client::ClientApp; +use util::FixedDec; + +mod client; +mod util; + +fn main() { + let a = FixedDec::from(0.75); + println!("a = {}", a); + let b = FixedDec::from(1.75); + println!("b = {}", b); + println!("a + b = {}", &a + &b); + let c = FixedDec::from(1.0 / 16.0); + println!("c = {}", c); + println!("a + c = {}", &a + &c); + println!("-a = {}", -&a); + println!("b - a = {}", &b - &a); + println!("-c = {}", -&c); + // let event_loop = winit::event_loop::EventLoop::new().expect("Failed to create event loop"); + // event_loop + // .run_app(&mut ClientApp::new()) + // .expect("Failed to run event loop"); +} diff --git a/src/util/fixed.rs b/src/util/fixed.rs new file mode 100644 index 0000000..f7dce39 --- /dev/null +++ b/src/util/fixed.rs @@ -0,0 +1,338 @@ +use num_traits::Zero; +use std::{ + fmt::{Binary, Debug, Display}, + ops::{Add, AddAssign, Mul, Neg, Shr, Sub, SubAssign}, +}; + +const POS: bool = false; +const NEG: bool = true; + +#[derive(Debug, Clone, PartialEq)] +pub struct FixedDec { + sign: bool, + dec: i32, + parts: Vec, +} + +impl FixedDec { + pub fn zeros() -> Self { + Self::zero() + } + + pub fn dec_len(&self) -> i32 { + self.parts.len() as i32 - self.dec + } + + pub fn part(&self, i: i32) -> u32 { + let Ok(i): Result = i.try_into() else { + return self.pre_padding(); + }; + self.parts.get(i).cloned().unwrap_or(0) + } + + pub fn is_pos(&self) -> bool { + !self.sign + } + + pub fn is_neg(&self) -> bool { + self.sign + } + + fn pre_padding(&self) -> u32 { + match self.sign { + POS => 0, + NEG => !0, + } + } +} + +impl Zero for FixedDec { + fn zero() -> Self { + Self { + sign: POS, + dec: 0, + parts: Vec::new(), + } + } + + fn is_zero(&self) -> bool { + self.parts.iter().all(|&b| b == 0) + } +} + +impl Shr for FixedDec { + type Output = Self; + + fn shr(self, rhs: u32) -> Self::Output { + let mut parts = Vec::new(); + let sr = rhs % 32; + let sl = 32 - sr; + let mask = (1 << sr) - 1; + let dec = self.dec - (rhs / 32) as i32; + let mut rem = 0; + for part in self.parts { + parts.push((part >> sr) ^ rem); + rem = (part & mask) << sl; + } + if rem != 0 { + parts.push(rem); + } + Self { + dec, + parts, + sign: self.sign, + } + } +} + +impl Add for FixedDec { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + &self + &rhs + } +} + +impl AddAssign<&FixedDec> for FixedDec { + fn add_assign(&mut self, rhs: &FixedDec) { + let dec = self.dec.max(rhs.dec); + let left_i = -dec; + let right_i = self.dec_len().max(rhs.dec_len()); + let len = (right_i - left_i) as usize; + if dec != self.dec { + let fill = self.pre_padding(); + let fill_len = rhs.dec - self.dec; + self.parts.splice(0..0, (0..fill_len).map(|_| fill)); + self.dec += fill_len; + } + if self.parts.len() != len { + self.parts.resize(len, 0); + } + let mut carry = false; + let rhs_offset = rhs.dec - self.dec; + for i in (0..self.parts.len()).rev() { + let a = self.parts[i]; + let b = rhs.part(i as i32 + rhs_offset); + let (res, c) = a.carrying_add(b, carry); + self.parts[i] = res; + carry = c; + } + let sign = if self.sign == rhs.sign { + if self.sign == POS && carry { + self.parts.insert(0, 1); + self.dec += 1; + } else if self.sign == NEG && !carry { + self.parts.insert(0, !1); + self.dec += 1; + } + self.sign + } else if carry { + POS + } else { + NEG + }; + self.sign = sign; + } +} + +impl SubAssign<&FixedDec> for FixedDec { + fn sub_assign(&mut self, rhs: &FixedDec) { + *self += &-rhs; + } +} + +impl Add for &FixedDec { + type Output = FixedDec; + + fn add(self, rhs: Self) -> Self::Output { + let mut dec = self.dec.max(rhs.dec); + let left_i = -dec; + let right_i = self.dec_len().max(rhs.dec_len()); + let mut parts = Vec::with_capacity((right_i - left_i) as usize); + let mut carry = false; + for i in (left_i..right_i).rev() { + let a = self.part(i + self.dec); + let b = rhs.part(i + rhs.dec); + let (res, c) = a.carrying_add(b, carry); + parts.push(res); + carry = c; + } + let sign = if self.sign == rhs.sign { + if self.is_pos() && carry { + parts.push(1); + dec += 1; + } else if self.is_neg() && !carry { + parts.push(!1); + dec += 1; + } + self.sign + } else if carry { + POS + } else { + NEG + }; + parts.reverse(); + FixedDec { parts, dec, sign } + } +} + +impl Sub for &FixedDec { + type Output = FixedDec; + + fn sub(self, rhs: Self) -> Self::Output { + self + &(-rhs) + } +} + +impl Neg for &FixedDec { + type Output = FixedDec; + + fn neg(self) -> Self::Output { + let parts = self.parts.iter().map(|p| !p).collect(); + let mut res = FixedDec { + parts, + sign: !self.sign, + dec: self.dec, + }; + res += &Self::Output { + parts: vec![1], + dec: self.dec - (self.parts.len() as i32 - 1), + sign: POS, + }; + res + } +} + +impl Mul for &FixedDec { + type Output = FixedDec; + + fn mul(self, rhs: Self) -> Self::Output { + let mut parts: Vec = vec![0; self.parts.len() + rhs.parts.len()]; + for (i, &x) in self.parts.iter().enumerate().rev() { + let mut carry: u32 = 0; + for (j, &y) in rhs.parts.iter().enumerate().rev() { + let (lsb, msb) = mul_lmsb(x, y); + let k = i + j + 1; + let (res, carry1) = parts[k].overflowing_add(lsb); + parts[k] = res; + let (res, carry2) = parts[k].overflowing_add(carry); + parts[k] = res; + // dude I have no clue if this can overflow; I know msb can take 1 without + // overflowing, but I'm not sure if 2 can get here when it's max + carry = (carry1 as u32) + (carry2 as u32) + msb; + } + if carry > 0 { + parts[i] = carry; + } + } + Self::Output { + dec: self.dec + rhs.dec, + parts, + sign: self.sign == rhs.sign, + } + } +} + +fn mul_lmsb(x: u32, y: u32) -> (u32, u32) { + let lsb = x.wrapping_mul(y); + let a = x & 0xffff; + let b = x >> 16; + let c = y & 0xffff; + let d = y >> 16; + let ad = a * d + ((a * c) >> 16); + let bc = b * c; + let car = ad > (0xffffffff - bc); + let msb = ((ad + bc) >> 16) + ((car as u32) << 16) + b * d; + (lsb, msb) +} + +const INV_SIGN_MASK: u32 = (1 << 31) - 1; +const FRAC_BIT: u32 = 1 << 23; +const FRAC_MASK: u32 = FRAC_BIT - 1; + +impl From for FixedDec { + fn from(value: f32) -> Self { + let raw = value.to_bits() & INV_SIGN_MASK; + let exp = (raw >> 23) as i32 - 127; + let frac = (raw & FRAC_MASK) + FRAC_BIT; + let start = -exp - 1; + let end = -exp + 23; + let start_i = start.div_euclid(32); + let end_i = (end - 1).div_euclid(32); + let parts = if start_i == end_i { + vec![frac << (8 - start.rem_euclid(32))] + } else { + let s = end.rem_euclid(32); + vec![frac >> s, frac << (32 - s)] + }; + Self { + sign: POS, + dec: -start_i, + parts, + } + } +} + +impl From<&FixedDec> for f32 { + fn from(value: &FixedDec) -> Self { + let mut sign = 0; + let value = if value.is_neg() { + sign = 1 << 31; + &-value + } else { + value + }; + let mut skip_count = 0; + let mut iter = value + .parts + .iter() + .inspect(|_| skip_count += 1) + .skip_while(|&&x| x == 0); + + let Some(v) = iter.next() else { + return 0.0; + }; + let start = v.leading_zeros(); + let frac = if start > 9 { + let sh = start - 9; + (v << sh) + iter.next().copied().map(|v| v >> (32 - sh)).unwrap_or(0) + } else { + v >> (9 - start) + }; + let exp = (127 - (skip_count * 32 + start)) << 23; + let res = frac + exp + sign; + println!(); + println!("res: {:032b}", res); + println!("ans: {:032b}", 0.75f32.to_bits()); + f32::from_bits(res) + } +} + +impl Display for FixedDec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", f32::from(self)) + } +} + +impl Binary for FixedDec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.sign == NEG { + write!(f, "-")?; + } + if self.dec < 0 { + write!(f, ".")?; + for _ in 0..(-self.dec) { + write!(f, "00000000000000000000000000000000")?; + } + } + for (i, part) in self.parts.iter().enumerate() { + if i as i32 == self.dec { + write!(f, ".")?; + } else if i != 0 { + write!(f, "_")?; + } + write!(f, "{:032b}", part)?; + } + Ok(()) + } +} diff --git a/src/util/mod.rs b/src/util/mod.rs new file mode 100644 index 0000000..725c440 --- /dev/null +++ b/src/util/mod.rs @@ -0,0 +1,2 @@ +mod fixed; +pub use fixed::*;