From 51556284bb92d97d0cbc51b076224572093a9b6e Mon Sep 17 00:00:00 2001 From: deepCurse Date: Mon, 20 Jan 2025 06:19:34 -0400 Subject: [PATCH] project setup --- .gitignore | 7 + Cargo.lock | 2665 ++++++++++++++++++++++++++ Cargo.toml | 92 + build.rs | 139 ++ rustfmt.toml | 33 + shaders/f_default.glsl | 10 + shaders/v_default.glsl | 20 + src/linux.rs | 940 +++++++++ src/main.rs | 46 + src/vita/debug_screen/font.bin | Bin 0 -> 2048 bytes src/vita/debug_screen/font.rs | 19 + src/vita/debug_screen/fonts.rs | 11 + src/vita/debug_screen/framebuffer.rs | 191 ++ src/vita/debug_screen/mod.rs | 2 + src/vita/gui/font.bin | Bin 0 -> 2048 bytes src/vita/gui/framebuffer.rs | 95 + src/vita/gui/mod.rs | 492 +++++ src/vita/mod.rs | 211 ++ src/windows.rs | 1 + thanks.txt | 10 + 20 files changed, 4984 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 build.rs create mode 100644 rustfmt.toml create mode 100644 shaders/f_default.glsl create mode 100644 shaders/v_default.glsl create mode 100644 src/linux.rs create mode 100644 src/main.rs create mode 100644 src/vita/debug_screen/font.bin create mode 100644 src/vita/debug_screen/font.rs create mode 100644 src/vita/debug_screen/fonts.rs create mode 100644 src/vita/debug_screen/framebuffer.rs create mode 100644 src/vita/debug_screen/mod.rs create mode 100644 src/vita/gui/font.bin create mode 100644 src/vita/gui/framebuffer.rs create mode 100644 src/vita/gui/mod.rs create mode 100644 src/vita/mod.rs create mode 100644 src/windows.rs create mode 100644 thanks.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..15f02fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ + +**/*.rs.bk + +/debug/ +/target/ +/.vscode/ +/.idea/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..baee0ba --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2665 @@ +# 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 = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[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 = "android-activity" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" +dependencies = [ + "android-properties", + "bitflags 2.8.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "approx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +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 = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +dependencies = [ + "serde", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys", + "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.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" + +[[package]] +name = "calloop" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" +dependencies = [ + "bitflags 2.8.0", + "log", + "polling", + "rustix", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cc" +version = "1.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +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 = "cgmath" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" +dependencies = [ + "approx", + "num-traits", +] + +[[package]] +name = "cmake" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +dependencies = [ + "cc", +] + +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + +[[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 = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concat-idents" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d" +dependencies = [ + "quote", + "syn", +] + +[[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 = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + +[[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 = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "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.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + +[[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", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[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 = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[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.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.8.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.8.0", +] + +[[package]] +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +dependencies = [ + "log", + "presser", + "thiserror 1.0.69", + "windows", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf29e94d6d243368b7a56caa16bc213e4f9f8ed38c4d9557069527b5d5281ca" +dependencies = [ + "bitflags 2.8.0", + "gpu-descriptor-types", + "hashbrown", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.8.0", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[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 = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2", + "dispatch", + "objc2", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[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 1.0.69", + "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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "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 = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +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.8.0", + "libc", + "redox_syscall 0.5.8", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[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.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.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.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +dependencies = [ + "bitflags 2.8.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "metal" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" +dependencies = [ + "bitflags 2.8.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "minemod" +version = "0.1.0" +dependencies = [ + "anyhow", + "cgmath", + "concat-idents", + "ctrlc", + "jobserver", + "libc", + "log", + "num_cpus", + "png", + "rand", + "shaderc", + "thiserror 2.0.11", + "tobj", + "tokio", + "tracing", + "tracing-subscriber", + "vitasdk-sys", + "vulkanalia", + "wgpu", + "winit", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "naga" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.8.0", + "cfg_aliases 0.2.1", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "rustc-hash", + "spirv", + "strum", + "termcolor", + "thiserror 2.0.11", + "unicode-xid", +] + +[[package]] +name = "ndk" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +dependencies = [ + "bitflags 2.8.0", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.8.0", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[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_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[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", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[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 = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[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.8", + "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-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[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.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +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.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "range-alloc" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags 2.8.0", +] + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "roxmltree" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[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.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +dependencies = [ + "bitflags 2.8.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + +[[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.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70b31447ca297092c5a9916fc3b955203157b37c19ca8edde4f52e9843e602c7" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shaderc" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27e07913ada18607bb60d12431cbe3358d3bbebbe95948e1618851dc01e63b7b" +dependencies = [ + "libc", + "shaderc-sys", +] + +[[package]] +name = "shaderc-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73120d240fe22196300f39ca8547ca2d014960f27b19b47b21288b396272f7f7" +dependencies = [ + "cmake", + "libc", + "roxmltree", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[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.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" +dependencies = [ + "bitflags 2.8.0", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix", + "thiserror 1.0.69", + "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 = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[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.8.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 = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +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.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[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 = "tobj" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3bd4ba05f29e4c65b6c0c11a58b6465ffa820bac890d76ad407b4e81d8372e8" +dependencies = [ + "ahash", + "log", +] + +[[package]] +name = "tokio" +version = "1.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[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 = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vitasdk-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "665d8a491ad572e0ebc103846c4a51e66b641c942391b7241f91c413a3a301a9" + +[[package]] +name = "vulkanalia" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb009d13f63b0cbabcf51fbfb62dfe8327d15a1cfdc689ee579989d20fb4ed76" +dependencies = [ + "cocoa", + "libloading", + "metal 0.27.0", + "objc", + "raw-window-handle", + "vulkanalia-sys", +] + +[[package]] +name = "vulkanalia-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea51b4a530bcb577a16002ea270b180b5f19b8adcefd6ccf79b53041204606bf" +dependencies = [ + "bitflags 1.3.2", +] + +[[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.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[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.8.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.8.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.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +dependencies = [ + "bitflags 2.8.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +dependencies = [ + "bitflags 2.8.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.8.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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wgpu" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e41253fc7b660735e2a2d9a58c563f2a047d3cc3445293d8f4095538c9e8afbe" +dependencies = [ + "arrayvec", + "bitflags 2.8.0", + "cfg_aliases 0.2.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 = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82a39b8842dc9ffcbe34346e3ab6d496b32a47f6497e119d762c97fcaae3cb37" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.8.0", + "cfg_aliases 0.2.1", + "document-features", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash", + "smallvec", + "thiserror 2.0.11", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a782e5056b060b0b4010881d1decddd059e44f2ecd01e2db2971b48ad3627e5" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.8.0", + "block", + "bytemuck", + "cfg_aliases 0.2.1", + "core-graphics-types", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal 0.31.0", + "naga", + "ndk-sys", + "objc", + "once_cell", + "ordered-float", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash", + "smallvec", + "thiserror 2.0.11", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "windows", + "windows-core", +] + +[[package]] +name = "wgpu-types" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" +dependencies = [ + "bitflags 2.8.0", + "js-sys", + "log", + "web-sys", +] + +[[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.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "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.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[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.29.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.8.0", + "bytemuck", + "calloop", + "cfg_aliases 0.1.1", + "core-foundation", + "core-graphics", + "cursor-icon", + "icrate", + "js-sys", + "libc", + "log", + "memmap2", + "ndk", + "ndk-sys", + "objc2", + "once_cell", + "orbclient", + "percent-encoding", + "raw-window-handle", + "redox_syscall 0.3.5", + "rustix", + "sctk-adwaita", + "smithay-client-toolkit", + "smol_str", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.48.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + +[[package]] +name = "winnow" +version = "0.6.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" +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.8.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.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" + +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "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", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0c4f69e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,92 @@ +[package] +name = "minemod" +version = "0.1.0" +edition = "2024" + +[package.metadata.vita] +title_id = "PKDC10002" +title_name = "MineMod" +# assets = "somewhere" # TODO make this a build.rs output folder so we can use build.rs to manage vita assets + +[profile.release] +opt-level = 2 +lto = true +codegen-units = 1 +panic = "abort" +strip = "debuginfo" + +[profile.release.package."*"] +opt-level = 3 +codegen-units = 1 +strip = "debuginfo" + +[profile.dev.package."*"] +opt-level = 3 + +[profile.wasm-release] +inherits = "release" +opt-level = "z" +strip = true + +[workspace] +members = [] + +# [patch."ssh://user@domain.com/repository.git"] +# namespace = { path = "path/to/thing" } + +[build-dependencies] +shaderc = "0.8.3" +num_cpus = "1.16.0" +jobserver = "0.1.32" + +[dependencies] +tracing = { version = "0.1.41", features = [ + "max_level_debug", + "release_max_level_warn", +] } +tracing-subscriber = "0.3.19" +log = "0.4.25" + +anyhow = "1.0.95" +thiserror = "2.0.11" + +cgmath = "0.18.0" +png = "0.17.16" +tobj = { version = "4.0.2", features = ["log"] } + +[target.'cfg(any(target_os = "windows",target_os = "linux",target_os = "macos"))'.dependencies] +vulkanalia = { version = "0.26.0", features = [ + "libloading", + "provisional", + "window", +] } +winit = "0.29" # dont update, many many breaking changes with no guides +ctrlc = "3.4.5" +tokio = { version = "1.43.0", features = ["full"] } + +[target.'cfg(target_family = "wasm")'.dependencies] +wgpu = "24.0.0" + +[target.'cfg(target_os = "vita")'.dependencies] +vitasdk-sys = { version = "0.3.3", features = ["all-stubs"] } +concat-idents = "1.1.5" +libc = "0.2.153" +rand = "0.8.5" +tokio = { version = "1.36.0", features = [ + "fs", + "macros", + "bytes", + "io-std", + "io-util", + "rt", + "rt-multi-thread", + "net", + "tracing", + "time", +] } + +[target.'cfg(target_os = "windows")'.dependencies] + +[target.'cfg(target_os = "linux")'.dependencies] + +[target.'cfg(target_os = "macos")'.dependencies] diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..5ba0e9e --- /dev/null +++ b/build.rs @@ -0,0 +1,139 @@ +// Requires crates: shaderc, num_cpus, jobserver + +// This file is licensed to anyone who obtains a copy by lever1209 under the CC BY 4.0 license available here: https://creativecommons.org/licenses/by/4.0/ + +const SHADER_SRC_ROOT:&'static str = "shaders/"; +const SUPPORTED_SHADER_FORMAT_EXTENSIONS_GLSL:[&'static str; 1] = ["glsl"]; +const SUPPORTED_SHADER_FORMAT_EXTENSIONS_HLSL:[&'static str; 2] = ["cg", "hlsl"]; +const COMPILED_SHADER_EXTENSION:&'static str = ".spv"; + +fn main() -> Result<(), Box> { + println!("cargo:rerun-if-changed=build.rs"); + + compile_shaders()?; + + Ok(()) +} + +fn compile_shaders() -> Result<(), Box> { + println!("cargo:rerun-if-changed={SHADER_SRC_ROOT}"); + + let client = unsafe { jobserver::Client::from_env() }.unwrap_or({ + println!("cargo:warning=Could not connect to the gnu jobserver. Assuming max supported threads."); + jobserver::Client::new(num_cpus::get())? + }); + + let out_dir = std::env::var("OUT_DIR").map_err(|err| format!("Could not read environment variable OUT_DIR: `{err}`"))?; + let shader_out_dir = std::path::Path::new(&out_dir).join(SHADER_SRC_ROOT); + std::fs::create_dir_all(&shader_out_dir)?; + + let mut running_tasks = vec![]; + + let mut shader_source_files = vec![]; + if let Err(err) = walk_dir(SHADER_SRC_ROOT.into(), &mut shader_source_files) { + println!("cargo:warning=There was an error walking the shader source directory: `{err}`"); + }; + + for input_path in shader_source_files { + let aquired = client + .acquire() + .map_err(|err| format!("There was an error while aquiring a jobserver token: `{err}`"))?; + + let shader_out_dir = shader_out_dir.clone(); + + running_tasks.push((input_path.clone(), std::thread::spawn(move || -> Result<(), Box> { + + let input_file_stem = match input_path.file_stem().and_then(|f| <&str>::try_from(f).ok()) { + Some(stem) => stem.to_owned(), + None => return Err(format!("Could not read file stem of file: {input_path:?}").into()), + }; + + let shader_kind = match &input_file_stem[0..=1] { + "f_" => shaderc::ShaderKind::Fragment, + "v_" => shaderc::ShaderKind::Vertex, + _ => return Err(format!("Shader folder contains a file that is neither a vertex or fragment shader: {input_path:?}").into()), + }; + + let new_file_name = input_file_stem + COMPILED_SHADER_EXTENSION; + let output_path = shader_out_dir.join(&new_file_name); + + if let Err(error) = compile_shader(&input_path, &output_path, shader_kind) { + println!("cargo:warning=Compilation process for input file: {input_path:?} was not successful: `{error}`"); + println!("cargo:warning=I cant be assed to fix this myself but cargo cuts off newlines in warning messages, so if the above error gets cut off youre going to need to find the text file or re run cargo with the -vv flag"); + } + + drop(aquired); + Ok(()) + }))); + } + + for (input_file, task) in running_tasks { + match task.join() { + Ok(Ok(())) => (), + Ok(Err(err)) => { + println!("cargo:warning=There was an error running a task: `{err}`"); + }, + Err(_) => { + println!("cargo:warning=A thread panicked while processing this file!: {input_file:?}",); + }, + } + } + Ok(()) +} + +fn walk_dir(path:std::path::PathBuf, file_paths_buf:&mut Vec) -> Result<(), Box> { + if std::path::PathBuf::from(&path).is_file() { + file_paths_buf.push(path); + return Ok(()); + } else { + let dir = std::fs::read_dir(path)?; + for f in dir { + walk_dir(f?.path(), file_paths_buf)?; + } + return Ok(()); + } +} + +fn compile_shader(input_path:&std::path::PathBuf, output_path:&std::path::PathBuf, shader_kind:shaderc::ShaderKind) -> Result<(), Box> { + let compiler = match shaderc::Compiler::new() { + Some(compiler) => compiler, + None => return Err(format!("Could not initialize shaderc compiler.").into()), + }; + + let target = if let Some(extension) = input_path.extension().and_then(|s| <&str>::try_from(s).ok()) { + if SUPPORTED_SHADER_FORMAT_EXTENSIONS_GLSL.contains(&extension) { + shaderc::SourceLanguage::GLSL + } else if SUPPORTED_SHADER_FORMAT_EXTENSIONS_HLSL.contains(&extension) { + shaderc::SourceLanguage::HLSL + } else { + return Err(format!("Could not determine compile target! This file has an invalid extension.").into()); + } + } else { + return Err(format!("Could not determine compile target! This file is missing an extension.").into()); + }; + + let options = match shaderc::CompileOptions::new() { + Some(mut options) => { + options.set_optimization_level(shaderc::OptimizationLevel::Performance); + options.set_source_language(target); + options + }, + None => return Err(format!("Could not initialize shaderc compiler options.").into()), + }; + + let source = std::fs::read_to_string(input_path)?; + let file_name = match input_path.file_name() { + Some(file_name) => file_name, + None => return Err("This is a directory!".into()), + }; + let file_name = match file_name.to_str() { + Some(file_name) => file_name, + None => return Err("Could not load this file name.".into()), + }; + + let binary_result = compiler.compile_into_spirv(&source, shader_kind, file_name, "main", Some(&options))?; + + std::fs::write(output_path, binary_result.as_binary_u8())?; + + Ok(()) +} diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..1abdef1 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,33 @@ +# i use tabs so stop bugging me and go elsewhere already + +hard_tabs=true +binop_separator="Back" +condense_wildcard_suffixes = true +empty_item_single_line = false +enum_discrim_align_threshold = 30 +struct_field_align_threshold = 30 +short_array_element_width_threshold = 30 +inline_attribute_width = 50 +fn_params_layout = "Compressed" +fn_single_line = true +format_code_in_doc_comments = true +format_macro_matchers = true +hex_literal_case = "Upper" +imports_indent = "Visual" +imports_layout = "Vertical" +# indent_style = "Visual" +match_arm_blocks = false +match_block_trailing_comma = true +max_width = 160 +imports_granularity = "Item" +newline_style = "Unix" +normalize_doc_attributes = true +overflow_delimited_expr = true +reorder_impl_items = true +# group_imports = "StdExternalCrate" +space_after_colon = false +# trailing_comma = "Always" +type_punctuation_density = "Compressed" +use_field_init_shorthand = true +use_try_shorthand = true +where_single_line = true diff --git a/shaders/f_default.glsl b/shaders/f_default.glsl new file mode 100644 index 0000000..c53f80f --- /dev/null +++ b/shaders/f_default.glsl @@ -0,0 +1,10 @@ + +#version 450 + +layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor, 1.0); +} diff --git a/shaders/v_default.glsl b/shaders/v_default.glsl new file mode 100644 index 0000000..66d6766 --- /dev/null +++ b/shaders/v_default.glsl @@ -0,0 +1,20 @@ +#version 450 + +layout(location = 0) out vec3 fragColor; + +vec2 positions[3] = vec2[]( + vec2(0.0, -0.5), + vec2(0.5, 0.5), + vec2(-0.5, 0.5) +); + +vec3 colors[3] = vec3[]( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) +); + +void main() { + gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); + fragColor = colors[gl_VertexIndex]; +} \ No newline at end of file diff --git a/src/linux.rs b/src/linux.rs new file mode 100644 index 0000000..d34f554 --- /dev/null +++ b/src/linux.rs @@ -0,0 +1,940 @@ +use anyhow::Result; +use anyhow::anyhow; + +use cgmath::vec2; +use cgmath::vec3; + +use log::*; + +use std::collections::HashSet; +use std::ffi::CStr; +use std::mem::size_of; +use std::os::raw::c_void; + +use thiserror::Error; + +use vulkanalia::Version; +use vulkanalia::bytecode::Bytecode; +use vulkanalia::loader::LIBRARY; +use vulkanalia::loader::LibloadingLoader; +use vulkanalia::prelude::v1_0::*; +use vulkanalia::window as vk_window; + +use vulkanalia::vk::ExtDebugUtilsExtension; +use vulkanalia::vk::KhrSurfaceExtension; +use vulkanalia::vk::KhrSwapchainExtension; + +use winit::dpi::LogicalSize; +use winit::event::Event; +use winit::event::WindowEvent; +use winit::event_loop::EventLoop; +use winit::window::Window; +use winit::window::WindowBuilder; + +type Vec2f = cgmath::Vector2; +type Vec3f = cgmath::Vector3; +type Vec4f = cgmath::Vector4; + +type Vec2d = cgmath::Vector2; +type Vec3d = cgmath::Vector3; +type Vec4d = cgmath::Vector4; + +type Mat2f = cgmath::Matrix2; +type Mat3f = cgmath::Matrix3; +type Mat4f = cgmath::Matrix4; + +type Mat2d = cgmath::Matrix2; +type Mat3d = cgmath::Matrix3; +type Mat4d = cgmath::Matrix4; + +const VALIDATION_ENABLED:bool = cfg!(debug_assertions); // add env support? +const VALIDATION_LAYER:vk::ExtensionName = vk::ExtensionName::from_bytes(b"VK_LAYER_KHRONOS_validation"); + +const DEVICE_EXTENSIONS:&[vk::ExtensionName] = &[vk::KHR_SWAPCHAIN_EXTENSION.name]; +const PORTABILITY_MACOS_VERSION:Version = Version::new(1, 3, 216); + +const WINDOW_TITLE:&'static str = "MineMod"; +const VK_APPLICATION_NAME:&'static [u8; 8] = b"minemod\0"; +const VK_ENGINE_NAME:&'static [u8; 10] = b"cataclysm\0"; +const MAX_FRAMES_IN_FLIGHT:usize = 2; + +macro_rules! const_shaders { + { $($vis:vis $identifier:ident = $string:literal; )* } => { + $( + #[allow(non_upper_case_globals)] + $vis static $identifier: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shaders/", $string)); + )* + }; +} + +pub fn main() -> Result<()> { + tracing_subscriber::fmt() + .compact() + .with_timer(tracing_subscriber::fmt::time::uptime()) + .with_ansi(true) + .with_level(true) + // .with_thread_ids(true) + .with_thread_names(true) + .with_max_level(if cfg!(debug_assertions) { + tracing::level_filters::LevelFilter::DEBUG + } else { + tracing::level_filters::LevelFilter::INFO + }) + .init(); + // pretty_env_logger::init_timed(); + + info!("Registering CTRLC hook."); + + let (shutdown_tx, shutdown_rx) = std::sync::mpsc::channel(); + + ctrlc::set_handler(move || { + shutdown_tx.send(()).expect("Failed to send shutdown signal"); + }) + .expect("Error setting Ctrl-C handler"); + + info!("Initializing event loop and winit window instance."); + + // Window + + let event_loop = EventLoop::new()?; + let window = WindowBuilder::new() + .with_title(WINDOW_TITLE) + .with_inner_size(LogicalSize::new(1024, 768)) + .build(&event_loop)?; + + info!("Creating app and starting event loop."); + + // App + + let mut app = unsafe { App::create(&window)? }; + let mut minimized = false; + + let shutdown_rx = std::sync::Arc::new(std::sync::Mutex::new(Some(shutdown_rx))); + + event_loop.run(move |event, elwt| { + let mut shutdown_rx_guard = shutdown_rx.lock().unwrap(); + + if let Some(receiver) = shutdown_rx_guard.as_mut() { + if receiver.try_recv().is_ok() { + info!("Closing event loop and destroying Vulkan instance."); + elwt.exit(); + unsafe { + app.device.device_wait_idle().unwrap(); + app.destroy(); + } + return; + } + } + + match event { + // Request a redraw when all events were processed. + Event::AboutToWait => window.request_redraw(), + Event::WindowEvent { event, .. } => match event { + // Render a frame if our Vulkan app is not being destroyed. + WindowEvent::RedrawRequested if !elwt.exiting() && !minimized => { + unsafe { app.render(&window) }.unwrap(); + }, + WindowEvent::Resized(size) => + if size.width == 0 || size.height == 0 { + minimized = true; + } else { + minimized = false; + app.resized = true; + }, + // Destroy our Vulkan app. + WindowEvent::CloseRequested => { + info!("Closing event loop and destroying Vulkan instance."); + elwt.exit(); + unsafe { + app.device.device_wait_idle().unwrap(); + app.destroy(); + } + }, + _ => {}, + }, + _ => {}, + } + })?; + + info!("Exiting program."); + + Ok(()) +} + +/// Our Vulkan app. +#[derive(Clone, Debug)] +struct App { + entry: Entry, + instance:Instance, + data: AppData, + device: Device, + frame: usize, // current frame + resized: bool, +} + +impl App { + /// Creates our Vulkan app. + unsafe fn create(window:&Window) -> Result { + let loader = LibloadingLoader::new(LIBRARY)?; + let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?; + let mut data = AppData::default(); + let instance = create_instance(window, &entry, &mut data)?; + data.surface = vk_window::create_surface(&instance, &window, &window)?; + pick_physical_device(&instance, &mut data)?; + let device = create_logical_device(&entry, &instance, &mut data)?; + create_swapchain(window, &instance, &device, &mut data)?; + create_swapchain_image_views(&device, &mut data)?; + create_render_pass(&instance, &device, &mut data)?; + create_pipeline(&device, &mut data)?; + create_framebuffers(&device, &mut data)?; + create_command_pool(&instance, &device, &mut data)?; + create_command_buffers(&device, &mut data)?; + create_sync_objects(&device, &mut data)?; + Ok(Self { + entry, + instance, + data, + device, + frame:0, + resized:false, + }) + } + + /// Renders a frame for our Vulkan app. + unsafe fn render(&mut self, window:&Window) -> Result<()> { + self.device.wait_for_fences(&[self.data.in_flight_fences[self.frame]], true, u64::MAX)?; + + let result = self.device.acquire_next_image_khr( + self.data.swapchain, + u64::MAX, + self.data.image_available_semaphores[self.frame], + vk::Fence::null(), + ); + + let image_index = match result { + Ok((image_index, _)) => image_index as usize, + Err(vk::ErrorCode::OUT_OF_DATE_KHR) => return self.recreate_swapchain(window), + Err(e) => return Err(anyhow!(e)), + }; + + if !self.data.images_in_flight[image_index as usize].is_null() { + self.device + .wait_for_fences(&[self.data.images_in_flight[image_index as usize]], true, u64::MAX)?; + } + + self.data.images_in_flight[image_index as usize] = self.data.in_flight_fences[self.frame]; + + let wait_semaphores = &[self.data.image_available_semaphores[self.frame]]; + let wait_stages = &[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]; + let command_buffers = &[self.data.command_buffers[image_index as usize]]; + let signal_semaphores = &[self.data.render_finished_semaphores[self.frame]]; + let submit_info = vk::SubmitInfo::builder() + .wait_semaphores(wait_semaphores) + .wait_dst_stage_mask(wait_stages) + .command_buffers(command_buffers) + .signal_semaphores(signal_semaphores); + + self.device.reset_fences(&[self.data.in_flight_fences[self.frame]])?; + + self.device + .queue_submit(self.data.graphics_queue, &[submit_info], self.data.in_flight_fences[self.frame])?; + + let swapchains = &[self.data.swapchain]; + let image_indices = &[image_index as u32]; + let present_info = vk::PresentInfoKHR::builder() + .wait_semaphores(signal_semaphores) + .swapchains(swapchains) + .image_indices(image_indices); + + let result = self.device.queue_present_khr(self.data.present_queue, &present_info); + + let changed = result == Ok(vk::SuccessCode::SUBOPTIMAL_KHR) || result == Err(vk::ErrorCode::OUT_OF_DATE_KHR); + + if self.resized || changed { + self.resized = false; + self.recreate_swapchain(window)?; + } else if let Err(e) = result { + return Err(anyhow!(e)); + } + + // self.device.queue_wait_idle(self.data.present_queue)?; + + self.frame = (self.frame + 1) % MAX_FRAMES_IN_FLIGHT; + + Ok(()) + } + + unsafe fn recreate_swapchain(&mut self, window:&Window) -> Result<()> { + self.device.device_wait_idle()?; + self.destroy_swapchain(); + create_swapchain(window, &self.instance, &self.device, &mut self.data)?; + create_swapchain_image_views(&self.device, &mut self.data)?; + create_render_pass(&self.instance, &self.device, &mut self.data)?; + create_pipeline(&self.device, &mut self.data)?; + create_framebuffers(&self.device, &mut self.data)?; + create_command_buffers(&self.device, &mut self.data)?; + self.data.images_in_flight.resize(self.data.swapchain_images.len(), vk::Fence::null()); + + Ok(()) + } + + unsafe fn destroy_swapchain(&mut self) { + self.data.framebuffers.iter().for_each(|f| self.device.destroy_framebuffer(*f, None)); + self.device.free_command_buffers(self.data.command_pool, &self.data.command_buffers); + self.device.destroy_pipeline(self.data.pipeline, None); + self.device.destroy_pipeline_layout(self.data.pipeline_layout, None); + self.device.destroy_render_pass(self.data.render_pass, None); + self.data.swapchain_image_views.iter().for_each(|v| self.device.destroy_image_view(*v, None)); + self.device.destroy_swapchain_khr(self.data.swapchain, None); + } + + /// Destroys our Vulkan app. + unsafe fn destroy(&mut self) { + self.destroy_swapchain(); + + self.data.in_flight_fences.iter().for_each(|f| self.device.destroy_fence(*f, None)); + self.data + .render_finished_semaphores + .iter() + .for_each(|s| self.device.destroy_semaphore(*s, None)); + self.data + .image_available_semaphores + .iter() + .for_each(|s| self.device.destroy_semaphore(*s, None)); + + self.device.destroy_command_pool(self.data.command_pool, None); + self.device.destroy_device(None); + self.instance.destroy_surface_khr(self.data.surface, None); + + if VALIDATION_ENABLED { + self.instance.destroy_debug_utils_messenger_ext(self.data.messenger, None); + } + + self.instance.destroy_instance(None); + } +} + +/// The Vulkan handles and associated properties used by our Vulkan app. +#[derive(Clone, Debug, Default)] +struct AppData { + messenger: vk::DebugUtilsMessengerEXT, + surface: vk::SurfaceKHR, + physical_device: vk::PhysicalDevice, + graphics_queue: vk::Queue, + present_queue: vk::Queue, + swapchain_format: vk::Format, + swapchain_extent: vk::Extent2D, + swapchain: vk::SwapchainKHR, + swapchain_images: Vec, + swapchain_image_views: Vec, + render_pass: vk::RenderPass, + pipeline_layout: vk::PipelineLayout, + pipeline: vk::Pipeline, + framebuffers: Vec, + command_pool: vk::CommandPool, + command_buffers: Vec, + image_available_semaphores:Vec, + render_finished_semaphores:Vec, + in_flight_fences: Vec, + images_in_flight: Vec, +} + +unsafe fn create_instance(window:&Window, entry:&Entry, data:&mut AppData) -> Result { + let application_info = vk::ApplicationInfo::builder() + .application_name(VK_APPLICATION_NAME) + .application_version(vk::make_version(0, 1, 0)) + .engine_name(VK_ENGINE_NAME) + .engine_version(vk::make_version(0, 1, 0)) + .api_version(vk::make_version(1, 0, 0)); + + let available_layers = entry + .enumerate_instance_layer_properties()? + .iter() + .map(|l| l.layer_name) + .collect::>(); + + if VALIDATION_ENABLED && !available_layers.contains(&VALIDATION_LAYER) { + return Err(anyhow!("Validation layer requested but not supported.")); + } + + let layers = if VALIDATION_ENABLED { vec![VALIDATION_LAYER.as_ptr()] } else { Vec::new() }; + + let mut extensions = vk_window::get_required_instance_extensions(window) + .iter() + .map(|e| e.as_ptr()) + .collect::>(); + + // needed for semaphores, unix only? + extensions.push(vk::KHR_GET_PHYSICAL_DEVICE_PROPERTIES2_EXTENSION.name.as_ptr()); + + // Required by Vulkan SDK on macOS since 1.3.216. + let flags = if cfg!(target_os = "macos") && entry.version()? >= PORTABILITY_MACOS_VERSION { + info!("Enabling extensions for macOS portability."); + // extensions.push( // already present above + // vk::KHR_GET_PHYSICAL_DEVICE_PROPERTIES2_EXTENSION + // .name + // .as_ptr(), + // ); + extensions.push(vk::KHR_PORTABILITY_ENUMERATION_EXTENSION.name.as_ptr()); + vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR + } else { + vk::InstanceCreateFlags::empty() + }; + if VALIDATION_ENABLED { + extensions.push(vk::EXT_DEBUG_UTILS_EXTENSION.name.as_ptr()); + } + + let mut info = vk::InstanceCreateInfo::builder() + .application_info(&application_info) + .enabled_layer_names(&layers) + .enabled_extension_names(&extensions) + .flags(flags); + + let mut debug_info = vk::DebugUtilsMessengerCreateInfoEXT::builder() + .message_severity(vk::DebugUtilsMessageSeverityFlagsEXT::all()) + .message_type( + vk::DebugUtilsMessageTypeFlagsEXT::GENERAL | vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION | vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE, + ) + .user_callback(Some(debug_callback)); + + if VALIDATION_ENABLED { + info = info.push_next(&mut debug_info); + } + + let instance = entry.create_instance(&info, None)?; + + if VALIDATION_ENABLED { + data.messenger = instance.create_debug_utils_messenger_ext(&debug_info, None)?; + } + + Ok(instance) +} + +extern "system" fn debug_callback( + severity:vk::DebugUtilsMessageSeverityFlagsEXT, type_:vk::DebugUtilsMessageTypeFlagsEXT, data:*const vk::DebugUtilsMessengerCallbackDataEXT, _:*mut c_void, +) -> vk::Bool32 { + let data = unsafe { *data }; + let message = unsafe { CStr::from_ptr(data.message) }.to_string_lossy(); + + if severity >= vk::DebugUtilsMessageSeverityFlagsEXT::ERROR { + error!("({:?}) {}", type_, message); + } else if severity >= vk::DebugUtilsMessageSeverityFlagsEXT::WARNING { + warn!("({:?}) {}", type_, message); + } else if severity >= vk::DebugUtilsMessageSeverityFlagsEXT::INFO { + debug!("({:?}) {}", type_, message); + } else { + trace!("({:?}) {}", type_, message); + } + + vk::FALSE +} + +#[derive(Debug, Error)] +#[error("{0}")] +pub struct SuitabilityError(pub &'static str); + +unsafe fn pick_physical_device(instance:&Instance, data:&mut AppData) -> Result<()> { + for physical_device in instance.enumerate_physical_devices()? { + let properties = instance.get_physical_device_properties(physical_device); + + if let Err(error) = check_physical_device(instance, data, physical_device) { + warn!("Skipping physical device (`{}`): {}", properties.device_name, error); + } else { + info!("Selected physical device (`{}`).", properties.device_name); + data.physical_device = physical_device; + return Ok(()); + } + } + + Err(anyhow!("Failed to find suitable physical device.")) +} +unsafe fn check_physical_device(instance:&Instance, data:&AppData, physical_device:vk::PhysicalDevice) -> Result<()> { + QueueFamilyIndices::get(instance, data, physical_device)?; + check_physical_device_extensions(instance, physical_device)?; + + let support = SwapchainSupport::get(instance, data, physical_device)?; + if support.formats.is_empty() || support.present_modes.is_empty() { + return Err(anyhow!(SuitabilityError("Insufficient swapchain support."))); + } + + // // TODO handle this like the other one? + // let properties = instance.get_physical_device_properties(physical_device); + // if properties.device_type != vk::PhysicalDeviceType::DISCRETE_GPU { + // return Err(anyhow!(SuitabilityError( + // "Only discrete GPUs are supported." + // ))); + // } + + // let features = instance.get_physical_device_features(physical_device); + // let required_features = [ + // (features.geometry_shader, "Missing geometry shader support."), + // // ( // needed for vr + // // features.multi_viewport, + // // "Missing support for multiple viewports.", + // // ), + // ]; + + // for (feature, string) in required_features { + // if feature != vk::TRUE { + // return Err(anyhow!(SuitabilityError(string))); + // } + // } + + Ok(()) +} +unsafe fn check_physical_device_extensions(instance:&Instance, physical_device:vk::PhysicalDevice) -> Result<()> { + let extensions = instance + .enumerate_device_extension_properties(physical_device, None)? + .iter() + .map(|e| e.extension_name) + .collect::>(); + if DEVICE_EXTENSIONS.iter().all(|e| extensions.contains(e)) { + Ok(()) + } else { + Err(anyhow!(SuitabilityError("Missing required device extensions."))) + } +} + +unsafe fn create_logical_device(entry:&Entry, instance:&Instance, data:&mut AppData) -> Result { + let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?; + + let mut unique_indices = HashSet::new(); + unique_indices.insert(indices.graphics); + unique_indices.insert(indices.present); + + let queue_priorities = &[1.0]; + let queue_infos = unique_indices + .iter() + .map(|i| vk::DeviceQueueCreateInfo::builder().queue_family_index(*i).queue_priorities(queue_priorities)) + .collect::>(); + + let layers = if VALIDATION_ENABLED { vec![VALIDATION_LAYER.as_ptr()] } else { vec![] }; + + let mut extensions = DEVICE_EXTENSIONS.iter().map(|n| n.as_ptr()).collect::>(); + + // Required by Vulkan SDK on macOS since 1.3.216. + if cfg!(target_os = "macos") && entry.version()? >= PORTABILITY_MACOS_VERSION { + extensions.push(vk::KHR_PORTABILITY_SUBSET_EXTENSION.name.as_ptr()); + } + + let features = vk::PhysicalDeviceFeatures::builder(); + + let info = vk::DeviceCreateInfo::builder() + .queue_create_infos(&queue_infos) + .enabled_layer_names(&layers) + .enabled_extension_names(&extensions) + .enabled_features(&features); + + let device = instance.create_device(data.physical_device, &info, None)?; + + data.graphics_queue = device.get_device_queue(indices.graphics, 0); + data.present_queue = device.get_device_queue(indices.present, 0); + + Ok(device) +} + +unsafe fn create_swapchain( + window:&Window, + instance:&Instance, + device:&Device, + data:&mut AppData, + // old_swapchain: Option +) -> Result<()> { + let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?; + let support = SwapchainSupport::get(instance, data, data.physical_device)?; + + let surface_format = get_swapchain_surface_format(&support.formats); + let present_mode = get_swapchain_present_mode(&support.present_modes); + let extent = get_swapchain_extent(window, support.capabilities); + + data.swapchain_format = surface_format.format; + data.swapchain_extent = extent; + + let mut image_count = support.capabilities.min_image_count + 1; + if support.capabilities.max_image_count != 0 && image_count > support.capabilities.max_image_count { + image_count = support.capabilities.max_image_count; + } + + let mut queue_family_indices = vec![]; + let image_sharing_mode = if indices.graphics != indices.present { + queue_family_indices.push(indices.graphics); + queue_family_indices.push(indices.present); + vk::SharingMode::CONCURRENT + } else { + vk::SharingMode::EXCLUSIVE + }; + + let info = vk::SwapchainCreateInfoKHR::builder() + .surface(data.surface) + .min_image_count(image_count) + .image_format(surface_format.format) + .image_color_space(surface_format.color_space) + .image_extent(extent) + .image_array_layers(1) + .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) + .image_sharing_mode(image_sharing_mode) + .queue_family_indices(&queue_family_indices) + .pre_transform(support.capabilities.current_transform) + .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) + .present_mode(present_mode) + .clipped(true) + .old_swapchain(vk::SwapchainKHR::null()); + // .old_swapchain(data.swapchain); // TODO if experiencing issues replace with vk::SwapchainKHR::null() + + data.swapchain = device.create_swapchain_khr(&info, None)?; + + data.swapchain_images = device.get_swapchain_images_khr(data.swapchain)?; + + Ok(()) +} + +fn get_swapchain_surface_format(formats:&[vk::SurfaceFormatKHR]) -> vk::SurfaceFormatKHR { + formats + .iter() + .cloned() + .find(|f| f.format == vk::Format::B8G8R8A8_SRGB && f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR) + .unwrap_or_else(|| formats[0]) +} + +fn get_swapchain_present_mode(present_modes:&[vk::PresentModeKHR]) -> vk::PresentModeKHR { + present_modes + .iter() + .cloned() + .find(|m| *m == vk::PresentModeKHR::MAILBOX) + .unwrap_or(vk::PresentModeKHR::FIFO) +} + +fn get_swapchain_extent(window:&Window, capabilities:vk::SurfaceCapabilitiesKHR) -> vk::Extent2D { + if capabilities.current_extent.width != u32::MAX { + capabilities.current_extent + } else { + vk::Extent2D::builder() + .width( + window + .inner_size() + .width + .clamp(capabilities.min_image_extent.width, capabilities.max_image_extent.width), + ) + .height( + window + .inner_size() + .height + .clamp(capabilities.min_image_extent.height, capabilities.max_image_extent.height), + ) + .build() + } +} + +unsafe fn create_swapchain_image_views(device:&Device, data:&mut AppData) -> Result<()> { + data.swapchain_image_views = data + .swapchain_images + .iter() + .map(|i| { + let components = vk::ComponentMapping::builder() + .r(vk::ComponentSwizzle::IDENTITY) + .g(vk::ComponentSwizzle::IDENTITY) + .b(vk::ComponentSwizzle::IDENTITY) + .a(vk::ComponentSwizzle::IDENTITY); + + let subresource_range = vk::ImageSubresourceRange::builder() + .aspect_mask(vk::ImageAspectFlags::COLOR) + .base_mip_level(0) + .level_count(1) + .base_array_layer(0) + .layer_count(1); + + let info = vk::ImageViewCreateInfo::builder() + .image(*i) + .view_type(vk::ImageViewType::_2D) + .format(data.swapchain_format) + .components(components) + .subresource_range(subresource_range); + + device.create_image_view(&info, None) + }) + .collect::, _>>()?; + + Ok(()) +} + +unsafe fn create_render_pass(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { + let color_attachment = vk::AttachmentDescription::builder() + .format(data.swapchain_format) + .samples(vk::SampleCountFlags::_1) + .load_op(vk::AttachmentLoadOp::CLEAR) + .store_op(vk::AttachmentStoreOp::STORE) + .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) + .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE) + .initial_layout(vk::ImageLayout::UNDEFINED) + .final_layout(vk::ImageLayout::PRESENT_SRC_KHR); + + let color_attachment_ref = vk::AttachmentReference::builder() + .attachment(0) + .layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL); + + let color_attachments = &[color_attachment_ref]; + let subpass = vk::SubpassDescription::builder() + .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS) + .color_attachments(color_attachments); + + let dependency = vk::SubpassDependency::builder() + .src_subpass(vk::SUBPASS_EXTERNAL) + .dst_subpass(0) + .src_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) + .src_access_mask(vk::AccessFlags::empty()) + .dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) + .dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE); + + let attachments = &[color_attachment]; + let subpasses = &[subpass]; + let dependencies = &[dependency]; + let info = vk::RenderPassCreateInfo::builder() + .attachments(attachments) + .subpasses(subpasses) + .dependencies(dependencies); + + data.render_pass = device.create_render_pass(&info, None)?; + + Ok(()) +} + +unsafe fn create_pipeline(device:&Device, data:&mut AppData) -> Result<()> { + const_shaders! { + frag = "f_default.spv"; + vert = "v_default.spv"; + } + + let vert_shader_module = create_shader_module(device, &vert[..])?; + let frag_shader_module = create_shader_module(device, &frag[..])?; + + let vert_stage = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::VERTEX) + .module(vert_shader_module) + .name(b"main\0"); // keep specialization_info in mind for pipeline creation optimizations that dont happen at render time + + let frag_stage = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::FRAGMENT) + .module(frag_shader_module) + .name(b"main\0"); + + let vertex_input_state = vk::PipelineVertexInputStateCreateInfo::builder(); + + let input_assembly_state = vk::PipelineInputAssemblyStateCreateInfo::builder() + .topology(vk::PrimitiveTopology::TRIANGLE_LIST) + .primitive_restart_enable(false); + + let viewport = vk::Viewport::builder() + .x(0.0) + .y(0.0) + .width(data.swapchain_extent.width as f32) + .height(data.swapchain_extent.height as f32) + .min_depth(0.0) + .max_depth(1.0); + + let scissor = vk::Rect2D::builder().offset(vk::Offset2D { x:0, y:0 }).extent(data.swapchain_extent); + + let viewports = &[viewport]; + let scissors = &[scissor]; + let viewport_state = vk::PipelineViewportStateCreateInfo::builder().viewports(viewports).scissors(scissors); + + let rasterization_state = vk::PipelineRasterizationStateCreateInfo::builder() + .depth_clamp_enable(false) + .rasterizer_discard_enable(false) + .polygon_mode(vk::PolygonMode::FILL) + .line_width(1.0) + .cull_mode(vk::CullModeFlags::BACK) + .front_face(vk::FrontFace::CLOCKWISE) + .depth_bias_enable(false); + + let multisample_state = vk::PipelineMultisampleStateCreateInfo::builder() + .sample_shading_enable(false) + .rasterization_samples(vk::SampleCountFlags::_1); + + let attachment = vk::PipelineColorBlendAttachmentState::builder() + .color_write_mask(vk::ColorComponentFlags::all()) + // .blend_enable(false); + .blend_enable(true) + .src_color_blend_factor(vk::BlendFactor::SRC_ALPHA) + .dst_color_blend_factor(vk::BlendFactor::ONE_MINUS_SRC_ALPHA) + .color_blend_op(vk::BlendOp::ADD) + .src_alpha_blend_factor(vk::BlendFactor::ONE) + .dst_alpha_blend_factor(vk::BlendFactor::ZERO) + .alpha_blend_op(vk::BlendOp::ADD); + + let attachments = &[attachment]; + let color_blend_state = vk::PipelineColorBlendStateCreateInfo::builder() + .logic_op_enable(false) + .logic_op(vk::LogicOp::COPY) + .attachments(attachments) + .blend_constants([0.0, 0.0, 0.0, 0.0]); + + let layout_info = vk::PipelineLayoutCreateInfo::builder(); + + data.pipeline_layout = device.create_pipeline_layout(&layout_info, None)?; + + let stages = &[vert_stage, frag_stage]; + let info = vk::GraphicsPipelineCreateInfo::builder() + .stages(stages) + .vertex_input_state(&vertex_input_state) + .input_assembly_state(&input_assembly_state) + .viewport_state(&viewport_state) + .rasterization_state(&rasterization_state) + .multisample_state(&multisample_state) + .color_blend_state(&color_blend_state) + .layout(data.pipeline_layout) + .render_pass(data.render_pass) + .subpass(0) + .base_pipeline_handle(vk::Pipeline::null()) // Optional. + .base_pipeline_index(-1); // Optional. + + data.pipeline = device.create_graphics_pipelines(vk::PipelineCache::null(), &[info], None)?.0[0]; + + device.destroy_shader_module(vert_shader_module, None); + device.destroy_shader_module(frag_shader_module, None); + Ok(()) +} + +unsafe fn create_shader_module(device:&Device, bytecode:&[u8]) -> Result { + let bytecode = Bytecode::new(bytecode).unwrap(); + + let info = vk::ShaderModuleCreateInfo::builder().code_size(bytecode.code_size()).code(bytecode.code()); + + Ok(device.create_shader_module(&info, None)?) +} + +unsafe fn create_framebuffers(device:&Device, data:&mut AppData) -> Result<()> { + data.framebuffers = data + .swapchain_image_views + .iter() + .map(|i| { + let attachments = &[*i]; + let create_info = vk::FramebufferCreateInfo::builder() + .render_pass(data.render_pass) + .attachments(attachments) + .width(data.swapchain_extent.width) + .height(data.swapchain_extent.height) + .layers(1); + + device.create_framebuffer(&create_info, None) + }) + .collect::, _>>()?; + + Ok(()) +} +unsafe fn create_command_pool(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { + let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?; + + let info = vk::CommandPoolCreateInfo::builder() + .flags(vk::CommandPoolCreateFlags::empty()) // Optional. + .queue_family_index(indices.graphics); + + data.command_pool = device.create_command_pool(&info, None)?; + + Ok(()) +} + +unsafe fn create_command_buffers(device:&Device, data:&mut AppData) -> Result<()> { + let allocate_info = vk::CommandBufferAllocateInfo::builder() + .command_pool(data.command_pool) + .level(vk::CommandBufferLevel::PRIMARY) + .command_buffer_count(data.framebuffers.len() as u32); + + data.command_buffers = device.allocate_command_buffers(&allocate_info)?; + + for (i, command_buffer) in data.command_buffers.iter().enumerate() { + let inheritance = vk::CommandBufferInheritanceInfo::builder(); + + let info = vk::CommandBufferBeginInfo::builder() + .flags(vk::CommandBufferUsageFlags::empty()) // Optional. + .inheritance_info(&inheritance); // Optional. + + device.begin_command_buffer(*command_buffer, &info)?; + + let render_area = vk::Rect2D::builder().offset(vk::Offset2D::default()).extent(data.swapchain_extent); + + let color_clear_value = vk::ClearValue { + color:vk::ClearColorValue { float32:[0.0, 0.0, 0.0, 1.0] }, + }; + + let clear_values = &[color_clear_value]; + let info = vk::RenderPassBeginInfo::builder() + .render_pass(data.render_pass) + .framebuffer(data.framebuffers[i]) + .render_area(render_area) + .clear_values(clear_values); + + device.cmd_begin_render_pass(*command_buffer, &info, vk::SubpassContents::INLINE); + device.cmd_bind_pipeline(*command_buffer, vk::PipelineBindPoint::GRAPHICS, data.pipeline); + device.cmd_draw(*command_buffer, 3, 1, 0, 0); + + device.cmd_end_render_pass(*command_buffer); + device.end_command_buffer(*command_buffer)?; + } + + Ok(()) +} + +unsafe fn create_sync_objects(device:&Device, data:&mut AppData) -> Result<()> { + let semaphore_info = vk::SemaphoreCreateInfo::builder(); + let fence_info = vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED); + + for _ in 0..MAX_FRAMES_IN_FLIGHT { + data.image_available_semaphores.push(device.create_semaphore(&semaphore_info, None)?); + data.render_finished_semaphores.push(device.create_semaphore(&semaphore_info, None)?); + + data.in_flight_fences.push(device.create_fence(&fence_info, None)?); + } + + data.images_in_flight = data.swapchain_images.iter().map(|_| vk::Fence::null()).collect(); + + Ok(()) +} + +#[derive(Copy, Clone, Debug)] +struct QueueFamilyIndices { + graphics:u32, + present: u32, +} + +impl QueueFamilyIndices { + unsafe fn get(instance:&Instance, data:&AppData, physical_device:vk::PhysicalDevice) -> Result { + let properties = instance.get_physical_device_queue_family_properties(physical_device); + + let graphics = properties + .iter() + .position(|p| p.queue_flags.contains(vk::QueueFlags::GRAPHICS)) + .map(|i| i as u32); + + let mut present = None; + for (index, properties) in properties.iter().enumerate() { + if instance.get_physical_device_surface_support_khr(physical_device, index as u32, data.surface)? { + present = Some(index as u32); + break; + } + } + + // Note that it's very likely that these end up being the same queue family after all, but throughout the program we will treat them as if they were separate queues for a uniform approach. Nevertheless, you could add logic to explicitly prefer a physical device that supports drawing and presentation in the same queue for improved performance. + if let (Some(graphics), Some(present)) = (graphics, present) { + Ok(Self { graphics, present }) + } else { + Err(anyhow!(SuitabilityError("Missing required queue families."))) + } + } +} + +#[derive(Clone, Debug)] +struct SwapchainSupport { + capabilities: vk::SurfaceCapabilitiesKHR, + formats: Vec, + present_modes:Vec, +} + +impl SwapchainSupport { + unsafe fn get(instance:&Instance, data:&AppData, physical_device:vk::PhysicalDevice) -> Result { + Ok(Self { + capabilities: instance.get_physical_device_surface_capabilities_khr(physical_device, data.surface)?, + formats: instance.get_physical_device_surface_formats_khr(physical_device, data.surface)?, + present_modes:instance.get_physical_device_surface_present_modes_khr(physical_device, data.surface)?, + }) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..306049d --- /dev/null +++ b/src/main.rs @@ -0,0 +1,46 @@ +#![deny(clippy::unwrap_used)] +#![allow( +// dead_code, + unused_variables, +// clippy::too_many_arguments, +// clippy::unnecessary_wraps, + unsafe_op_in_unsafe_fn +)] + +// planned system targets + +#[cfg(target_os = "linux")] mod linux; +#[cfg(target_os = "linux")] pub use linux::*; +#[cfg(target_os = "windows")] mod windows; +#[cfg(target_os = "windows")] pub use windows::*; +#[cfg(target_os = "macos")] mod mac; +#[cfg(target_os = "macos")] pub use mac::*; +#[cfg(target_family = "wasm")] mod wasm; +#[cfg(target_family = "wasm")] pub use wasm::*; +#[cfg(target_os = "vita")] mod vita; +#[cfg(target_os = "vita")] pub use vita::*; + +// unconfirmed system targets + +// bindgen, cc, https://github.com/rust-console + +// switch // c lib: libnx, crate: rust-switch, toolchain: devkitPro +// #[cfg(target_os = "horizon")] +// mod switch; +// #[cfg(target_os = "horizon")] +// pub use switch::*; +// ps3 // sdk: PSL1GHT, target: powerpc64-unknown-linux-gnu +// #[cfg(target_os = "psl1ght")] +// mod ps3; +// #[cfg(target_os = "psl1ght")] +// pub use ps3::*; +// x360 // c lib: libxenon, make custom spec for xenon target +// #[cfg(target_os = "xenon")] +// mod x369; +// #[cfg(target_os = "xenon")] +// pub use x360::*; +// wii // toolchain: devkitPPC, target: powerpc-unknown-eabi, c lib: libogc +// #[cfg(target_os = "wii")] +// mod wii; +// #[cfg(target_os = "wii")] +// pub use wii::*; diff --git a/src/vita/debug_screen/font.bin b/src/vita/debug_screen/font.bin new file mode 100644 index 0000000000000000000000000000000000000000..9b332fcdca105d217c70c4b953b6737c919e0a37 GIT binary patch literal 2048 zcmYjSF^Jq&5S{Z~u)6(Dr6Q1zQL&}KjSAs>jxALFVv7_hR0S0#sNBHa@%M1?ixet1 zV2m2WFRu)^5xDRcE?gcs#bOMXA_SEx%qnk2+K|y|M>Co~Gyl!}5z$2X<(uuB-!Jq0 z=F>QS`Z<4bJRYwyMJl_R`TDq4naD?QP@3Xz9LI+T{AH`#+uKz}@84cuU%!1nF3!LC z)q7uOtJNw~S1Mg5$xJjs*f%b&4YXa8ht_*Zy2(Kuy7<1F_x|9<8ty@(uowwL#K z{?DHEFzT6aFOxV=_mJK(aUH*LM_HFbNe z-o<2E6PjH~ki-t$z$M{Utka>^bzoO|V2?stj5o7HRF-&@bg1^bu=h3TvPA|1kQriqjbZ`e1sRO0P^?;QIuVAlX@A=1kgO%{B)^kR@E#yCaU77u^VW(S!ae+X z%c=8wPJsr275Jen#?;ucRGez$rIhRwx)Tjtw^^v8jo*-ScYD9TgAN%WUKCY3zpF$Z z9O|*;x@ySPZdXM$VBy4oWC=CiQ;IlEX-r{DTZoqRL>~hP9R6X?{&_zv@9zM>WnrVC`Qj|9TSq0yVDvC(~$`ZwoKY` zKVX;GrY;)^P@%7D&->JN!lR&xYc=y(ChXkRs)U``TX>Rn>Ll~l+0Vp{092EO1|0*u zCa&~=#^Ov~e0$UULeFjUs&8Hs5-Pcmke6^?&$4N$ZCi`FO}qgvcUB!ZKI3VnQxI2g zoZA3_1ois-6QeZXqONWCue|>a_;4K!_A7N)bAC9f5(ixHwutw!X=rH)jSHM7^MS39 z4kiPJiqw&h2DX6$M5y9R--Pwc=sV^=hCI>$9E8_N(G&?d{tNay;jo*F+9@ySr+v;ie8utnD?&q99$iXztNr@#_3H~23}S%bp4$cE!nh^TRS4B`xundb zMUis9FpXmmT7YDtW1f$v=}MI6VlnBunb?-se4XihrXOZ{@^t0-_N%8)_?C}|#KLUG zH^p^_{?Iu(JAb@*e11mbO&-Vj&A5GsugSx^E&HC$iDNOHWPbPT*@q8&10{=w0>j)D ze98J?`MV^2EVyU^Nu%xQzf7YtIdHQG9i8v`WKXKdaeKf literal 0 HcmV?d00001 diff --git a/src/vita/debug_screen/font.rs b/src/vita/debug_screen/font.rs new file mode 100644 index 0000000..be7afde --- /dev/null +++ b/src/vita/debug_screen/font.rs @@ -0,0 +1,19 @@ +pub struct DebugFont { + pub glyphs:&'static [u8], + pub width: usize, + pub height:usize, + pub first: u8, + pub last: u8, + pub size_w:usize, + pub size_h:usize, +} + +pub const DEBUG_FONT:DebugFont = DebugFont { + glyphs:include_bytes!("font.bin"), + width: 8, + height:8, + first: 0, + last: 255, + size_w:8, + size_h:8, +}; diff --git a/src/vita/debug_screen/fonts.rs b/src/vita/debug_screen/fonts.rs new file mode 100644 index 0000000..8266e42 --- /dev/null +++ b/src/vita/debug_screen/fonts.rs @@ -0,0 +1,11 @@ +struct Font { + bits_per_row:u8, + row_count: u8, + glyphs: [u8; 255], +} + +const COMIC_MONO_FONT:Font = Font { + bits_per_row:8, + row_count: 8, + glyphs: [0x00000000], +}; diff --git a/src/vita/debug_screen/framebuffer.rs b/src/vita/debug_screen/framebuffer.rs new file mode 100644 index 0000000..ca2d4f7 --- /dev/null +++ b/src/vita/debug_screen/framebuffer.rs @@ -0,0 +1,191 @@ +use core::ffi::c_void; +use core::fmt::Result; +use core::fmt::Write; +use core::mem::size_of; +use core::ptr; + +use vitasdk_sys::SCE_DISPLAY_SETBUF_NEXTFRAME; +use vitasdk_sys::SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW; +use vitasdk_sys::SceDisplayFrameBuf; +use vitasdk_sys::SceUID; +use vitasdk_sys::sceDisplaySetFrameBuf; +use vitasdk_sys::sceKernelAllocMemBlock; +use vitasdk_sys::sceKernelFreeMemBlock; +use vitasdk_sys::sceKernelGetMemBlockBase; + +use super::font::DEBUG_FONT; + +const SCREEN_WIDTH:usize = 960; +const SCREEN_HEIGHT:usize = 544; +const SCREEN_PIXEL_COUNT:usize = SCREEN_WIDTH * SCREEN_HEIGHT; +const SCREEN_FB_WIDTH:usize = 960; +const SCREEN_FB_SIZE:usize = 2 * 1024 * 1024; // 2kb +const SCREEN_TAB_SIZE:usize = 4; // Tab size in number of characters +const SCREEN_TAB_W:usize = DEBUG_FONT.size_w * SCREEN_TAB_SIZE; + +const DEFAULT_FG:u32 = 0xFFFFFFFF; +const DEFAULT_BG:u32 = 0xFF000000; + +pub struct DebugScreen { + framebuffer:Framebuffer, + coord_x: usize, + coord_y: usize, + color_fg: u32, + color_bg: u32, +} + +pub struct Framebuffer { + buf: *mut u32, + block_uid:SceUID, +} + +impl Framebuffer { + pub fn new() -> Framebuffer { + // Allocate memory to use as display buffer + let mut base:*mut c_void = ::core::ptr::null_mut(); + let block_uid = unsafe { + let block_uid:SceUID = sceKernelAllocMemBlock( + b"display\0".as_ptr() as *const i8, // a dereferenced memory position of the display + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + SCREEN_FB_SIZE as u32, + ::core::ptr::null_mut(), + ); + sceKernelGetMemBlockBase(block_uid, &mut base); + block_uid + }; + Framebuffer { + buf:base as *mut u32, + block_uid, + } + } + + pub fn set_display(&mut self) { + // Sets buffer as current display frame + let frame = SceDisplayFrameBuf { + size: size_of::() as u32, + base: self.buf as *mut c_void, + pitch: SCREEN_FB_WIDTH as u32, + pixelformat:0, + width: SCREEN_WIDTH as u32, + height: SCREEN_HEIGHT as u32, + }; + unsafe { + sceDisplaySetFrameBuf(&frame, SCE_DISPLAY_SETBUF_NEXTFRAME); + } + } + + #[allow(unused)] + pub fn get(&self, index:usize) -> u32 { + if index > SCREEN_PIXEL_COUNT { + panic!("Invalid framebuffer index"); + } + unsafe { ptr::read_volatile(self.buf.offset(index.try_into().unwrap())) } + } + + pub fn set(&mut self, index:usize, value:u32) { + if index > SCREEN_PIXEL_COUNT { + panic!("Invalid framebuffer index"); + } + unsafe { ptr::write_volatile(self.buf.offset(index.try_into().unwrap()), value) } + } +} + +impl Drop for Framebuffer { + fn drop(&mut self) { let _error_code = unsafe { sceKernelFreeMemBlock(self.block_uid) }; } +} + +impl Write for DebugScreen { + fn write_str(&mut self, s:&str) -> Result { + self.puts(s.as_bytes()); + Ok(()) + } +} + +impl DebugScreen { + pub fn new() -> Self { + let mut framebuffer = Framebuffer::new(); + framebuffer.set_display(); + Self { + framebuffer, + coord_x:0, + coord_y:0, + color_fg:DEFAULT_FG, + color_bg:DEFAULT_BG, + } + } + + #[allow(unused)] + fn clear(&mut self, from_h:usize, to_h:usize, from_w:usize, to_w:usize) { + for h in from_h..to_h { + for w in from_w..to_w { + self.framebuffer.set(h * SCREEN_FB_WIDTH + w, self.color_bg); + } + } + } + + fn puts(&mut self, text:&[u8]) { + let bytes_per_glyph = DEBUG_FONT.width * DEBUG_FONT.height / 8; + + for &chr in text.iter() { + if chr == b'\t' { + self.coord_x += SCREEN_TAB_W - (self.coord_x % SCREEN_TAB_W); + continue; + } + + // Go to next line at the end of the current line + if self.coord_x + DEBUG_FONT.width > SCREEN_WIDTH { + self.coord_y += DEBUG_FONT.size_h; + self.coord_x = 0; + } + + // Go to screen top when at the bottom of the screen + if self.coord_y + DEBUG_FONT.height > SCREEN_HEIGHT { + self.coord_x = 0; + self.coord_y = 0; + } + + if chr == b'\n' { + self.coord_x = 0; + self.coord_y += DEBUG_FONT.size_h; + continue; + } else if chr == b'\r' { + self.coord_x = 0; + continue; + } + + let current_offset = self.coord_x + self.coord_y * SCREEN_FB_WIDTH; + let mut font = &DEBUG_FONT.glyphs[(chr - DEBUG_FONT.first) as usize * bytes_per_glyph..]; + let mut mask = 1 << 7; + + for row in 0..DEBUG_FONT.height { + for col in 0..DEBUG_FONT.width { + if mask == 0 { + font = &font[1..]; + mask = 1 << 7; + } + + self.framebuffer.set( + current_offset + row * SCREEN_FB_WIDTH + col, + if font[0] & mask == 0 { self.color_bg } else { self.color_fg }, + ); + + mask >>= 1; + } + + #[allow(clippy::reversed_empty_ranges)] + for col in DEBUG_FONT.width..DEBUG_FONT.size_w { + self.framebuffer.set(current_offset + row * SCREEN_FB_WIDTH + col, self.color_bg) + } + } + + #[allow(clippy::reversed_empty_ranges)] + for row in DEBUG_FONT.height..DEBUG_FONT.size_h { + for col in 0..DEBUG_FONT.size_w { + self.framebuffer.set(current_offset + row * SCREEN_FB_WIDTH + col, self.color_bg) + } + } + + self.coord_x += DEBUG_FONT.size_w; + } + } +} diff --git a/src/vita/debug_screen/mod.rs b/src/vita/debug_screen/mod.rs new file mode 100644 index 0000000..27cbe8d --- /dev/null +++ b/src/vita/debug_screen/mod.rs @@ -0,0 +1,2 @@ +pub mod font; +pub mod framebuffer; diff --git a/src/vita/gui/font.bin b/src/vita/gui/font.bin new file mode 100644 index 0000000000000000000000000000000000000000..9b332fcdca105d217c70c4b953b6737c919e0a37 GIT binary patch literal 2048 zcmYjSF^Jq&5S{Z~u)6(Dr6Q1zQL&}KjSAs>jxALFVv7_hR0S0#sNBHa@%M1?ixet1 zV2m2WFRu)^5xDRcE?gcs#bOMXA_SEx%qnk2+K|y|M>Co~Gyl!}5z$2X<(uuB-!Jq0 z=F>QS`Z<4bJRYwyMJl_R`TDq4naD?QP@3Xz9LI+T{AH`#+uKz}@84cuU%!1nF3!LC z)q7uOtJNw~S1Mg5$xJjs*f%b&4YXa8ht_*Zy2(Kuy7<1F_x|9<8ty@(uowwL#K z{?DHEFzT6aFOxV=_mJK(aUH*LM_HFbNe z-o<2E6PjH~ki-t$z$M{Utka>^bzoO|V2?stj5o7HRF-&@bg1^bu=h3TvPA|1kQriqjbZ`e1sRO0P^?;QIuVAlX@A=1kgO%{B)^kR@E#yCaU77u^VW(S!ae+X z%c=8wPJsr275Jen#?;ucRGez$rIhRwx)Tjtw^^v8jo*-ScYD9TgAN%WUKCY3zpF$Z z9O|*;x@ySPZdXM$VBy4oWC=CiQ;IlEX-r{DTZoqRL>~hP9R6X?{&_zv@9zM>WnrVC`Qj|9TSq0yVDvC(~$`ZwoKY` zKVX;GrY;)^P@%7D&->JN!lR&xYc=y(ChXkRs)U``TX>Rn>Ll~l+0Vp{092EO1|0*u zCa&~=#^Ov~e0$UULeFjUs&8Hs5-Pcmke6^?&$4N$ZCi`FO}qgvcUB!ZKI3VnQxI2g zoZA3_1ois-6QeZXqONWCue|>a_;4K!_A7N)bAC9f5(ixHwutw!X=rH)jSHM7^MS39 z4kiPJiqw&h2DX6$M5y9R--Pwc=sV^=hCI>$9E8_N(G&?d{tNay;jo*F+9@ySr+v;ie8utnD?&q99$iXztNr@#_3H~23}S%bp4$cE!nh^TRS4B`xundb zMUis9FpXmmT7YDtW1f$v=}MI6VlnBunb?-se4XihrXOZ{@^t0-_N%8)_?C}|#KLUG zH^p^_{?Iu(JAb@*e11mbO&-Vj&A5GsugSx^E&HC$iDNOHWPbPT*@q8&10{=w0>j)D ze98J?`MV^2EVyU^Nu%xQzf7YtIdHQG9i8v`WKXKdaeKf literal 0 HcmV?d00001 diff --git a/src/vita/gui/framebuffer.rs b/src/vita/gui/framebuffer.rs new file mode 100644 index 0000000..1017ca5 --- /dev/null +++ b/src/vita/gui/framebuffer.rs @@ -0,0 +1,95 @@ +use std::mem::size_of; +use std::ptr; + +use vitasdk_sys::SCE_DISPLAY_SETBUF_NEXTFRAME; +use vitasdk_sys::SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW; +use vitasdk_sys::SceDisplayFrameBuf; +use vitasdk_sys::SceUID; +use vitasdk_sys::c_void; +use vitasdk_sys::sceDisplaySetFrameBuf; +use vitasdk_sys::sceKernelAllocMemBlock; +use vitasdk_sys::sceKernelFreeMemBlock; +use vitasdk_sys::sceKernelGetMemBlockBase; + +use crate::CDRAM_ALIGNMENT; +use crate::align; + +#[derive(Debug, Clone)] +pub struct Framebuffer { + pub buf: *mut u32, + pub block_uid: SceUID, + pub screen_height:u32, + pub screen_width: u32, + pub pixel_pitch: u32, + // pub pixel_count: u32, + pub pixel_format: u32, +} + +impl Framebuffer { + pub fn new() -> Framebuffer { + const SCREEN_WIDTH:u32 = 960; + const SCREEN_HEIGHT:u32 = 544; + const PIXEL_PITCH:u32 = SCREEN_WIDTH; + const PIXEL_COUNT:u32 = SCREEN_WIDTH * SCREEN_HEIGHT; + const FRAMEBUFFER_SIZE:u32 = align(PIXEL_COUNT * size_of::() as u32, CDRAM_ALIGNMENT); + + // Allocate memory to use as display buffer + let mut base:*mut c_void = ::core::ptr::null_mut(); + let block_uid = unsafe { + let block_uid:SceUID = sceKernelAllocMemBlock( + b"display\0".as_ptr() as *const i8, // a dereferenced memory position of the display // WHY i8 + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + FRAMEBUFFER_SIZE, + ::core::ptr::null_mut(), + ); + sceKernelGetMemBlockBase(block_uid, &mut base); + block_uid + }; + Framebuffer { + buf:base as *mut u32, + block_uid, + screen_height:SCREEN_HEIGHT, + screen_width:SCREEN_WIDTH, + pixel_pitch:PIXEL_PITCH, + pixel_format:0, + } + } + + pub fn set_display(&mut self) { + // Sets buffer as current display frame + let frame = SceDisplayFrameBuf { + size: size_of::() as u32, + base: self.buf as *mut c_void, + pitch: self.pixel_pitch, + pixelformat:self.pixel_format, + width: self.screen_width, + height: self.screen_height, + }; + unsafe { + sceDisplaySetFrameBuf(&frame, SCE_DISPLAY_SETBUF_NEXTFRAME); + } + } + + pub fn get(&self, index:u32) -> u32 { + if index > self.screen_height * self.screen_width { + panic!("Invalid framebuffer index"); + } + unsafe { ptr::read_volatile(self.buf.offset(index.try_into().unwrap())) } + } + + pub fn set(&mut self, index:u32, value:u32) { + if index > self.screen_height * self.screen_width { + panic!("Invalid framebuffer index"); + } + unsafe { ptr::write_volatile(self.buf.offset(index.try_into().unwrap()), value) } + } + + pub fn clear(&mut self) { + for index in 0..(self.screen_height * self.screen_width) { + self.set(index, 0); + } + } +} +impl Drop for Framebuffer { + fn drop(&mut self) { let _error_code = unsafe { sceKernelFreeMemBlock(self.block_uid) }; } +} diff --git a/src/vita/gui/mod.rs b/src/vita/gui/mod.rs new file mode 100644 index 0000000..70c61e6 --- /dev/null +++ b/src/vita/gui/mod.rs @@ -0,0 +1,492 @@ +use std::fmt::Write; + +pub mod framebuffer; + +pub const CHAR_BUF_SIZE_LIMIT:usize = 4 * 1024; // 4kb buf +pub const CHAR_BUF_RESET_SIZE:usize = 1 * 1024; // reset to 1kb buf +pub const TAB_WIDTH:u32 = 4; + +#[derive(Debug, Clone, Copy)] +pub struct Font { + char_width: u32, + char_height: u32, + pix_size_width: u32, + pix_size_height:u32, + first: u32, + last: u32, + glyphs: &'static [u8], +} + +pub const DEBUG_FONT:Font = Font { + char_height: 8, + char_width: 8, + pix_size_width: 8, + pix_size_height:8, + first: 0, + last: 255, + glyphs: include_bytes!("font.bin"), +}; + +#[derive(Debug, Clone)] +pub struct CharacterBuffer { + buffer: Vec, + buffer_x: u32, + buffer_y: u32, + use_word_wrap:bool, +} + +impl CharacterBuffer { + // TODO + pub fn get_sized_buf(&self, x:u32, y:u32, width:u32, height:u32) -> CharacterBuffer { + let buffer = vec![]; + // let buffer = self.buffer.clone(); + + CharacterBuffer { + buffer, + buffer_x:0, + buffer_y:0, + use_word_wrap:self.use_word_wrap, + } + } + + #[inline] + pub fn from_char_array(chars:&[char], use_word_wrap:bool) -> CharacterBuffer { + let mut cbuf = CharacterBuffer { + buffer:vec![], + buffer_x:0, + buffer_y:0, + use_word_wrap, + }; + + for char in chars { + cbuf.buffer.push(*char); + } + + cbuf + } + + pub fn to_pix(char:char, font:&Font, color_fg:u32, color_bg:u32) -> Vec { + let bytes_per_glyph = font.char_width * font.char_height / 8; + + let mut font_bytes = &font.glyphs[(char as usize - font.first as usize) * bytes_per_glyph as usize..]; + + let mut revec = vec![0; (font.char_width * font.char_height) as usize]; + + let mut mask = 1 << 7; + + for row in 0..font.char_height { + for col in 0..font.char_width { + if mask == 0 { + font_bytes = &font_bytes[1..]; + mask = 1 << 7; + } + + revec[(row * font.char_width + col) as usize] = if font_bytes[0] & mask == 0 { color_bg } else { color_fg }; + + // self.framebuffer.set( + // current_offset + row * self.column_count + col, + // if font[0] & mask == 0 { + // self.color_bg + // } else { + // self.color_fg + // }, + // ); + + mask >>= 1; + } + } + + // self.cursor_position_x += font.pix_size_width; + + revec + } +} + +#[derive(Debug, Clone)] +pub struct TextScreen { + framebuffer:framebuffer::Framebuffer, + font: Font, + color_bg: u32, + color_fg: u32, + + // for tracking charbuf + char_buf: CharacterBuffer, + // TODO move into cbuf + row_count: u32, + column_count:u32, + + // for tracking charbuf inside framebuffer + screen_vertical_position: u32, + screen_horizontal_position:u32, +} + +impl TextScreen { + // pub fn new( + // font: Font, + // use_word_wrap: bool, + // cursor_position_x: u32, + // cursor_position_y: u32, + // screen_vertical_position: u32, + // screen_horizontal_position: u32, + // char_buf: CharacterBuffer, + // color_fg: u32, + // color_bg: u32, + // ) -> TextScreen { + // let framebuffer = framebuffer::Framebuffer::new(); + + // let row_count = framebuffer.screen_height - (framebuffer.screen_height % font.char_height); + // let column_count = framebuffer.screen_width - (framebuffer.screen_width % font.char_width); + + // // let font = DEBUG_FONT; + // // let char_buf_vec_size = (framebuffer.screen_height / font.char_height) + // // * (framebuffer.screen_width / font.char_width); + + // TextScreen { + // framebuffer, + // font, + // cursor_position_x, + // cursor_position_y, + // row_count, + // column_count, + // screen_vertical_position, + // screen_horizontal_position, + // char_buf, // vec![TextChar(' '); char_buf_vec_size as usize * 2], + // color_bg, + // color_fg, + // } + // } + + pub fn predef() -> TextScreen { + let framebuffer = framebuffer::Framebuffer::new(); + + let row_count = framebuffer.screen_height - (framebuffer.screen_height % DEBUG_FONT.char_height); + let column_count = framebuffer.screen_width - (framebuffer.screen_width % DEBUG_FONT.char_width); + + let font = DEBUG_FONT; + let char_buf_vec_size = (framebuffer.screen_height / font.char_height) * (framebuffer.screen_width / font.char_width); + + TextScreen { + framebuffer, + font, + row_count, + column_count, + screen_vertical_position:0, + screen_horizontal_position:0, + char_buf:CharacterBuffer { + // buffer: vec![' '; char_buf_vec_size as usize * 2], + buffer: vec![' '; 32], + buffer_x: 0, + buffer_y: 0, + use_word_wrap:true, + }, + color_bg:0x00_00_00_00, // ABGR + color_fg:0xFF_FF_FF_FF, // ABGR + } + } + + pub fn set_cursor(&mut self, x:u32, y:u32) { + self.char_buf.buffer_x = x; + self.char_buf.buffer_y = y; + } + + pub fn clear(&mut self) { + self.char_buf.buffer.clear(); + self.char_buf.buffer_x = 0; + self.char_buf.buffer_y = 0; + // self.framebuffer.clear(); + } + + pub fn update_screen_raw(&mut self) { + let mut screen_x = 0; + let mut screen_y = 0; + + // let screen_position = self.screen_vertical_position * self.font.char_height; + + // if self.screen_vertical_position > self.screen_vertical_position + self.row_count { + // panic!("current screen pos"); + // } + + // for x in 300..400 { + // for y in 200..333 { + // self.framebuffer + // .set(x + y * self.framebuffer.screen_width, 0xFF_FF_FF_FF); + // } + // } + + // let cbuf = self.char_buf.clone(); + // self.char_buf.get_sized_buf( + // self.cursor_position_x, + // self.cursor_position_y, + // self.column_count, + // self.row_count, + // ); + + // cbuf.buffer = Vec::from_iter("Goodbye Void\n".chars()); + + // panic!("cbuf len: {:#?}", cbuf); + + for char in &self.char_buf.buffer { + // TODO re check like this for all end pixels and return if next end pixel is true + let end_pos = (screen_x + self.font.char_width) + (screen_y + self.font.char_height) * self.column_count; + if end_pos > self.framebuffer.screen_height * self.framebuffer.screen_width { + todo!("shift entire framebuffer up by like 15 lines and update it"); + } + + match char { + '\n' => { + screen_x = 0; + screen_y += 1 * self.font.char_height; + continue; + }, + '\t' => { + screen_x = screen_x + TAB_WIDTH * self.font.char_width; + continue; + }, + _ => { + let pix = CharacterBuffer::to_pix(*char, &self.font, self.color_fg, self.color_bg); + + for y in 0..self.font.char_height { + for x in 0..self.font.char_width { + self.framebuffer.set( + // 336 + x + y, + (screen_x + screen_y * self.framebuffer.screen_width) + (x + y * self.framebuffer.screen_width), + // ((self.cursor_position_x * self.font.char_width) + // + (self.cursor_position_y * self.font.char_height) + // * self.framebuffer.screen_width) + // + y * self.framebuffer.screen_width + // + x, + // 0xFF_FF_FF_FF, + pix[(x + y * self.font.char_width) as usize], + ); + // self.framebuffer.set( + // x + y * self.framebuffer.screen_width, + // 255, + // //char_pix[(x + y) as usize], + // ); + } + } + }, + } + + // if screen_x + self.font.char_width > self.framebuffer.screen_width { + // screen_x = 0; + // screen_y += self.font.char_height; + // } else { + screen_x += self.font.char_width; + // } + } + + // for y in self.screen_vertical_position..self.screen_vertical_position + self.row_count { + // for x in + // self.screen_horizontal_position..self.screen_horizontal_position + self.column_count + // { + + // } + // } + } + + pub fn enable(&mut self) { self.framebuffer.set_display(); } + + pub fn toss(&mut self) { + if self.char_buf.buffer.len() > CHAR_BUF_SIZE_LIMIT { + todo!(); + self.char_buf.buffer = self.char_buf.buffer.split_off(CHAR_BUF_RESET_SIZE); + } + } + + // pub fn draw_pos(&mut self, x: u32, y: u32) { + // let char = self.char_buf.buffer[(x + y * self.column_count) as usize]; + + // let char_pix = CharacterBuffer::to_pix(char, &self.font, self.color_fg, self.color_bg); + + // for y in 0..self.font.char_height { + // for x in 0..self.font.char_width { + // if self.cursor_position_x * self.font.char_width + self.font.char_width + // > self.framebuffer.screen_width + // { + // // self.set_cursor(self.cursor_position_x, self.cursor_position_y + 1); + // } + + // self.framebuffer.set( + // // 336 + x + y, + // // self.cursor_position_x + x + (self.cursor_position_y + y) * self.framebuffer.screen_width, + // ((self.cursor_position_x * self.font.char_width) + // + (self.cursor_position_y * self.font.char_height) + // * self.framebuffer.screen_width) + // + y * self.framebuffer.screen_width + // + x, + // // 0xFF_FF_FF_FF, + // char_pix[(x + y * self.font.char_width) as usize], + // ); + // // self.framebuffer.set( + // // x + y * self.framebuffer.screen_width, + // // 255, + // // //char_pix[(x + y) as usize], + // // ); + // } + // } + + // // // horizontal spacing + // // #[allow(clippy::reversed_empty_ranges)] + // // for col in DEBUG_FONT.char_width..DEBUG_FONT.pix_size_width { + // // self.framebuffer.set( + // // current_offset + row * self.column_count + col, + // // self.color_bg, + // // ) + // // } + + // // // vertical spacing + // // #[allow(clippy::reversed_empty_ranges)] + // // for row in DEBUG_FONT.char_height..DEBUG_FONT.pix_size_height { + // // for col in 0..DEBUG_FONT.pix_size_width { + // // self.framebuffer.set( + // // current_offset + row * self.column_count + col, + // // self.color_bg, + // // ) + // // } + // // } + // } + + // pub fn draw_screen() {} + + // #[deprecated] + // pub fn update_pos(&mut self, x: u32, y: u32) { + // let bytes_per_glyph = DEBUG_FONT.char_width * DEBUG_FONT.char_height / 8; + + // // for &chr in self.text.iter() { + + // // if chr == b'\t' { + // // self.text_position_x += SCREEN_TAB_W - (self.text_position_x % SCREEN_TAB_W); + // // continue; + // // } + + // // Go to next line at the end of the current line + // // if self.text_position_x + DEBUG_FONT.char_width > SCREEN_WIDTH { + // // self.text_position_y += DEBUG_FONT.char_height; + // // self.text_position_x = 0; + // // } + + // // Go to screen top when at the bottom of the screen + // // if self.text_position_y + DEBUG_FONT.char_height > SCREEN_HEIGHT { + // // self.text_position_x = 0; + // // self.text_position_y = 0; + // // // todo!(); + // // } + + // // if chr == b'\n' { + // // self.coord_x = 0; + // // self.coord_y += DEBUG_FONT.size_h; + // // continue; + // // } else if chr == b'\r' { + // // self.coord_x = 0; + // // continue; + // // } + + // let current_offset = self.cursor_position_x + self.cursor_position_y * self.column_count; + // let mut font = &DEBUG_FONT.glyphs + // // [(chr - DEBUG_FONT.first as u8) as usize * bytes_per_glyph as usize..]; + // [((x + y*self.row_count) as usize - DEBUG_FONT.first as usize) * bytes_per_glyph as usize..]; + // let mut mask = 1 << 7; + + // for row in 0..DEBUG_FONT.char_height { + // for col in 0..DEBUG_FONT.char_width { + // if mask == 0 { + // font = &font[1..]; + // mask = 1 << 7; + // } + + // self.framebuffer.set( + // current_offset + row * self.column_count + col, + // if font[0] & mask == 0 { + // self.color_bg + // } else { + // self.color_fg + // }, + // ); + + // mask >>= 1; + // } + + // #[allow(clippy::reversed_empty_ranges)] + // for col in DEBUG_FONT.char_width..DEBUG_FONT.pix_size_width { + // self.framebuffer.set( + // current_offset + row * self.column_count + col, + // self.color_bg, + // ) + // } + // } + + // #[allow(clippy::reversed_empty_ranges)] + // for row in DEBUG_FONT.char_height..DEBUG_FONT.pix_size_height { + // for col in 0..DEBUG_FONT.pix_size_width { + // self.framebuffer.set( + // current_offset + row * self.column_count + col, + // self.color_bg, + // ) + // } + // } + + // self.cursor_position_x += DEBUG_FONT.pix_size_width; + // // } + // } + + // #[deprecated] + // pub fn update_screen(&mut self) { + // for x in 0..self.row_count { + // for y in 0..self.column_count { + // self.update_pos(x, y); + // } + // } + // } +} + +impl Write for TextScreen { + fn write_str(&mut self, s:&str) -> std::fmt::Result { + for char in s.chars() { + let pos = self.char_buf.buffer_x + self.char_buf.buffer_y * self.column_count; + // if position is outside current buf, allocate more space + // but if we try to allocate more space than we should + // just cut the char_buf in half to prevent memory bloating + while pos as usize >= self.char_buf.buffer.len() { + self.toss(); + // self.char_buf.buffer.extend([' '; 256]); + self.char_buf.buffer.extend([' '; 32]); + } + + self.char_buf.buffer[pos as usize] = char; + self.char_buf.buffer_x += 1; + } + + // let mut chars = s.chars(); + // while let Some(char) = chars.next() { + // match char { + // '\n' => (), //self.set_cursor(self.cursor_position_x, self.cursor_position_y + 1), + // '\t' => (), // self.set_cursor( + // // self.cursor_position_x + TAB_WIDTH - (self.cursor_position_x % TAB_WIDTH), + // // self.cursor_position_y, + // // ), + // '\r' => (), //self.set_cursor(0, self.cursor_position_y), + // _ => { + // // let pos = self.cursor_position_x + self.cursor_position_y * self.row_count; + + // // if position is outside current buf, allocate more space + // // but if we try to allocate more space than we should + // // just cut the char_buf in half to prevent memory bloating + // while pos as usize > self.char_buf.len() { + // if self.char_buf.len() > CHAR_BUF_SIZE_LIMIT { + // self.char_buf = self.char_buf.split_off(CHAR_BUF_RESET_SIZE); + // } + // self.char_buf.extend([TextChar(' '); 256]); + // } + + // self.char_buf[pos as usize] = TextChar(char); + + // // self.draw_pos(self.cursor_position_x, self.cursor_position_y); + // // self.set_cursor(self.cursor_position_x + 1, self.cursor_position_y); + // } + // } + // // std::thread::sleep(Duration::from_millis(200)); + // } + Ok(()) + } +} diff --git a/src/vita/mod.rs b/src/vita/mod.rs new file mode 100644 index 0000000..c31a448 --- /dev/null +++ b/src/vita/mod.rs @@ -0,0 +1,211 @@ +use std::fmt::Write; +use std::panic::PanicHookInfo; +use std::thread; +use std::time::Duration; + +use vitasdk_sys::sceGxmTerminate; + +mod debug_screen; +mod gui; + +// pub const CDRAM_ALIGNMENT: u32 = 0x3FFFF; +/// 256 kb +pub const CDRAM_ALIGNMENT:u32 = (256 * 1024) - 1; +/// 4 kb +pub const NOT_CDRAM_ALIGNMENT:u32 = (4 * 1024) - 1; + +#[inline] +pub const fn align(data:u32, alignment:u32) -> u32 { (data + alignment) & !alignment } + +// these should probably be macros? +#[inline] +pub fn abs(x:i8) -> i8 { if x > 0 { x } else { x * -1 } } + +// tracing based logger + +fn rainbow_color(t:f32) -> (u32, u32, u32) { + let hue = t * 360.0; // Convert time to hue (0-360 degrees) + let saturation = 1.0; // Maximum saturation + let value = 1.0; // Maximum value (brightness) + + // Convert HSV to RGB + let c = value * saturation; + let x = c * (1.0 - (((hue / 60.0) % 2.0) - 1.0).abs()); + let m = value - c; + let (r, g, b) = match hue { + 0.0..=60.0 => (c, x, 0.0), + 60.0..=120.0 => (x, c, 0.0), + 120.0..=180.0 => (0.0, c, x), + 180.0..=240.0 => (0.0, x, c), + 240.0..=300.0 => (x, 0.0, c), + _ => (c, 0.0, x), + }; + + // Scale RGB values to 8-bit integers + let r = (255.0 * (r + m)) as u32; + let g = (255.0 * (g + m)) as u32; + let b = (255.0 * (b + m)) as u32; + + (r, g, b) +} + +fn ilerp(min:f32, max:f32, input:f32) -> f32 { (input - min) / (max - min) } + +// #[tokio::main] +pub fn main() { + std::panic::set_hook(Box::new(custom_panic_hook)); + + println!("Panic hook set"); + + // SCE_GXM_ERROR_INVALID_POINTER + + // const thing1: u32 = 0x80024b05; + // const thing2: u32 = 0x80024309; + + // unsafe { sceClibPrintf("whar?".as_ptr() as *const i8); } + + // text_screen(); + + // std::thread::sleep(Duration::from_secs(3)); + + // for _ in 0..3 { + // raw_rainbow(); + // } + + // std::thread::sleep(Duration::from_secs(3)); + + // new_text_screen(); + + // std::thread::sleep(Duration::from_secs(3)); + + // unsafe { + // cube::cube(); + // cube2::cube(); + // cube3::cube(); + // } + + std::thread::sleep(Duration::from_secs(3)); + + panic!("Test panic!"); + + // loop { + // std::thread::sleep(Duration::from_secs(10)); + // } + + unsafe { sceGxmTerminate() }; +} + +// fn new_text_screen() { +// let mut screen = gui::TextScreen::predef(); +// screen.enable(); + +// // for i in 336..446 { +// // screen.framebuffer.set(i, 0xFF_FF_FF_FF); +// // } + +// // screen.set_cursor(4, 0); +// // write!(screen, "\n").ok(); +// // screen.update_screen_raw(); +// write!(screen, "Goodbye Void!\n").ok(); +// screen.update_screen_raw(); +// thread::sleep(Duration::from_secs(3)); +// write!(screen, "Goodbye Void!\n").ok(); +// screen.update_screen_raw(); +// thread::sleep(Duration::from_secs(3)); +// write!(screen, "Goodbye Void!\n").ok(); +// screen.update_screen_raw(); +// thread::sleep(Duration::from_secs(3)); + +// screen.set_cursor(0, 3); +// for _ in 0..25 { +// write!(screen, "Goodbye Void!\n").ok(); +// // screen.update_screen_raw(); +// } + +// thread::sleep(Duration::from_secs(3)); +// screen.clear(); +// screen.update_screen_raw(); + +// // screen.set_foreground(255,255,0); + +// // for x in 0..24 { +// // for y in 0..24 { +// // mono_screen.set_cursor(24 + x, 24 + y); +// // write!((219 as char).to_string()); +// // thread::sleep(Duration::from_millis(16)); +// // } +// // } +// // mono_screen.set_cursor(0,1); +// // mono_screen.set_foreground(0,0,0); + +// // drop(screen); + +// // let mut screen = gui::TextScreen::new(); +// // screen.set_display(); +// // loop { +// // screen.clear(); +// // screen.update_screen_raw(); +// // std::thread::sleep(Duration::from_millis(100)); +// // } +// } + +// fn text_screen() { +// let mut screen = debug::framebuffer::DebugScreen::new(); +// writeln!(screen, "crusty").ok(); +// // thread::sleep(Duration::from_secs(2)); +// writeln!(screen, "newline").ok(); +// // thread::sleep(Duration::from_secs(2)); + +// let random_numbers: Vec = (0..8).map(|_i| rand::random::()).collect(); +// writeln!(screen, "random numbers: {:?}", random_numbers).ok(); + +// // writeln!(screen, "I know where you sleep :3").ok(); +// } + +fn raw_rainbow() { + let mut raw_buffer = gui::framebuffer::Framebuffer::new(); + raw_buffer.set_display(); + + for index_width in 0..raw_buffer.screen_width { + thread::sleep(Duration::from_micros(20)); + + let (r, g, b) = rainbow_color(ilerp(0.0, raw_buffer.screen_width as f32, index_width as f32)); + + for index_height in 0..raw_buffer.screen_height { + raw_buffer.set(index_width + (index_height * raw_buffer.screen_width), 0 as u32 | b << 16 | g << 8 | r); // VITA USES ABGR + } + } +} + +fn custom_panic_hook(info:&PanicHookInfo<'_>) { + // The current implementation always returns `Some`. + let location = info.location().unwrap(); + + let msg = match info.payload().downcast_ref::<&'static str>() { + Some(s) => *s, + None => match info.payload().downcast_ref::() { + Some(s) => &s[..], + None => "Box", + }, + }; + let name = "unknown"; + + let mut screen = debug_screen::framebuffer::DebugScreen::new(); + + println!("thread '{}' panicked at '{}', {}", name, msg, location); + writeln!(screen, "thread '{}' panicked at '{}', {}", name, msg, location).ok(); + + // Give 2 seconds to see the error in case capturing the stack trace fails + // (capturing the stack trace allocates memory) + thread::sleep(Duration::from_secs(2)); + + let _ = std::panic::catch_unwind(move || { + // The backtrace is full of "unknown" for some reason + let backtrace = std::backtrace::Backtrace::force_capture(); + writeln!(screen, "{}", backtrace).ok(); + }); + + loop { + thread::sleep(Duration::from_secs(60)); + } +} diff --git a/src/windows.rs b/src/windows.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/windows.rs @@ -0,0 +1 @@ + diff --git a/thanks.txt b/thanks.txt new file mode 100644 index 0000000..367a8cc --- /dev/null +++ b/thanks.txt @@ -0,0 +1,10 @@ +# list of resources ive used in the making of this project +# thank you to everyone here for allowing me to learn what was required to make this project + +https://kylemayes.github.io/vulkanalia/introduction.html + +# javidx9 code it yourself console game engine tutorial +https://www.youtube.com/watch?v=ih20l3pJoeU +https://www.youtube.com/watch?v=XgMWc6LumG4 +https://www.youtube.com/watch?v=HXSuNxpCzdM +https://www.youtube.com/watch?v=nBzCS-Y0FcY