From ad4cef9739b857a29a48b88162e07fa6ba67a4b6 Mon Sep 17 00:00:00 2001 From: Caznix Date: Thu, 3 Apr 2025 01:37:53 -0400 Subject: [PATCH] add window icon --- Cargo.lock | 495 ++++++++++++++++++++++++++++++- engine/Cargo.toml | 1 + engine/build.rs | 2 +- engine/src/core/ecs/mod.rs | 1 + engine/src/core/panic.rs | 6 +- engine/src/core/render/ctx.rs | 24 +- engine/src/core/render/mod.rs | 65 +++- engine/src/core/repl/commands.rs | 2 +- engine/src/core/repl/handler.rs | 6 +- engine/src/core/repl/mod.rs | 3 - engine/src/error.rs | 62 ++-- engine/src/main.rs | 26 +- engine/src/metadata.rs | 79 +++-- 13 files changed, 659 insertions(+), 113 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd42f48..7bc6fe5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "android-activity" version = "0.6.0" @@ -121,6 +127,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -166,6 +189,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98922d6a4cfbcb08820c69d8eeccc05bb1f29bfa06b4f5b1dbfe9a868bd7608e" +dependencies = [ + "arrayvec", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -196,6 +242,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -211,6 +263,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + [[package]] name = "block" version = "0.1.6" @@ -261,6 +319,12 @@ dependencies = [ "syn", ] +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.10.1" @@ -310,6 +374,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -395,6 +469,12 @@ dependencies = [ "unicode-width 0.1.14", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colored" version = "3.0.0" @@ -463,6 +543,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" version = "0.5.14" @@ -497,6 +586,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + [[package]] name = "cursor-icon" version = "1.1.0" @@ -594,6 +689,21 @@ version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" +[[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fd-lock" version = "4.0.4" @@ -605,6 +715,25 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "foldhash" version = "0.1.5" @@ -748,6 +877,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.31.1" @@ -875,6 +1014,16 @@ dependencies = [ "bitflags 2.9.0", ] +[[package]] +name = "half" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.15.2" @@ -934,6 +1083,45 @@ dependencies = [ "cc", ] +[[package]] +name = "image" +version = "0.25.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" + [[package]] name = "indexmap" version = "2.8.0" @@ -944,6 +1132,17 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "itertools" version = "0.11.0" @@ -953,6 +1152,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "jni" version = "0.21.1" @@ -984,6 +1192,12 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.77" @@ -1017,12 +1231,28 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +[[package]] +name = "libfuzzer-sys" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75" +dependencies = [ + "arbitrary", + "cc", +] + [[package]] name = "libloading" version = "0.8.6" @@ -1084,6 +1314,15 @@ version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -1093,6 +1332,16 @@ dependencies = [ "libc", ] +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" version = "2.7.4" @@ -1136,6 +1385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -1222,6 +1472,12 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nibble_vec" version = "0.1.0" @@ -1253,6 +1509,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "ntapi" version = "0.4.1" @@ -1272,6 +1534,47 @@ dependencies = [ "winapi", ] +[[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-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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" @@ -1673,6 +1976,19 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "polling" version = "3.7.4" @@ -1726,6 +2042,34 @@ name = "profiling" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" @@ -1791,6 +2135,56 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.12.1", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror 1.0.69", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a5f31fcf7500f9401fea858ea4ab5525c99f2322cfcee732c0e6c74208c0c6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "raw-cpuid" version = "11.5.0" @@ -1896,6 +2290,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -2058,6 +2458,21 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "slab" version = "0.4.9" @@ -2183,6 +2598,25 @@ dependencies = [ "windows 0.57.0", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "termcolor" version = "1.4.1" @@ -2242,6 +2676,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tiny-skia" version = "0.11.4" @@ -2443,12 +2888,29 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" @@ -2461,7 +2923,7 @@ version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c73a36bc44e3039f51fbee93e39f41225f6b17b380eb70cc2aab942df06b34dd" dependencies = [ - "itertools", + "itertools 0.11.0", "nom", ] @@ -2681,6 +3143,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "wfd" version = "0.1.7" @@ -3343,6 +3811,7 @@ dependencies = [ "chrono", "colored", "futures", + "image", "native-dialog", "parking_lot", "raw-cpuid", @@ -3400,3 +3869,27 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" +dependencies = [ + "zune-core", +] diff --git a/engine/Cargo.toml b/engine/Cargo.toml index 5388c30..67b856f 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -34,6 +34,7 @@ serde = { version = "1.0.219", features = ["derive"] } native-dialog = "0.7.0" sysinfo = "0.34.2" raw-cpuid = "11.5.0" +image = "0.25.6" [build-dependencies] built = { version = "0.7.7", features = ["chrono"] } diff --git a/engine/build.rs b/engine/build.rs index a7315d0..206e189 100644 --- a/engine/build.rs +++ b/engine/build.rs @@ -1,3 +1,3 @@ fn main() { built::write_built_file().expect("Failed to write build information"); -} \ No newline at end of file +} diff --git a/engine/src/core/ecs/mod.rs b/engine/src/core/ecs/mod.rs index e69de29..8b13789 100644 --- a/engine/src/core/ecs/mod.rs +++ b/engine/src/core/ecs/mod.rs @@ -0,0 +1 @@ + diff --git a/engine/src/core/panic.rs b/engine/src/core/panic.rs index b76d9a9..92d8ae1 100644 --- a/engine/src/core/panic.rs +++ b/engine/src/core/panic.rs @@ -1,7 +1,7 @@ -use std::str::FromStr; -use std::{error::Error, path::PathBuf}; use std::fmt::Write as FmtWrite; use std::mem; +use std::str::FromStr; +use std::{error::Error, path::PathBuf}; use backtrace::Backtrace; use native_dialog::{MessageDialog, MessageType}; @@ -25,9 +25,9 @@ pub fn set_panic_hook() { } fn process_panic(info: &std::panic::PanicHookInfo<'_>) -> Result<(), Box> { + use std::io::Write; use colored::Colorize; - use std::io::Write; let log_dir = PathBuf::from_str("./").expect("wtf, The current directory no longer exists?"); if !log_dir.exists() { diff --git a/engine/src/core/render/ctx.rs b/engine/src/core/render/ctx.rs index 2190e21..596f49b 100644 --- a/engine/src/core/render/ctx.rs +++ b/engine/src/core/render/ctx.rs @@ -13,8 +13,9 @@ use wgpu_text::glyph_brush::ab_glyph::FontRef; use wgpu_text::glyph_brush::{HorizontalAlign, Layout, OwnedSection, OwnedText, VerticalAlign}; use wgpu_text::{BrushBuilder, TextBrush}; use winit::window::Window; -use crate::error::{ZenyxError, ZenyxErrorKind}; + use crate::error::Result; +use crate::error::{ZenyxError, ZenyxErrorKind}; const SHADER_SRC: &str = include_str!("shader.wgsl"); @@ -130,7 +131,7 @@ struct Model { bind_group: wgpu::BindGroup, index_count: u32, transform: Matrix4, - version: u32, + version: u32, } impl Model { @@ -174,7 +175,7 @@ impl Model { bind_group, index_count: indices.len() as u32, transform: Matrix4::identity(), - version: 1 + version: 1, } } @@ -190,7 +191,6 @@ impl Model { self.version += 1; } } - } pub struct Renderer<'window> { @@ -211,7 +211,7 @@ pub struct Renderer<'window> { frame_count: u32, fps: f32, font_state: FontState, - model_versions: Vec, + model_versions: Vec, } struct FontState { @@ -370,6 +370,8 @@ impl<'window> Renderer<'window> { surface.configure(&device, &surface_config); let (depth_texture, depth_texture_view) = create_depth_texture(&device, surface_config.width, surface_config.height); + let (depth_texture, depth_texture_view) = + create_depth_texture(&device, surface_config.width, surface_config.height); let font_bytes = include_bytes!("DejaVuSans.ttf"); let font = FontRef::try_from_slice(font_bytes).map_err(|e| { @@ -385,8 +387,6 @@ impl<'window> Renderer<'window> { let scale = base_scale * (surface_config.width as f32 / base_width as f32).clamp(0.5, 2.0); let color = wgpu::Color::WHITE; - - let section = OwnedSection::default() .add_text(OwnedText::new("FPS: 0.00").with_scale(scale).with_color([ color.r as f32, @@ -430,7 +430,7 @@ impl<'window> Renderer<'window> { scale, color, }, - model_versions: vec![] + model_versions: vec![], }) } @@ -475,16 +475,16 @@ impl<'window> Renderer<'window> { for (i, model) in self.models.iter_mut().enumerate() { let angle = Rad(elapsed * 0.8 + i as f32 * 0.3); if i % 2 == 0 { - model.set_transform(Matrix4::from_angle_y(angle)); + model.set_transform(Matrix4::from_angle_y(angle)); } else { - model.set_transform(Matrix4::from_angle_x(angle) * Matrix4::from_angle_y(angle)); + model.set_transform(Matrix4::from_angle_x(angle) * Matrix4::from_angle_y(angle)); } } for (i, model) in self.models.iter().enumerate() { if model.version > self.model_versions[i] { model.update(&self.queue); #[cfg(debug_assertions)] - trace!("Updating model: {:#?}",model); + trace!("Updating model: {:#?}", model); self.model_versions[i] = model.version; } } @@ -604,9 +604,11 @@ impl<'window> Renderer<'window> { pub fn bg_color(&self) -> &wgpu::Color { &self.bg_color } + pub fn text_color(&self) -> &wgpu::Color { &self.font_state.color } + pub fn set_text_color(&mut self, color: wgpu::Color) { self.font_state.color = color; } diff --git a/engine/src/core/render/mod.rs b/engine/src/core/render/mod.rs index 30fd623..ba01a84 100644 --- a/engine/src/core/render/mod.rs +++ b/engine/src/core/render/mod.rs @@ -1,21 +1,26 @@ +use std::env; +use std::fs; +use std::io::Cursor; use std::ops::Deref; +use std::path::PathBuf; use std::sync::Arc; use ctx::{Renderer, Vertex}; -use winit::dpi::LogicalSize; -use winit::dpi::Size; -use std::env; -use std::fs; -use std::path::PathBuf; +use image::ImageDecoder; +use image::ImageFormat; use tobj::Mesh; use tobj::{LoadOptions, Model}; use tracing::{debug, error, info, trace, warn}; use wgpu::rwh::HasWindowHandle; use winit::application::ApplicationHandler; +use winit::dpi::LogicalSize; +use winit::dpi::Size; use winit::event::{KeyEvent, WindowEvent}; use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop}; use winit::monitor::MonitorHandle; +use winit::platform::windows::WindowAttributesExtWindows; use winit::window::Fullscreen; +use winit::window::Icon; use winit::window::Window; use winit::window::WindowId; @@ -90,7 +95,14 @@ f 6/11/6 5/10/6 1/1/6 2/13/6 impl App<'_> { fn create_main_window(&mut self, event_loop: &ActiveEventLoop) { - let win_attr = Window::default_attributes().with_title("Zenyx").with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0))); + let icon = self.load_icon_from_bytes(Self::ICON).unwrap(); + + let win_attr = Window::default_attributes() + .with_title("Zenyx") + .with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0))) + .with_window_icon(icon.clone()) + .with_taskbar_icon(icon); + match event_loop.create_window(win_attr) { Ok(window) => { let window = Arc::new(window); @@ -167,7 +179,7 @@ impl App<'_> { ) { if !key_event.state.is_pressed() || key_event.repeat { return; - } + } match key_event.physical_key { winit::keyboard::PhysicalKey::Code(code) => match code { winit::keyboard::KeyCode::Space => { @@ -206,6 +218,7 @@ impl App<'_> { warn!("No window context for toggling background: {:?}", window_id); } } + fn toggle_fullscreen(&mut self, window_id: WindowId) { if let Some(ctx) = self.windows.get_mut(&window_id) { let is_fullscreen = ctx.window.fullscreen().is_some(); @@ -223,13 +236,43 @@ impl App<'_> { warn!("No window found for fullscreen toggle: {:?}", window_id); } } + fn load_icon_from_bytes(&self, bytes: &[u8]) -> Result, String> { + const IMAGE_DIR: &str = env!("CARGO_MANIFEST_DIR"); + let cursor = Cursor::new(bytes); + let format = image::guess_format(bytes).map_err(|_| "Failed to guess image format")?; + let decoder = match format { + ImageFormat::Png => image::codecs::png::PngDecoder::new(cursor).map_err(|e| format!("Failed to decode PNG: {}", e))?, + _ => { + let img = image::load_from_memory(bytes).map_err(|e| format!("Failed to load image: {}", e))?.into_rgba8(); + let (width, height) = img.dimensions(); + return Icon::from_rgba(img.into_raw(), width, height) + .map(Some) + .map_err(|e| format!("Failed to create icon from bytes: {}", e)); + } + }; + let (width, height) = decoder.dimensions(); + let mut image_data = vec![0; decoder.total_bytes() as usize]; + decoder.read_image(&mut image_data).map_err(|e| format!("Failed to read image data: {}", e))?; + + Icon::from_rgba(image_data, width, height) + .map(Some) + .map_err(|e| format!("Failed to create icon from bytes: {}", e)) + } + + const ICON: &'static [u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../assets/Badge.png")); fn spawn_child_window(&mut self, event_loop: &ActiveEventLoop) { if let Some(main_ctx) = self.windows.values().find(|ctx| ctx.is_main_window()) { let title = format!("Zenyx - New Window {}", self.windows.len()); - // TODO: Verify that this is safe instead of matching on it + let icon = self.load_icon_from_bytes(Self::ICON).unwrap(); + let win_attr = unsafe { - let base = Window::default_attributes().with_title(title).with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0))); + let base = Window::default_attributes() + .with_title(title) + .with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0))) + .with_window_icon(icon.clone()) + .with_taskbar_icon(icon); + match main_ctx.window_handle() { Ok(handle) => { if !cfg!(target_os = "windows") { @@ -237,11 +280,11 @@ impl App<'_> { } else { base } - }, + } Err(e) => { error!("{e}"); base - }, + } } }; match event_loop.create_window(win_attr) { diff --git a/engine/src/core/repl/commands.rs b/engine/src/core/repl/commands.rs index d34227e..9e9a3ec 100644 --- a/engine/src/core/repl/commands.rs +++ b/engine/src/core/repl/commands.rs @@ -5,7 +5,7 @@ use regex::Regex; use super::{handler::Command, input::tokenize}; use crate::core::repl::handler::COMMAND_MANAGER; -use crate::error::{ZenyxError,ZenyxErrorKind}; +use crate::error::{ZenyxError, ZenyxErrorKind}; #[derive(Default)] pub struct HelpCommand; diff --git a/engine/src/core/repl/handler.rs b/engine/src/core/repl/handler.rs index e9b70b0..45784ff 100644 --- a/engine/src/core/repl/handler.rs +++ b/engine/src/core/repl/handler.rs @@ -1,11 +1,13 @@ use std::collections::HashMap; +use std::sync::LazyLock; use colored::Colorize; use parking_lot::RwLock; -use std::sync::LazyLock; + use crate::error::{ZenyxError, ZenyxErrorKind}; -pub static COMMAND_MANAGER: LazyLock> = LazyLock::new(|| { RwLock::new(CommandManager::init()) }); +pub static COMMAND_MANAGER: LazyLock> = + LazyLock::new(|| RwLock::new(CommandManager::init())); #[macro_export] macro_rules! commands { diff --git a/engine/src/core/repl/mod.rs b/engine/src/core/repl/mod.rs index 21e1524..c850436 100644 --- a/engine/src/core/repl/mod.rs +++ b/engine/src/core/repl/mod.rs @@ -6,9 +6,6 @@ pub mod commands; pub mod handler; pub mod input; - - - pub fn setup() { commands!( HelpCommand, diff --git a/engine/src/error.rs b/engine/src/error.rs index b39bb3e..3595964 100644 --- a/engine/src/error.rs +++ b/engine/src/error.rs @@ -1,9 +1,9 @@ -use colored::Colorize; -use thiserror::Error; use std::fmt::Write; +use colored::Colorize; +use thiserror::Error; -#[derive(Debug, Error,PartialEq)] +#[derive(Debug, Error, PartialEq)] pub enum ZenyxErrorKind { #[error("Surface creation failed")] SurfaceCreation, @@ -48,6 +48,7 @@ impl ZenyxError { source: None, } } + pub fn kind(&self) -> &ZenyxErrorKind { &self.kind } @@ -87,45 +88,21 @@ impl ZenyxError { if let Some(msg) = &self.message { let line_padding = " ".repeat(padding_spaces); - writeln!( - output, - "{}>> {}\x1b[0m", - line_padding, - msg.bright_white() - ) - .unwrap(); + writeln!(output, "{}>> {}\x1b[0m", line_padding, msg.bright_white()).unwrap(); } if let Some(ctx) = &self.context { let line_padding = " ".repeat(padding_spaces); writeln!(output, "{}│\x1b[0m", line_padding.bright_white().bold()).unwrap(); - writeln!( - output, - "{}╰─ Note: {}\x1b[0m", - line_padding, - ctx - ) - .unwrap(); + writeln!(output, "{}╰─ Note: {}\x1b[0m", line_padding, ctx).unwrap(); } if let Some(source) = &self.source { let line_padding = " ".repeat(padding_spaces); - writeln!( - output, - "{}╰─ Caused by: {}\x1b[0m", - line_padding, - source - ) - .unwrap(); + writeln!(output, "{}╰─ Caused by: {}\x1b[0m", line_padding, source).unwrap(); let mut current = source.source(); let mut depth = 1; while let Some(err) = current { let indent = " ".repeat(padding_spaces * depth); - writeln!( - output, - "{}↳ {}\x1b[0m", - indent, - err - ) - .unwrap(); + writeln!(output, "{}↳ {}\x1b[0m", indent, err).unwrap(); depth += 1; current = err.source(); } @@ -136,22 +113,31 @@ impl ZenyxError { impl std::fmt::Display for ZenyxError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Error: {}{}{}{}", + write!( + f, + "Error: {}{}{}{}", self.kind, - self.message.as_ref().map_or("".to_string(), |msg| format!(" - {}", msg)), - self.context.as_ref().map_or("".to_string(), |ctx| format!(" [{}]", ctx)), - self.source.as_ref().map_or("".to_string(), |src| format!(" - caused by: {}", src)) + self.message + .as_ref() + .map_or("".to_string(), |msg| format!(" - {}", msg)), + self.context + .as_ref() + .map_or("".to_string(), |ctx| format!(" [{}]", ctx)), + self.source + .as_ref() + .map_or("".to_string(), |src| format!(" - caused by: {}", src)) ) } } impl std::error::Error for ZenyxError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - self.source.as_ref().map(|s| s.as_ref() as &(dyn std::error::Error + 'static)) + self.source + .as_ref() + .map(|s| s.as_ref() as &(dyn std::error::Error + 'static)) } } - impl From for ZenyxError { fn from(err: std::io::Error) -> Self { Self::builder(ZenyxErrorKind::Io) @@ -230,7 +216,6 @@ mod tests { assert!(error.source.is_some()); } - #[test] fn test_from_rustyline_error() { let readline_error = rustyline::error::ReadlineError::Interrupted; @@ -256,7 +241,6 @@ mod tests { error.pretty_print(); } - #[test] fn test_error_source_chain() { let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "File not found"); diff --git a/engine/src/main.rs b/engine/src/main.rs index 070d3f6..c654a72 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -1,5 +1,5 @@ use core::{panic::set_panic_hook, repl::setup, splash}; -use thiserror::Error; + use colored::Colorize; use tokio::runtime; #[allow(unused_imports)] @@ -29,31 +29,26 @@ async fn main() { init_logger(); let sysinfo = crate::metadata::SystemMetadata::current(); - set_panic_hook(); setup(); - - splash::print_splash(); if !cfg!(debug_assertions) { info!("{}", "Debug mode disabled".bright_blue()); set_panic_hook(); } else { - println!("{}",sysinfo.verbose_summary()); + println!("{}", sysinfo.verbose_summary()); } - + info!("Type 'help' for a list of commands."); let repl_thread = std::thread::spawn(|| { - let rt = match runtime::Builder::new_current_thread() - .enable_all() - .build() { - Ok(rt) => rt, - Err(e) => { - error!("A fatal error has occured: {e}"); - std::process::exit(1) - }, - }; + let rt = match runtime::Builder::new_current_thread().enable_all().build() { + Ok(rt) => rt, + Err(e) => { + error!("A fatal error has occured: {e}"); + std::process::exit(1) + } + }; rt.block_on(core::repl::input::handle_repl()) }); splash::print_splash(); @@ -71,5 +66,4 @@ async fn main() { if let Err(_) = repl_thread.join() { error!("REPL thread panicked"); } - } diff --git a/engine/src/metadata.rs b/engine/src/metadata.rs index dadbd01..1530d1d 100644 --- a/engine/src/metadata.rs +++ b/engine/src/metadata.rs @@ -1,9 +1,10 @@ +use std::collections::HashSet; use std::fmt; use std::str::FromStr; -use sysinfo::{CpuRefreshKind, RefreshKind, System}; + use raw_cpuid::CpuId; +use sysinfo::{CpuRefreshKind, RefreshKind, System}; use wgpu::DeviceType; -use std::collections::HashSet; mod build_info { include!(concat!(env!("OUT_DIR"), "/built.rs")); @@ -24,11 +25,15 @@ impl Memory { } pub const fn from_mb(mb: u64) -> Self { - Self { bytes: mb * 1024 * 1024 } + Self { + bytes: mb * 1024 * 1024, + } } pub const fn from_gb(gb: u64) -> Self { - Self { bytes: gb * 1024 * 1024 * 1024 } + Self { + bytes: gb * 1024 * 1024 * 1024, + } } pub const fn as_bytes(&self) -> u64 { @@ -185,18 +190,24 @@ pub struct CPU { impl CPU { pub fn current() -> Self { - let mut sys = System::new_with_specifics(RefreshKind::default().with_cpu(CpuRefreshKind::everything())); + let mut sys = System::new_with_specifics( + RefreshKind::default().with_cpu(CpuRefreshKind::everything()), + ); sys.refresh_cpu_all(); let cpu_opt = sys.cpus().first(); - let brand = cpu_opt.map(|cpu| cpu.brand().into()) + let brand = cpu_opt + .map(|cpu| cpu.brand().into()) .unwrap_or(CPUBrand::Other("unknown".into())); - let name = cpu_opt.map(|cpu| cpu.name().to_string()) + let name = cpu_opt + .map(|cpu| cpu.name().to_string()) .unwrap_or_else(|| "unknown".into()); - let vendor_id = cpu_opt.map(|cpu| cpu.vendor_id().to_string()) + let vendor_id = cpu_opt + .map(|cpu| cpu.vendor_id().to_string()) .unwrap_or_else(|| "unknown".into()); - let max_clock_speed = cpu_opt.map(|cpu| ClockSpeed(cpu.frequency() as u32)) + let max_clock_speed = cpu_opt + .map(|cpu| ClockSpeed(cpu.frequency() as u32)) .unwrap_or(ClockSpeed(0)); let current_clock_speed = max_clock_speed; @@ -214,20 +225,26 @@ impl CPU { let size = cache.physical_line_partitions() * cache.coherency_line_size() * cache.associativity(); - if size > 0 { l1_cache = Some(Memory::from_bytes(size.try_into().unwrap())); } - }, + if size > 0 { + l1_cache = Some(Memory::from_bytes(size.try_into().unwrap())); + } + } 2 => { let size = cache.physical_line_partitions() * cache.coherency_line_size() * cache.associativity(); - if size > 0 { l2_cache = Some(Memory::from_bytes(size.try_into().unwrap())); } - }, + if size > 0 { + l2_cache = Some(Memory::from_bytes(size.try_into().unwrap())); + } + } 3 => { let size = (cache.physical_line_partitions() as u64) * (cache.coherency_line_size() as u64) * (cache.associativity() as u64); - if size > 0 { l3_cache = Some(Memory::from_bytes(size)); } - }, + if size > 0 { + l3_cache = Some(Memory::from_bytes(size)); + } + } _ => {} } } @@ -235,7 +252,9 @@ impl CPU { Self { brand, - arch: std::env::consts::ARCH.parse().unwrap_or(CPUArch::Other("unknown".into())), + arch: std::env::consts::ARCH + .parse() + .unwrap_or(CPUArch::Other("unknown".into())), name, vendor_id, physical_cores, @@ -257,7 +276,7 @@ impl CPU { } pub fn is_arm(&self) -> bool { - matches!(self.brand,CPUBrand::Intel) + matches!(self.brand, CPUBrand::Intel) } pub fn is_high_clock(&self) -> bool { @@ -278,13 +297,23 @@ impl CPU { self.arch, self.name, self.vendor_id, - self.physical_cores.map(|c| c.to_string()).unwrap_or_else(|| "unknown".into()), - self.logical_cores.map(|c| c.to_string()).unwrap_or_else(|| "unknown".into()), + self.physical_cores + .map(|c| c.to_string()) + .unwrap_or_else(|| "unknown".into()), + self.logical_cores + .map(|c| c.to_string()) + .unwrap_or_else(|| "unknown".into()), self.max_clock_speed, self.current_clock_speed, - self.l1_cache.map(|c| c.format_human()).unwrap_or_else(|| "unknown".into()), - self.l2_cache.map(|c| c.format_human()).unwrap_or_else(|| "unknown".into()), - self.l3_cache.map(|c| c.format_human()).unwrap_or_else(|| "unknown".into()), + self.l1_cache + .map(|c| c.format_human()) + .unwrap_or_else(|| "unknown".into()), + self.l2_cache + .map(|c| c.format_human()) + .unwrap_or_else(|| "unknown".into()), + self.l3_cache + .map(|c| c.format_human()) + .unwrap_or_else(|| "unknown".into()), ) } } @@ -332,7 +361,6 @@ pub struct GPU { pub driver_version: Option, } - impl GPU { pub fn current() -> Vec { let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { @@ -363,6 +391,7 @@ impl GPU { pub fn is_dedicated(&self) -> bool { !self.is_integrated() } + pub fn is_mobile(&self) -> bool { let lower_name = self.name.to_lowercase(); lower_name.contains("adreno") @@ -490,6 +519,7 @@ impl SystemMetadata { compile_info: CompileInfo::current(), } } + pub fn main_gpu(&self) -> Option<&GPU> { self.gpus .iter() @@ -498,7 +528,6 @@ impl SystemMetadata { .or_else(|| self.gpus.first()) } - pub fn verbose_summary(&self) -> String { let main_gpu = self.main_gpu(); let main_gpu_info = main_gpu @@ -556,4 +585,4 @@ mod tests { assert!(metadata.memory.total.as_bytes() > 0); assert!(!metadata.compile_info.pkg_version.is_empty()); } -} \ No newline at end of file +}