From f7f5d9d8a5e5323824c27f501c1de85e73659da7 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 18 Feb 2023 10:41:07 -0500 Subject: [PATCH] Split into lib, CLI, GUI --- Cargo.lock | 3661 +++++++++++++++++++++++- Cargo.toml | 40 +- lib/Cargo.toml | 14 + {src => lib/src}/format/chunk.rs | 0 lib/src/format/cmdl.rs | 820 ++++++ lib/src/format/foot.rs | 30 + {src => lib/src}/format/mod.rs | 64 +- {src => lib/src}/format/pack.rs | 213 +- {src => lib/src}/format/rfrm.rs | 0 {src => lib/src}/format/txtr.rs | 60 +- lib/src/lib.rs | 2 + {src => lib/src}/util/astc.rs | 0 lib/src/util/compression.rs | 46 + {src => lib/src}/util/dds.rs | 0 {src => lib/src}/util/file.rs | 0 lib/src/util/lzss.rs | 36 + {src => lib/src}/util/mod.rs | 1 + retrotool-gui/Cargo.toml | 28 + retrotool-gui/src/loaders.rs | 229 ++ retrotool-gui/src/main.rs | 278 ++ retrotool/Cargo.toml | 29 + {src => retrotool/src}/argh_version.rs | 0 {src => retrotool/src}/cmd/cmdl.rs | 919 +----- {src => retrotool/src}/cmd/fmv0.rs | 5 +- {src => retrotool/src}/cmd/mod.rs | 0 {src => retrotool/src}/cmd/pak.rs | 11 +- retrotool/src/cmd/txtr.rs | 80 + {src => retrotool/src}/main.rs | 2 - src/cmd/txtr.rs | 141 - src/util/lzss.rs | 81 - 30 files changed, 5612 insertions(+), 1178 deletions(-) create mode 100644 lib/Cargo.toml rename {src => lib/src}/format/chunk.rs (100%) create mode 100644 lib/src/format/cmdl.rs create mode 100644 lib/src/format/foot.rs rename {src => lib/src}/format/mod.rs (51%) rename {src => lib/src}/format/pack.rs (59%) rename {src => lib/src}/format/rfrm.rs (100%) rename {src => lib/src}/format/txtr.rs (85%) create mode 100644 lib/src/lib.rs rename {src => lib/src}/util/astc.rs (100%) create mode 100644 lib/src/util/compression.rs rename {src => lib/src}/util/dds.rs (100%) rename {src => lib/src}/util/file.rs (100%) create mode 100644 lib/src/util/lzss.rs rename {src => lib/src}/util/mod.rs (95%) create mode 100644 retrotool-gui/Cargo.toml create mode 100644 retrotool-gui/src/loaders.rs create mode 100644 retrotool-gui/src/main.rs create mode 100644 retrotool/Cargo.toml rename {src => retrotool/src}/argh_version.rs (100%) rename {src => retrotool/src}/cmd/cmdl.rs (60%) rename {src => retrotool/src}/cmd/fmv0.rs (97%) rename {src => retrotool/src}/cmd/mod.rs (100%) rename {src => retrotool/src}/cmd/pak.rs (96%) create mode 100644 retrotool/src/cmd/txtr.rs rename {src => retrotool/src}/main.rs (97%) delete mode 100644 src/cmd/txtr.rs delete mode 100644 src/util/lzss.rs diff --git a/Cargo.lock b/Cargo.lock index 037e109..6e72ca1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,50 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ab_glyph" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe21446ad43aa56417a767f3e2f3d7c4ca522904de1dd640529a76e9c5c3b33c" +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 = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.20" @@ -11,12 +55,90 @@ dependencies = [ "memchr", ] +[[package]] +name = "alsa" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5915f52fe2cf65e83924d037b6c5290b7cee097c6b5c8700746e6168a343fd6b" +dependencies = [ + "alsa-sys", + "bitflags", + "libc", + "nix 0.23.2", +] + +[[package]] +name = "alsa-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "android_log-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e" + +[[package]] +name = "android_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8619b80c242aa7bd638b5c7ddd952addeecb71f69c75e33f1d47b2804f8f883a" +dependencies = [ + "android_log-sys", + "env_logger", + "log", + "once_cell", +] + +[[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.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arboard" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6041616acea41d67c4a984709ddab1587fd0b10efe5cc563fee954d2f011854" +dependencies = [ + "clipboard-win", + "core-graphics", + "image", + "log", + "objc", + "objc-foundation", + "objc_id", + "once_cell", + "parking_lot", + "thiserror", + "winapi", + "x11rb", +] + [[package]] name = "argh" version = "0.1.10" @@ -51,12 +173,782 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "ash" +version = "0.37.2+1.3.238" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28bf19c1f0a470be5fbf7522a308a05df06610252c5bcf5143e1b23f629a9a03" +dependencies = [ + "libloading", +] + +[[package]] +name = "astc-decode" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6058e6202e20b7fa445692ec4b77ca8eb02508091fcd479ea753d9f60e376b" + +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue 2.1.0", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue 2.1.0", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-lock" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" +dependencies = [ + "event-listener", + "futures-lite", +] + +[[package]] +name = "async-task" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" + +[[package]] +name = "atomic_refcell" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "857253367827bd9d0fd973f0ef15506a96e79e41b0ad7aa691203a4e3214f6c8" + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bevy" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae99b246505811f5bc19d2de1e406ec5d2816b421d58fa223779eb576f472c9" +dependencies = [ + "bevy_dylib", + "bevy_internal", +] + +[[package]] +name = "bevy_animation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d43b8073f299eb60ce9e1d60fa293b348590dd57aca8321d6859d9e7aa57d2da" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_core", + "bevy_ecs", + "bevy_hierarchy", + "bevy_math", + "bevy_reflect", + "bevy_time", + "bevy_transform", + "bevy_utils", +] + +[[package]] +name = "bevy_app" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "536e4d0018347478545ed8b6cb6e57b9279ee984868e81b7c0e78e0fb3222e42" +dependencies = [ + "bevy_derive", + "bevy_ecs", + "bevy_reflect", + "bevy_utils", + "downcast-rs", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "bevy_asset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db1bb550168304df69c867c09125e1aae7ff51cf21575396e1598bf293442c4" +dependencies = [ + "anyhow", + "bevy_app", + "bevy_diagnostic", + "bevy_ecs", + "bevy_log", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "crossbeam-channel", + "downcast-rs", + "fastrand", + "js-sys", + "ndk-glue", + "notify", + "parking_lot", + "serde", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "bevy_audio" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a05efc6c23bef37520e44029943c65b7e8a4fe4f5e54cb3f96e63ce0b3d361" +dependencies = [ + "anyhow", + "bevy_app", + "bevy_asset", + "bevy_ecs", + "bevy_reflect", + "bevy_utils", + "parking_lot", + "rodio", +] + +[[package]] +name = "bevy_core" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96299aceb3c8362cb4aa39ff81c7ef758a5f4e768d16b5046a91628eff114ac0" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_math", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "bytemuck", +] + +[[package]] +name = "bevy_core_pipeline" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc128a9860aadf16fb343ae427f2768986fd91dce64d945455acda9759c48014" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bitflags", + "radsort", + "serde", +] + +[[package]] +name = "bevy_derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7baf73c58d41c353c6fd08e6764a2e7420c9f19e8227b391c50981db6d0282a6" +dependencies = [ + "bevy_macro_utils", + "quote", + "syn", +] + +[[package]] +name = "bevy_diagnostic" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63bf96ec7980fa25b77ff6c72dfafada477936c0dab76c1edf6c028c0e5fe0e4" +dependencies = [ + "bevy_app", + "bevy_core", + "bevy_ecs", + "bevy_log", + "bevy_time", + "bevy_utils", +] + +[[package]] +name = "bevy_dylib" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d193c3d56e3bdd106596327d15dd67ddfd862f8b5aa8260677efefe3ddef736" +dependencies = [ + "bevy_internal", +] + +[[package]] +name = "bevy_ecs" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c071d7c6bc9801253485e05d0c257284150de755391902746837ba21c0cf74" +dependencies = [ + "async-channel", + "bevy_ecs_macros", + "bevy_ptr", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "downcast-rs", + "event-listener", + "fixedbitset", + "fxhash", + "serde", + "thread_local", +] + +[[package]] +name = "bevy_ecs_macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c15bd45438eeb681ad74f2d205bb07a5699f98f9524462a30ec764afab2742ce" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bevy_egui" +version = "0.19.0" +source = "git+https://github.com/paul-hansen/bevy_egui?branch=egui-0.21#6778a8c308f120ed1a9c8c261a05f971873919d8" +dependencies = [ + "arboard", + "bevy", + "egui", + "thread_local", + "webbrowser", +] + +[[package]] +name = "bevy_encase_derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "962b6bb0d30e92ec2e6c29837acce9e55b920733a634e7c3c5fd5a514bea7a24" +dependencies = [ + "bevy_macro_utils", + "encase_derive_impl", +] + +[[package]] +name = "bevy_gilrs" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4af552dad82f854b2fae24f36a389fd8ee99d65fe86ae876e854e70d53ff16d9" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_input", + "bevy_utils", + "gilrs", +] + +[[package]] +name = "bevy_gltf" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e853e346ba412354e02292c7aa5b9a9dccdfa748e273b1b7ebf8f6a172f89712" +dependencies = [ + "anyhow", + "base64", + "bevy_animation", + "bevy_app", + "bevy_asset", + "bevy_core", + "bevy_core_pipeline", + "bevy_ecs", + "bevy_hierarchy", + "bevy_log", + "bevy_math", + "bevy_pbr", + "bevy_reflect", + "bevy_render", + "bevy_scene", + "bevy_tasks", + "bevy_transform", + "bevy_utils", + "gltf", + "percent-encoding", + "thiserror", +] + +[[package]] +name = "bevy_hierarchy" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd6d50c48c6e1bcb5e08a768b765323292bb3bf3a439b992754c57ffb85b23a" +dependencies = [ + "bevy_app", + "bevy_core", + "bevy_ecs", + "bevy_log", + "bevy_reflect", + "bevy_utils", + "smallvec", +] + +[[package]] +name = "bevy_input" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3378b5171284f4c4c0e8307081718a9fe458f846444616bd82d69110dcabca51" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_math", + "bevy_reflect", + "bevy_utils", + "thiserror", +] + +[[package]] +name = "bevy_internal" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c46014b7e885b1311de06b6039e448454a4db55b8d35464798ba88faa186e11" +dependencies = [ + "bevy_animation", + "bevy_app", + "bevy_asset", + "bevy_audio", + "bevy_core", + "bevy_core_pipeline", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_gilrs", + "bevy_gltf", + "bevy_hierarchy", + "bevy_input", + "bevy_log", + "bevy_math", + "bevy_pbr", + "bevy_ptr", + "bevy_reflect", + "bevy_render", + "bevy_scene", + "bevy_sprite", + "bevy_tasks", + "bevy_text", + "bevy_time", + "bevy_transform", + "bevy_ui", + "bevy_utils", + "bevy_window", + "bevy_winit", + "ndk-glue", +] + +[[package]] +name = "bevy_log" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c480bac54cf4ae76edc3ae9ae3fa7c5e1b385e7f2111ef5ec3fd00cf3a7998b" +dependencies = [ + "android_log-sys", + "bevy_app", + "bevy_ecs", + "bevy_utils", + "console_error_panic_hook", + "tracing-log", + "tracing-subscriber", + "tracing-wasm", +] + +[[package]] +name = "bevy_macro_utils" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022bb69196deeea691b6997414af85bbd7f2b34a8914c4aa7a7ff4dfa44f7677" +dependencies = [ + "quote", + "syn", + "toml", +] + +[[package]] +name = "bevy_math" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d434c77ab766c806ed9062ef8a7285b3b02b47df51f188d4496199c3ac062eaf" +dependencies = [ + "glam", + "serde", +] + +[[package]] +name = "bevy_mikktspace" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfb5908d33fd613069be516180b8f138aaaf6e41c36b1fd98c6c29c00c24a13" +dependencies = [ + "glam", +] + +[[package]] +name = "bevy_pbr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310b1f260a475d81445623e138e1b7245759a42310bc1f84b550a3f4ff8763bf" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bitflags", + "bytemuck", + "radsort", +] + +[[package]] +name = "bevy_ptr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec44f7655039546bc5d34d98de877083473f3e9b2b81d560c528d6d74d3eff4" + +[[package]] +name = "bevy_reflect" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6deae303a7f69dc243b2fa35b5e193cc920229f448942080c8eb2dbd9de6d37a" +dependencies = [ + "bevy_math", + "bevy_ptr", + "bevy_reflect_derive", + "bevy_utils", + "downcast-rs", + "erased-serde", + "glam", + "once_cell", + "parking_lot", + "serde", + "smallvec", + "thiserror", +] + +[[package]] +name = "bevy_reflect_derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bf4cb9cd5acb4193f890f36cb63679f1502e2de025e66a63b194b8b133d018" +dependencies = [ + "bevy_macro_utils", + "bit-set", + "proc-macro2", + "quote", + "syn", + "uuid", +] + +[[package]] +name = "bevy_render" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e3282a8f8779d2aced93207fbed73f740937c6c2bd27bd84f0799b081c7fca5" +dependencies = [ + "anyhow", + "bevy_app", + "bevy_asset", + "bevy_core", + "bevy_derive", + "bevy_ecs", + "bevy_encase_derive", + "bevy_hierarchy", + "bevy_log", + "bevy_math", + "bevy_mikktspace", + "bevy_reflect", + "bevy_render_macros", + "bevy_time", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bitflags", + "codespan-reporting", + "downcast-rs", + "encase", + "futures-lite", + "hex", + "hexasphere", + "image", + "naga", + "once_cell", + "parking_lot", + "regex", + "serde", + "smallvec", + "thiserror", + "thread_local", + "wgpu", +] + +[[package]] +name = "bevy_render_macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7acae697776ac05bea523e1725cf2660c91c53abe72c66782ea1e1b9eedb572" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bevy_scene" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9c66a628c833d53bae54fe94cbc0d3f12c29e9d2e6c3f2356d45ad57db0c8c" +dependencies = [ + "anyhow", + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_hierarchy", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "ron", + "serde", + "thiserror", + "uuid", +] + +[[package]] +name = "bevy_sprite" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ec01c7db7f698d95bcb70708527c3ae6bcdc78fc247abe74f935cae8f0a1145" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_log", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bitflags", + "bytemuck", + "fixedbitset", + "guillotiere", + "rectangle-pack", + "thiserror", +] + +[[package]] +name = "bevy_tasks" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680b16b53df9c9f24681dd95f4d772d83760bd19adf8bca00f358a3aad997853" +dependencies = [ + "async-channel", + "async-executor", + "async-task", + "concurrent-queue 1.2.4", + "futures-lite", + "once_cell", + "wasm-bindgen-futures", +] + +[[package]] +name = "bevy_text" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60c74c1bdaabde7db28f6728aa13bc7b1d744a2201b2bbfd83d2224404c57f5c" +dependencies = [ + "ab_glyph", + "anyhow", + "bevy_app", + "bevy_asset", + "bevy_ecs", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_sprite", + "bevy_transform", + "bevy_utils", + "bevy_window", + "glyph_brush_layout", + "serde", + "thiserror", +] + +[[package]] +name = "bevy_time" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c38a6d3ea929c7f81e6adf5a6c62cf7e8c40f5106c2174d6057e9d8ea624d" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_reflect", + "bevy_utils", + "crossbeam-channel", +] + +[[package]] +name = "bevy_transform" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba13c57a040b89767191a6f6d720a635b7792793628bfa41a9e38b7026484aec" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_hierarchy", + "bevy_math", + "bevy_reflect", +] + +[[package]] +name = "bevy_ui" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e82ace6156f11fcdf2319102ff8fb8367b82d1e32b7d05d387a1963602f965" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_hierarchy", + "bevy_input", + "bevy_log", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_sprite", + "bevy_text", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bytemuck", + "serde", + "smallvec", + "taffy", + "thiserror", +] + +[[package]] +name = "bevy_utils" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16750aae52cd35bd7b60eb61cee883420b250e11b4a290b8d44b2b2941795739" +dependencies = [ + "ahash 0.7.6", + "getrandom", + "hashbrown", + "instant", + "tracing", + "uuid", +] + +[[package]] +name = "bevy_window" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a44d3f3bd54a2261f4f57f614bf7bccc8d2832761493c0cd7dab81d98cc151e" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_input", + "bevy_math", + "bevy_reflect", + "bevy_utils", + "raw-window-handle 0.5.0", +] + +[[package]] +name = "bevy_winit" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7b7e647ecd0b3577468da37767dcdd7c26ca9f80da0060b2ec4c77336b6d2e1" +dependencies = [ + "approx", + "bevy_app", + "bevy_ecs", + "bevy_input", + "bevy_math", + "bevy_utils", + "bevy_window", + "crossbeam-channel", + "raw-window-handle 0.5.0", + "wasm-bindgen", + "web-sys", + "winit", +] + +[[package]] +name = "bindgen" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a022e58a142a46fea340d68012b9201c094e93ec3d033a944a24f8fd4a4f09a" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + [[package]] name = "binrw" version = "0.11.1" @@ -81,17 +973,64 @@ dependencies = [ "syn", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + [[package]] name = "bytemuck" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aca418a974d83d40a0c1f0c5cba6ff4bc28d8df099109ca459a2118d40b6322" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "byteorder" @@ -99,11 +1038,41 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cache-padded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" + [[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] [[package]] name = "cfg-if" @@ -111,12 +1080,320 @@ 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 = "clang-sys" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clipboard-win" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-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 = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" +dependencies = [ + "cache-padded", +] + +[[package]] +name = "concurrent-queue" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const_panic" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58baae561b85ca19b3122a9ddd35c8ec40c3bcd14fe89921824eae73f7baffbf" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "coreaudio-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11894b20ebfe1ff903cbdc52259693389eea03b94918a2def2c30c3bf227ad88" +dependencies = [ + "bitflags", + "coreaudio-sys", +] + +[[package]] +name = "coreaudio-sys" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9444b94b8024feecc29e01a9706c69c1e26bfee480221c90764200cfd778fb" +dependencies = [ + "bindgen", +] + +[[package]] +name = "cpal" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f342c1b63e185e9953584ff2199726bf53850d96610a310e3aca09e9405a2d0b" +dependencies = [ + "alsa", + "core-foundation-sys", + "coreaudio-rs", + "jni 0.19.0", + "js-sys", + "libc", + "mach", + "ndk 0.7.0", + "ndk-context", + "oboe", + "once_cell", + "parking_lot", + "stdweb", + "thiserror", + "wasm-bindgen", + "web-sys", + "windows 0.37.0", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.7.1", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + [[package]] name = "crunchy" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "d3d12" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "827914e1f53b1e0e025ecd3d967a7836b7bcb54520f90e21ef8df7b4d88a2759" +dependencies = [ + "bitflags", + "libloading", + "winapi", +] + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "ddsfile" version = "0.5.2-unstable" @@ -128,12 +1405,120 @@ dependencies = [ "num-traits", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "ecolor" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f99fe3cac305af9d6d92971af60d0f7ea4d783201ef1673571567b6699964d9" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "egui" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6412a21e0bde7c0918f7fb44bbbb86b5e1f88e63c026a4e747cc7af02f76dfbe" +dependencies = [ + "ahash 0.8.3", + "epaint", + "nohash-hasher", +] + +[[package]] +name = "egui_dock" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f86bdfe987f753ffcdf896932f09babfc63580b21e1899c304166f0befc85c8" +dependencies = [ + "egui", +] + [[package]] name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "emath" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ecd80612937e0267909d5351770fe150004e24dab93954f69ca62eecd3f77e" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "encase" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48ec50086547d597b5c871a78399ec04a14828a6a5c445a61ed4687c540edec6" +dependencies = [ + "const_panic", + "encase_derive", + "glam", + "thiserror", +] + +[[package]] +name = "encase_derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda93e9714c7683c474f49a461a2ae329471d2bda43c4302d41c6d8339579e92" +dependencies = [ + "encase_derive_impl", +] + +[[package]] +name = "encase_derive_impl" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec27b639e942eb0297513b81cc6d87c50f6c77dc8c37af00a39ed5db3b9657ee" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "enum-primitive-derive" version = "0.2.2" @@ -158,6 +1543,31 @@ dependencies = [ "termcolor", ] +[[package]] +name = "epaint" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e78b5c58a1f7f621f9d546add2adce20636422c9b251e29f749e8a2f713c95" +dependencies = [ + "ab_glyph", + "ahash 0.8.3", + "atomic_refcell", + "bytemuck", + "ecolor", + "emath", + "nohash-hasher", + "parking_lot", +] + +[[package]] +name = "erased-serde" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ca605381c017ec7a5fef5e548f1cfaa419ed0f6df6367339300db74c92aa7d" +dependencies = [ + "serde", +] + [[package]] name = "errno" version = "0.2.8" @@ -179,6 +1589,284 @@ dependencies = [ "libc", ] +[[package]] +name = "error-code" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" +dependencies = [ + "libc", + "str-buf", +] + +[[package]] +name = "euclid" +version = "0.22.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b52c2ef4a78da0ba68fbe1fd920627411096d2ac478f7f4c9f3a54ba6705bade" +dependencies = [ + "num-traits", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "exr" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8af5ef47e2ed89d23d0ecbc1b681b30390069de70260937877514377fc24feb" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "smallvec", + "threadpool", + "zune-inflate", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "filetime" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.45.0", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "futures-core" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" + +[[package]] +name = "futures-io" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-sink" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gilrs" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d0342acdc7b591d171212e17c9350ca02383b86d5f9af33c6e3598e03a6c57e" +dependencies = [ + "fnv", + "gilrs-core", + "log", + "uuid", + "vec_map", +] + +[[package]] +name = "gilrs-core" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6789d356476c3280a4e15365d23f62b4b4f1bcdac81fdd552f65807bce4666dd" +dependencies = [ + "core-foundation", + "io-kit-sys", + "js-sys", + "libc", + "libudev-sys", + "log", + "nix 0.25.1", + "uuid", + "vec_map", + "wasm-bindgen", + "web-sys", + "windows 0.43.0", +] + +[[package]] +name = "glam" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774" +dependencies = [ + "bytemuck", + "serde", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "glow" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8bd5877156a19b8ac83a29b2306fe20537429d318f3ff0a1a2119f8d9c61919" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gltf" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd7703af6975def3b32573c60aaa5ebfebfab5d879da1e1315d87155ba57bcd" +dependencies = [ + "byteorder", + "gltf-json", + "lazy_static", + "urlencoding", +] + [[package]] name = "gltf-derive" version = "1.1.0" @@ -203,6 +1891,66 @@ dependencies = [ "serde_json", ] +[[package]] +name = "glyph_brush_layout" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc32c2334f00ca5ac3695c5009ae35da21da8c62d255b5b96d56e2597a637a38" +dependencies = [ + "ab_glyph", + "approx", + "xi-unicode", +] + +[[package]] +name = "gpu-alloc" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc59e5f710e310e76e6707f86c561dd646f69a8876da9131703b2f717de818d" +dependencies = [ + "bitflags", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" +dependencies = [ + "bitflags", +] + +[[package]] +name = "gpu-descriptor" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0c02e1ba0bdb14e965058ca34e09c020f8e507a760df1121728e0aef68d57a" +dependencies = [ + "bitflags", + "gpu-descriptor-types", + "hashbrown", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" +dependencies = [ + "bitflags", +] + +[[package]] +name = "guillotiere" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" +dependencies = [ + "euclid", + "svg_fmt", +] + [[package]] name = "half" version = "2.2.1" @@ -212,24 +1960,172 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59d2aba832b60be25c1b169146b27c64115470981b128ed84c8db18c1b03c6ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", + "serde", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hexasphere" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619ce654558681d7d0a7809e1b20249c7032ff13ee6baa7bb7ff64f7f28a906a" +dependencies = [ + "glam", + "once_cell", +] + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "inflections" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "io-kit-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7789f7f3c9686f96164f5109d69152de759e76e284f736bd57661c6df5091919" +dependencies = [ + "core-foundation-sys", + "mach", +] + [[package]] name = "io-lifetimes" version = "1.0.5" @@ -237,7 +2133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -246,10 +2142,10 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -258,18 +2154,169 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[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.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "kqueue" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" +dependencies = [ + "bitflags", + "libc", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "lewton" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777b48df9aaab155475a83a7df3070395ea1ac6902f5cd062b8f2b028075c030" +dependencies = [ + "byteorder", + "ogg", + "tinyvec", +] + [[package]] name = "libc" version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "linux-raw-sys" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.17" @@ -279,6 +2326,33 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "memchr" version = "2.5.0" @@ -287,13 +2361,306 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "2af2c65375e552a67fe3829ca63e8a7c27a378a62824594f43b2851d682b5ec2" dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metal" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de11355d1f6781482d027a3b4d4de7825dcedb197bf573e0596d00008402d060" +dependencies = [ + "bitflags", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.45.0", +] + +[[package]] +name = "naga" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707" +dependencies = [ + "bit-set", + "bitflags", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "petgraph", + "pp-rs", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ndk" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys 0.3.0", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys 0.4.1+23.1.7779620", + "num_enum", + "raw-window-handle 0.5.0", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-glue" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0434fabdd2c15e0aab768ca31d5b7b333717f03cf02037d5a0a3ff3c278ed67f" +dependencies = [ + "android_logger", + "libc", + "log", + "ndk 0.7.0", + "ndk-context", + "ndk-macro", + "ndk-sys 0.4.1+23.1.7779620", + "once_cell", + "parking_lot", +] + +[[package]] +name = "ndk-macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" +dependencies = [ + "darling", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom8" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" +dependencies = [ + "memchr", +] + +[[package]] +name = "notify" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ea850aa68a06e48fdb069c0ec44d0d64c8dbffa49bf3b6f7f0a901fdea1ba9" +dependencies = [ + "bitflags", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "mio", + "walkdir", + "windows-sys 0.42.0", +] + +[[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-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -303,12 +2670,249 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0072973714303aa6e3631c7e8e777970cf4bdd25dc4932e41031027b8bcc4e" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0629cbd6b897944899b1f10496d9c4a7ac5878d45fd61bc22e9e79bfbbc29597" +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-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "oboe" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f63c358b4fa0fbcfefd7c8be5cfc39c08ce2389f5325687e7762a48d30a5c1" +dependencies = [ + "jni 0.19.0", + "ndk 0.6.0", + "ndk-context", + "num-derive", + "num-traits", + "oboe-sys", +] + +[[package]] +name = "oboe-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3370abb7372ed744232c12954d920d1a40f1c4686de9e79e800021ef492294bd" +dependencies = [ + "cc", +] + +[[package]] +name = "ogg" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6951b4e8bf21c8193da321bcce9c9dd2e13c858fe078bf9054a288b419ae5d6e" +dependencies = [ + "byteorder", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[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.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25e9fb15717794fae58ab55c26e044103aad13186fbb625893f9a3bbcc24228" +dependencies = [ + "ttf-parser", +] + [[package]] name = "owo-colors" version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "pp-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.51" @@ -318,6 +2922,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74605f360ce573babfe43964cbe520294dcb081afbf8c108fc6e23036b4da2df" + [[package]] name = "quote" version = "1.0.23" @@ -327,6 +2937,84 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radsort" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17fd96390ed3feda12e1dfe2645ed587e0bea749e319333f104a33ff62f77a0b" + +[[package]] +name = "range-alloc" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" + +[[package]] +name = "raw-window-handle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" +dependencies = [ + "cty", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a" +dependencies = [ + "cty", +] + +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "rectangle-pack" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d463f2884048e7153449a55166f91028d5b0ea53c79377099ce4e8cf0cf9bb" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + [[package]] name = "regex" version = "1.7.1" @@ -338,12 +3026,41 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "renderdoc-sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" + +[[package]] +name = "retrolib" +version = "0.1.0" +dependencies = [ + "anyhow", + "binrw", + "binrw_derive", + "ddsfile", + "log", + "memmap2", + "tegra_swizzle", + "uuid", +] + [[package]] name = "retrotool" version = "0.1.0" @@ -358,11 +3075,66 @@ dependencies = [ "half", "log", "memmap2", + "retrolib", "serde_json", "tegra_swizzle", "uuid", ] +[[package]] +name = "retrotool-gui" +version = "0.1.0" +dependencies = [ + "anyhow", + "astc-decode", + "bevy", + "bevy_egui", + "binrw", + "egui", + "egui_dock", + "image", + "log", + "retrolib", + "uuid", + "walkdir", +] + +[[package]] +name = "rodio" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb10b653d5ec0e9411a2e7d46e2c7f4046fd87d35b9955bd73ba4108d69072b5" +dependencies = [ + "cpal", + "lewton", +] + +[[package]] +name = "ron" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300a51053b1cb55c80b7a9fde4120726ddf25ca241a1cbb926626f62fb136bff" +dependencies = [ + "base64", + "bitflags", + "serde", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.36.8" @@ -374,7 +3146,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -383,11 +3155,50 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +[[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_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_derive" @@ -411,6 +3222,161 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "simd-adler32" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14a5df39617d7c8558154693a1bb8157a4aab8179209540cc0b10e5dc24e0b18" + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +dependencies = [ + "serde", +] + +[[package]] +name = "spin" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spirv" +version = "0.2.0+1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" +dependencies = [ + "bitflags", + "num-traits", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + +[[package]] +name = "str-buf" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "svg_fmt" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2" + [[package]] name = "syn" version = "1.0.107" @@ -422,6 +3388,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "taffy" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec27dea659b100d489dffa57cf0efc6d7bfefb119af817b92cc14006c0b214e3" +dependencies = [ + "arrayvec", + "hash32", + "hash32-derive", + "num-traits", + "typenum", +] + [[package]] name = "tegra_swizzle" version = "0.3.0" @@ -437,17 +3416,475 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" + +[[package]] +name = "toml_edit" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" +dependencies = [ + "indexmap", + "nom8", + "toml_datetime", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + +[[package]] +name = "ttf-parser" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0609f771ad9c6155384897e1df4d948e692667cc0588548b68eb44d052b27633" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" + [[package]] name = "unicode-ident" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "urlencoding" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" + [[package]] name = "uuid" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "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.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d1fa1e5c829b2bf9eb1e28fb950248b797cd6a04866fbdfa8bc31e5eef4c78" +dependencies = [ + "core-foundation", + "dirs", + "jni 0.20.0", + "log", + "ndk-context", + "objc", + "raw-window-handle 0.5.0", + "url", + "web-sys", +] + +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + +[[package]] +name = "wgpu" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f643110d228fd62a60c5ed2ab56c4d5b3704520bd50561174ec4ec74932937" +dependencies = [ + "arrayvec", + "js-sys", + "log", + "naga", + "parking_lot", + "raw-window-handle 0.5.0", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6000d1284ef8eec6076fd5544a73125fd7eb9b635f18dceeb829d826f41724ca" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags", + "cfg_aliases", + "codespan-reporting", + "fxhash", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle 0.5.0", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cc320a61acb26be4f549c9b1b53405c10a223fbfea363ec39474c32c348d12f" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags", + "block", + "core-graphics-types", + "d3d12", + "foreign-types", + "fxhash", + "glow", + "gpu-alloc", + "gpu-descriptor", + "js-sys", + "khronos-egl", + "libloading", + "log", + "metal", + "naga", + "objc", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle 0.5.0", + "renderdoc-sys", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb6b28ef22cac17b9109b25b3bf8c9a103eeb293d7c5f78653979b09140375f6" +dependencies = [ + "bitflags", +] [[package]] name = "winapi" @@ -474,12 +3911,77 @@ dependencies = [ "winapi", ] +[[package]] +name = "winapi-wsapoll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" +dependencies = [ + "windows_aarch64_msvc 0.37.0", + "windows_i686_gnu 0.37.0", + "windows_i686_msvc 0.37.0", + "windows_x86_64_gnu 0.37.0", + "windows_x86_64_msvc 0.37.0", +] + +[[package]] +name = "windows" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -496,12 +3998,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_x86_64_msvc 0.42.1", ] [[package]] @@ -510,24 +4012,72 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" + [[package]] name = "windows_aarch64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_gnu" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" + [[package]] name = "windows_i686_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_i686_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" + [[package]] name = "windows_i686_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" + [[package]] name = "windows_x86_64_gnu" version = "0.42.1" @@ -540,8 +4090,97 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" + [[package]] name = "windows_x86_64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + +[[package]] +name = "winit" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" +dependencies = [ + "bitflags", + "cocoa", + "core-foundation", + "core-graphics", + "dispatch", + "instant", + "libc", + "log", + "mio", + "ndk 0.7.0", + "ndk-glue", + "objc", + "once_cell", + "parking_lot", + "percent-encoding", + "raw-window-handle 0.4.3", + "raw-window-handle 0.5.0", + "wasm-bindgen", + "web-sys", + "windows-sys 0.36.1", + "x11-dl", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" +dependencies = [ + "gethostname", + "nix 0.24.3", + "winapi", + "winapi-wsapoll", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +dependencies = [ + "nix 0.24.3", +] + +[[package]] +name = "xi-unicode" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" + +[[package]] +name = "zune-inflate" +version = "0.2.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589245df6230839c305984dcc0a8385cc72af1fd223f360ffd5d65efa4216d40" +dependencies = [ + "simd-adler32", +] diff --git a/Cargo.toml b/Cargo.toml index a9980e4..eeeef62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,33 +1,19 @@ -[package] -name = "retrotool" -description = "Tools for working with Retro game formats." -authors = ["Luke Street "] -license = "MIT OR Apache-2.0" -version = "0.1.0" -edition = "2021" -publish = false -repository = "https://github.com/PrimeDecomp/retrotool" -readme = "README.md" -categories = ["command-line-utilities"] +[workspace] +members = [ + "lib", + "retrotool", + "retrotool-gui", +] +resolver = "2" [profile.release] lto = "thin" panic = "abort" strip = "debuginfo" -[dependencies] -anyhow = "1.0.69" -argh = "0.1.10" -# astc-decode = "0.3.1" -binrw = "0.11.1" -binrw_derive = "0.11.1" -ddsfile = { git = "https://github.com/encounter/ddsfile", rev = "880f04c1dffa680eab0e9e09cfa58591fe186a31" } -env_logger = "0.10.0" -gltf-json = { version = "1.1.0", features = ["names", "extras"] } -half = "2.2.1" -# image = "0.24.5" -log = "0.4.17" -memmap2 = "0.5.8" -serde_json = "1.0.93" -tegra_swizzle = "0.3.0" -uuid = "1.3.0" +[profile.dev.package] +bevy = { opt-level = 3 } +egui = { opt-level = 3 } +naga = { opt-level = 3 } +wgpu = { opt-level = 3 } +winit = { opt-level = 3 } diff --git a/lib/Cargo.toml b/lib/Cargo.toml new file mode 100644 index 0000000..546caa9 --- /dev/null +++ b/lib/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "retrolib" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.69" +binrw = "0.11.1" +binrw_derive = "0.11.1" +ddsfile = { git = "https://github.com/encounter/ddsfile", rev = "880f04c1dffa680eab0e9e09cfa58591fe186a31" } +log = "0.4.17" +memmap2 = "0.5.9" +tegra_swizzle = "0.3.0" +uuid = "1.3.0" diff --git a/src/format/chunk.rs b/lib/src/format/chunk.rs similarity index 100% rename from src/format/chunk.rs rename to lib/src/format/chunk.rs diff --git a/lib/src/format/cmdl.rs b/lib/src/format/cmdl.rs new file mode 100644 index 0000000..295be20 --- /dev/null +++ b/lib/src/format/cmdl.rs @@ -0,0 +1,820 @@ +use std::{borrow::Cow, io::Cursor}; + +use anyhow::{bail, ensure, Result}; +use binrw::{binrw, BinReaderExt, Endian}; +use uuid::Uuid; + +use crate::{ + format::{ + chunk::ChunkDescriptor, rfrm::FormDescriptor, CAABox, CColor4f, CMatrix4f, + CStringFixedName, CVector4i, FourCC, + }, + util::compression::decompress_buffer, +}; + +// Cooked model +pub const K_FORM_CMDL: FourCC = FourCC(*b"CMDL"); + +// Model header +pub const K_CHUNK_HEAD: FourCC = FourCC(*b"HEAD"); +// Material data +pub const K_CHUNK_MTRL: FourCC = FourCC(*b"MTRL"); +// Mesh data +pub const K_CHUNK_MESH: FourCC = FourCC(*b"MESH"); +// Vertex buffer +pub const K_CHUNK_VBUF: FourCC = FourCC(*b"VBUF"); +// Index buffer +pub const K_CHUNK_IBUF: FourCC = FourCC(*b"IBUF"); +// GPU data +pub const K_CHUNK_GPU: FourCC = FourCC(*b"GPU "); + +#[binrw] +#[derive(Clone, Debug)] +pub struct SModelReadBufferInfo { + pub size: u32, + pub offset: u32, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SModelBufferInfo { + pub read_index: u32, + pub offset: u32, + pub size: u32, + pub dest_size: u32, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SModelMetaData { + pub unk: u32, + pub gpu_offset: u32, + #[bw(try_calc = read_info.len().try_into())] + pub read_info_count: u32, + #[br(count = read_info_count)] + pub read_info: Vec, + #[bw(try_calc = vtx_buffer_info.len().try_into())] + pub vtx_buffer_count: u32, + #[br(count = vtx_buffer_count)] + pub vtx_buffer_info: Vec, + #[bw(try_calc = idx_buffer_info.len().try_into())] + pub idx_info_count: u32, + #[br(count = idx_info_count)] + pub idx_buffer_info: Vec, +} + +#[binrw] +#[repr(u32)] +#[brw(repr(u32))] +#[derive(Copy, Clone, Debug)] +pub enum EBufferType { + U8 = 0, // ? + U16 = 1, + U32 = 2, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SIndexBufferInfoSection { + #[bw(try_calc = info.len().try_into())] + pub count: u32, + #[br(count = count)] + pub info: Vec, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SVertexBufferInfoSection { + #[bw(try_calc = info.len().try_into())] + pub count: u32, + #[br(count = count)] + pub info: Vec, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SVertexBufferInfo { + pub vertex_count: u32, + #[bw(try_calc = components.len().try_into())] + pub component_count: u32, + #[br(count = component_count)] + pub components: Vec, + pub unk: u8, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SVertexDataComponent { + pub buffer_index: u32, + pub offset: u32, + pub stride: u32, + pub format: EVertexDataFormat, + pub component: EVertexComponent, +} + +#[binrw] +#[repr(u32)] +#[brw(repr(u32))] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum EVertexDataFormat { + Unknown = u32::MAX, + R8Unorm = 0, + R8Uint = 1, + R8Snorm = 2, + R8Sint = 3, + R16Unorm = 4, + R16Uint = 5, + R16Snorm = 6, + R16Sint = 7, + R16Float = 8, + Rg8Unorm = 9, + Rg8Uint = 10, + Rg8Snorm = 11, + Rg8Sint = 12, + R32Uint = 13, + R32Sint = 14, + R32Float = 15, + Rg16Unorm = 16, + Rg16Uint = 17, + Rg16Snorm = 18, + Rg16Sint = 19, + Rg16Float = 20, + Rgba8Unorm = 21, + Rgba8Uint = 22, + Rgba8Snorm = 23, + Rgba8Sint = 24, + Rgb10a2Unorm = 25, + Rgb10a2Uint = 26, + Rg32Uint = 27, + Rg32Sint = 28, + Rg32Float = 29, + Rgba16Unorm = 30, + Rgba16Uint = 31, + Rgba16Snorm = 32, + Rgba16Sint = 33, + Rgba16Float = 34, + Rgb32Uint = 35, + Rgb32Sint = 36, + Rgb32Float = 37, + Rgba32Uint = 38, + Rgba32Sint = 39, + Rgba32Float = 40, +} + +impl EVertexDataFormat { + pub fn byte_size(self) -> u32 { + match self { + EVertexDataFormat::Unknown => 0, + EVertexDataFormat::R8Unorm => 1, + EVertexDataFormat::R8Uint => 1, + EVertexDataFormat::R8Snorm => 1, + EVertexDataFormat::R8Sint => 1, + EVertexDataFormat::R16Unorm => 2, + EVertexDataFormat::R16Uint => 2, + EVertexDataFormat::R16Snorm => 2, + EVertexDataFormat::R16Sint => 2, + EVertexDataFormat::R16Float => 2, + EVertexDataFormat::Rg8Unorm => 2, + EVertexDataFormat::Rg8Uint => 2, + EVertexDataFormat::Rg8Snorm => 2, + EVertexDataFormat::Rg8Sint => 2, + EVertexDataFormat::R32Uint => 4, + EVertexDataFormat::R32Sint => 4, + EVertexDataFormat::R32Float => 4, + EVertexDataFormat::Rg16Unorm => 4, + EVertexDataFormat::Rg16Uint => 4, + EVertexDataFormat::Rg16Snorm => 4, + EVertexDataFormat::Rg16Sint => 4, + EVertexDataFormat::Rg16Float => 4, + EVertexDataFormat::Rgba8Unorm => 4, + EVertexDataFormat::Rgba8Uint => 4, + EVertexDataFormat::Rgba8Snorm => 4, + EVertexDataFormat::Rgba8Sint => 4, + EVertexDataFormat::Rgb10a2Unorm => 4, + EVertexDataFormat::Rgb10a2Uint => 4, + EVertexDataFormat::Rg32Uint => 8, + EVertexDataFormat::Rg32Sint => 8, + EVertexDataFormat::Rg32Float => 8, + EVertexDataFormat::Rgba16Unorm => 8, + EVertexDataFormat::Rgba16Uint => 8, + EVertexDataFormat::Rgba16Snorm => 8, + EVertexDataFormat::Rgba16Sint => 8, + EVertexDataFormat::Rgba16Float => 8, + EVertexDataFormat::Rgb32Uint => 12, + EVertexDataFormat::Rgb32Sint => 12, + EVertexDataFormat::Rgb32Float => 12, + EVertexDataFormat::Rgba32Uint => 16, + EVertexDataFormat::Rgba32Sint => 16, + EVertexDataFormat::Rgba32Float => 16, + } + } + + pub fn normalized(self) -> bool { + matches!( + self, + EVertexDataFormat::R8Unorm + | EVertexDataFormat::R8Snorm + | EVertexDataFormat::R16Unorm + | EVertexDataFormat::R16Snorm + | EVertexDataFormat::Rg8Unorm + | EVertexDataFormat::Rg8Snorm + | EVertexDataFormat::Rg16Unorm + | EVertexDataFormat::Rg16Snorm + | EVertexDataFormat::Rgba8Unorm + | EVertexDataFormat::Rgba8Snorm + | EVertexDataFormat::Rgb10a2Unorm + | EVertexDataFormat::Rgba16Unorm + | EVertexDataFormat::Rgba16Snorm + ) + } +} + +#[binrw] +#[repr(u32)] +#[brw(repr(u32))] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum EVertexComponent { + Position = 0, // in_position + Normal = 1, // in_normal + Tangent0 = 2, // in_tangent[0] + Tangent1 = 3, // in_tangent[1] + Tangent2 = 4, // in_tangent[2] + TexCoord0 = 5, // in_texCoord[0] + TexCoord1 = 6, // in_texCoord[1] + TexCoord2 = 7, // in_texCoord[2] + TexCoord3 = 8, // in_texCoord[3] + Color = 9, // in_color + BoneIndices = 10, // in_boneIndices + BoneWeights = 11, // in_boneWeights + BakedLightingCoord = 12, // in_bakedLightingCoord + BakedLightingTangent = 13, // in_bakedLightingTangent + VertInstanceParams = 14, // in_vertInstanceParams + VertInstanceColor = 15, // in_vertInstanceColor + VertTransform0 = 16, // in_vertTransform[0] + VertTransform1 = 17, // in_vertTransform[1] + VertTransform2 = 18, // in_vertTransform[2] + CurrentPosition = 19, // in_currentPosition + VertInstanceOpacityParams = 20, // in_vertInstanceOpacityParams + VertInstanceColorIndexingParams = 21, // in_vertInstanceColorIndexingParams + VertInstanceOpacityIndexingParams = 22, // in_vertInstanceOpacityIndexingParams + VertInstancePaintParams = 23, // in_vertInstancePaintParams + BakedLightingLookup = 24, // in_bakedLightingLookup + MaterialChoice0 = 25, // in_materialChoice[0] + MaterialChoice1 = 26, // in_materialChoice[1] + MaterialChoice2 = 27, // in_materialChoice[2] + MaterialChoice3 = 28, // in_materialChoice[3] +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SMeshLoadInformation { + #[bw(try_calc = meshes.len().try_into())] + pub mesh_count: u32, + #[br(count = mesh_count)] + pub meshes: Vec, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CRenderMesh { + pub material_idx: u16, + pub vtx_buf_idx: u8, + pub idx_buf_idx: u8, + pub index_start: u32, + pub index_count: u32, + pub unk_c: u16, + pub unk_e: u16, // 64 +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SModelHeader { + pub unk: u32, + pub bounds: CAABox, + // TODO +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SMaterialChunk { + pub unk: u32, + #[bw(try_calc = materials.len().try_into())] + pub material_count: u32, + #[br(count = material_count)] + pub materials: Vec, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CMaterialCache { + #[br(try_map = CStringFixedName::into_string)] + #[bw(map = CStringFixedName::from_string)] + pub name: String, + #[br(map = Uuid::from_bytes_le)] + #[bw(map = Uuid::to_bytes_le)] + pub shader_id: Uuid, + #[br(map = Uuid::from_bytes_le)] + #[bw(map = Uuid::to_bytes_le)] + pub unk_guid: Uuid, + pub unk1: u32, + pub unk2: u32, + #[bw(try_calc = types.len().try_into())] + pub type_count: u32, + #[br(count = type_count)] + pub types: Vec, + #[bw(try_calc = render_types.len().try_into())] + pub render_type_count: u32, + #[br(count = render_type_count)] + pub render_types: Vec, + #[bw(try_calc = data_types.len().try_into())] + pub data_count: u32, + #[br(count = data_count)] + pub data_types: Vec, + #[br(count = data_count)] + pub data: Vec, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SMaterialRenderTypes { + pub data_id: FourCC, + pub data_type: FourCC, + pub flag1: u8, + pub flag2: u8, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct SMaterialType { + pub data_id: EMaterialDataId, + pub data_type: EMaterialDataType, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CMaterialData { + pub data_id: EMaterialDataId, + pub data_type: EMaterialDataType, + #[br(args { id: data_id, ty: data_type })] + pub data: CMaterialDataInner, +} + +#[binrw] +#[br(import { id: EMaterialDataId, ty: EMaterialDataType })] +#[derive(Clone, Debug)] +pub enum CMaterialDataInner { + #[br(pre_assert(ty == EMaterialDataType::Texture))] + Texture(CMaterialTextureTokenData), + #[br(pre_assert(ty == EMaterialDataType::Color))] + Color(CColor4f), + #[br(pre_assert(ty == EMaterialDataType::Scalar))] + Scalar(f32), + #[br(pre_assert(ty == EMaterialDataType::Int1))] + Int1(i32), + #[br(pre_assert(ty == EMaterialDataType::Int4))] + Int4(CVector4i), + #[br(pre_assert(ty == EMaterialDataType::Mat4))] + Mat4(CMatrix4f), + #[br(pre_assert(ty == EMaterialDataType::Complex && id.is_texture_layered()))] + LayeredTexture(CLayeredTextureData), +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CMaterialTextureTokenData { + #[br(map = Uuid::from_bytes_le)] + #[bw(map = Uuid::to_bytes_le)] + pub id: Uuid, + #[br(if(!id.is_nil()))] + pub usage: Option, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CLayeredTextureBaseData { + pub unk: u32, + pub colors: [CColor4f; 3], + pub flags: u8, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CLayeredTextureData { + pub base: CLayeredTextureBaseData, + pub textures: [CMaterialTextureTokenData; 3], +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct STextureUsageInfo { + pub flags: u32, + pub filter: u32, + pub wrap_x: u32, + pub wrap_y: u32, + pub wrap_z: u32, +} + +#[binrw] +#[repr(u32)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum EMaterialDataType { + #[brw(magic(b"TXTR"))] + Texture = 1, + #[brw(magic(b"COLR"))] + Color = 2, + #[brw(magic(b"SCLR"))] + Scalar = 3, + #[brw(magic(b"INT1"))] + Int1 = 4, + #[brw(magic(b"CPLX"))] + Complex = 5, + #[brw(magic(b"INT4"))] + Int4 = 6, + #[brw(magic(b"MAT4"))] + Mat4 = 7, +} + +#[binrw] +#[repr(u32)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[allow(clippy::upper_case_acronyms)] +pub enum EMaterialDataId { + // TXTR data IDs + #[brw(magic(b"CBUF"))] + CBUF = 1, + #[brw(magic(b"ZBUF"))] + ZBUF = 2, + #[brw(magic(b"GBUF"))] + GBUF = 3, + #[brw(magic(b"GFLG"))] + GFLG = 4, + #[brw(magic(b"OPCT"))] + OPCT = 5, + #[brw(magic(b"DIFT"))] + DIFT = 6, + #[brw(magic(b"ICAN"))] + ICAN = 7, + #[brw(magic(b"SINC"))] + SINC = 8, + #[brw(magic(b"NMAP"))] + NMAP = 9, + #[brw(magic(b"MNMP"))] + MNMP = 10, + #[brw(magic(b"REFL"))] + REFL = 11, + #[brw(magic(b"REFS"))] + REFS = 12, + #[brw(magic(b"REFV"))] + REFV = 13, + #[brw(magic(b"SPCT"))] + SPCT = 14, + #[brw(magic(b"LIBD"))] + LIBD = 15, + #[brw(magic(b"LIBS"))] + LIBS = 16, + #[brw(magic(b"FOGR"))] + FOGR = 17, + #[brw(magic(b"INDI"))] + INDI = 18, + #[brw(magic(b"OTMP"))] + OTMP = 19, + #[brw(magic(b"CGMP"))] + CGMP = 20, + #[brw(magic(b"OGMP"))] + OGMP = 21, + #[brw(magic(b"VAND"))] + VAND = 22, + #[brw(magic(b"BLAT"))] + BLAT = 23, + #[brw(magic(b"BCLR"))] + BCLR = 24, + #[brw(magic(b"METL"))] + METL = 25, + #[brw(magic(b"TCH0"))] + TCH0 = 26, + #[brw(magic(b"TCH1"))] + TCH1 = 27, + #[brw(magic(b"TCH2"))] + TCH2 = 28, + #[brw(magic(b"TCH3"))] + TCH3 = 29, + #[brw(magic(b"TCH4"))] + TCH4 = 30, + #[brw(magic(b"TCH5"))] + TCH5 = 31, + // COLR data IDs + #[brw(magic(b"DIFC"))] + DIFC = 32, + #[brw(magic(b"SHRC"))] + SHRC = 33, + #[brw(magic(b"SPCC"))] + SPCC = 34, + #[brw(magic(b"ICNC"))] + ICNC = 35, + #[brw(magic(b"ICMC"))] + ICMC = 36, + #[brw(magic(b"ODAT"))] + ODAT = 37, + #[brw(magic(b"MDCI"))] + MDCI = 38, + #[brw(magic(b"MDOI"))] + MDOI = 39, + #[brw(magic(b"LODC"))] + LODC = 40, + #[brw(magic(b"LODP"))] + LODP = 41, + #[brw(magic(b"VANP"))] + VANP = 42, + #[brw(magic(b"BLAL"))] + BLAL = 43, + #[brw(magic(b"BLCM"))] + BLCM = 44, + #[brw(magic(b"INDP"))] + INDP = 45, + #[brw(magic(b"PVLO"))] + PVLO = 46, + #[brw(magic(b"PSXT"))] + PSXT = 47, + #[brw(magic(b"PTAI"))] + PTAI = 48, + #[brw(magic(b"PCMD"))] + PCMD = 49, + #[brw(magic(b"BSAO"))] + BSAO = 50, + #[brw(magic(b"CCH0"))] + CCH0 = 51, + #[brw(magic(b"CCH1"))] + CCH1 = 52, + #[brw(magic(b"CCH2"))] + CCH2 = 53, + #[brw(magic(b"CCH3"))] + CCH3 = 54, + #[brw(magic(b"CCH4"))] + CCH4 = 55, + #[brw(magic(b"CCH5"))] + CCH5 = 56, + #[brw(magic(b"CCH6"))] + CCH6 = 57, + #[brw(magic(b"BKLT"))] + BKLT = 58, + #[brw(magic(b"BKLB"))] + BKLB = 59, + #[brw(magic(b"BKLA"))] + BKLA = 60, + #[brw(magic(b"BKGL"))] + BKGL = 61, + #[brw(magic(b"DYIN"))] + DYIN = 62, + #[brw(magic(b"CLP0"))] + CLP0 = 63, + #[brw(magic(b"HOTP"))] + HOTP = 64, + // INT1 data IDs + #[brw(magic(b"SHID"))] + SHID = 65, + #[brw(magic(b"GBFF"))] + GBFF = 66, + #[brw(magic(b"PMOD"))] + PMOD = 67, + #[brw(magic(b"PFLG"))] + PFLG = 68, + #[brw(magic(b"BLPI"))] + BLPI = 69, + #[brw(magic(b"ICH0"))] + ICH0 = 70, + #[brw(magic(b"ICH1"))] + ICH1 = 71, + #[brw(magic(b"ICH2"))] + ICH2 = 72, + // INT4 data IDs + #[brw(magic(b"AUVI"))] + AUVI = 73, + #[brw(magic(b"ECH0"))] + ECH0 = 74, + // SCLR data IDs + #[brw(magic(b"OPCS"))] + OPCS = 75, + #[brw(magic(b"SPCP"))] + SPCP = 76, + #[brw(magic(b"INDS"))] + INDS = 77, + #[brw(magic(b"BLSM"))] + BLSM = 78, + #[brw(magic(b"LITS"))] + LITS = 79, + #[brw(magic(b"MDOE"))] + MDOE = 80, + #[brw(magic(b"VANF"))] + VANF = 81, + #[brw(magic(b"OTHS"))] + OTHS = 82, + #[brw(magic(b"PZSO"))] + PZSO = 83, + #[brw(magic(b"RCH0"))] + RCH0 = 84, + #[brw(magic(b"RCH1"))] + RCH1 = 85, + #[brw(magic(b"RCH2"))] + RCH2 = 86, + // MAT4 data IDs + #[brw(magic(b"PXFM"))] + PXFM = 87, + #[brw(magic(b"MCH0"))] + MCH0 = 88, + // CPLX data IDs + #[brw(magic(b"BCRL"))] + BCRL = 89, // texture_layered + #[brw(magic(b"MTLL"))] + MTLL = 90, // texture_layered + #[brw(magic(b"NRML"))] + NRML = 91, // texture_layered + #[brw(magic(b"SHDD"))] + SHDD = 92, + #[brw(magic(b"SKIN"))] + SKIN = 93, + #[brw(magic(b"DIMD"))] + DIMD = 94, + #[brw(magic(b"LIT "))] + LIT = 95, + #[brw(magic(b"ALLD"))] + ALLD = 96, + #[brw(magic(b"DLLD"))] + DLLD = 97, + #[brw(magic(b"CLLD"))] + CLLD = 98, + #[brw(magic(b"AUXF"))] + AUXF = 99, + #[brw(magic(b"WIND"))] + WIND = 100, + #[brw(magic(b"WATR"))] + WATR = 101, + #[brw(magic(b"DFXS"))] + DFXS = 102, + #[brw(magic(b"DFXN"))] + DFXN = 103, + #[brw(magic(b"MCDD"))] + MCDD = 104, + #[brw(magic(b"CAUS"))] + CAUS = 105, + #[brw(magic(b"BLPD"))] + BLPD = 106, + #[brw(magic(b"BLPT"))] + BLPT = 107, + #[brw(magic(b"FOGS"))] + FOGS = 108, + #[brw(magic(b"VOLF"))] + VOLF = 109, + #[brw(magic(b"VFXB"))] + VFXB = 110, + #[brw(magic(b"VFXD"))] + VFXD = 111, + #[brw(magic(b"REFP"))] + REFP = 112, + #[brw(magic(b"RAIN"))] + RAIN = 113, + #[brw(magic(b"XCH0"))] + XCH0 = 114, + #[brw(magic(b"XCH1"))] + XCH1 = 115, +} + +impl EMaterialDataId { + pub fn is_texture_layered(self) -> bool { + matches!(self, EMaterialDataId::BCRL | EMaterialDataId::MTLL | EMaterialDataId::NRML) + } +} + +#[binrw] +#[repr(u32)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[allow(clippy::upper_case_acronyms)] +pub enum EMaterialFlag { + #[brw(magic(b"MFTR"))] + MFTR = 0, + #[brw(magic(b"MFMT"))] + MFMT = 1, + #[brw(magic(b"MFSR"))] + MFSR = 2, + #[brw(magic(b"MFSK"))] + MFSK = 3, + #[brw(magic(b"MFVC"))] + MFVC = 4, + #[brw(magic(b"MF1B"))] + MF1B = 5, + #[brw(magic(b"MFAV"))] + MFAV = 6, + #[brw(magic(b"MFIN"))] + MFIN = 7, + #[brw(magic(b"MFCA"))] + MFCA = 8, + #[brw(magic(b"MFIM"))] + MFIM = 9, + #[brw(magic(b"MTSM"))] + MTSM = 10, + #[brw(magic(b"MFRL"))] + MFRL = 11, + #[brw(magic(b"MFOE"))] + MFOE = 12, + #[brw(magic(b"MFOT"))] + MFOT = 13, + #[brw(magic(b"MFCI"))] + MFCI = 14, + #[brw(magic(b"MFOI"))] + MFOI = 15, + #[brw(magic(b"MFVA"))] + MFVA = 16, + #[brw(magic(b"MFSU"))] + MFSU = 17, + #[brw(magic(b"MFBP"))] + MFBP = 18, + #[brw(magic(b"MFBL"))] + MFBL = 19, + #[brw(magic(b"MFLB"))] + MFLB = 20, + #[brw(magic(b"MF1E"))] + MF1E = 21, + #[brw(magic(b"MFC0"))] + MFC0 = 22, + #[brw(magic(b"MFC1"))] + MFC1 = 23, + #[brw(magic(b"MFC2"))] + MFC2 = 24, + #[brw(magic(b"MFC3"))] + MFC3 = 25, + #[brw(magic(b"MFC4"))] + MFC4 = 26, +} + +fn decompress_gpu_buffers<'a>( + file_data: &'a [u8], + read_info: &[SModelReadBufferInfo], + buffer_info: &[SModelBufferInfo], +) -> Result>> { + let mut out = Vec::with_capacity(buffer_info.len()); + for info in buffer_info { + let read_info = &read_info[info.read_index as usize]; + let read_buffer = + &file_data[read_info.offset as usize..(read_info.offset + read_info.size) as usize]; + let comp_buf = &read_buffer[info.offset as usize..(info.offset + info.size) as usize]; + let (_, buf) = decompress_buffer(comp_buf, info.dest_size as u64)?; + out.push(buf); + } + Ok(out) +} + +pub struct ModelData<'a> { + pub head: SModelHeader, + pub mtrl: SMaterialChunk, + pub mesh: SMeshLoadInformation, + pub vbuf: SVertexBufferInfoSection, + pub ibuf: SIndexBufferInfoSection, + pub vtx_buffers: Vec>, + pub idx_buffers: Vec>, +} + +impl ModelData<'_> { + pub fn slice<'a>(data: &'a [u8], meta: &[u8], e: Endian) -> Result> { + let (cmdl_desc, mut cmdl_data, _) = FormDescriptor::slice(&data, Endian::Little)?; + ensure!(cmdl_desc.id == K_FORM_CMDL); + ensure!(cmdl_desc.version_a == 114); + ensure!(cmdl_desc.version_b == 125); + + let meta: SModelMetaData = Cursor::new(meta).read_type(e)?; + let vtx_buffers = decompress_gpu_buffers(data, &meta.read_info, &meta.vtx_buffer_info)?; + let idx_buffers = decompress_gpu_buffers(data, &meta.read_info, &meta.idx_buffer_info)?; + + let mut head: Option = None; + let mut mtrl: Option = None; + let mut mesh: Option = None; + let mut vbuf: Option = None; + let mut ibuf: Option = None; + while !cmdl_data.is_empty() { + let (chunk_desc, chunk_data, remain) = ChunkDescriptor::slice(cmdl_data, e)?; + match chunk_desc.id { + K_CHUNK_HEAD => head = Some(Cursor::new(chunk_data).read_type(e)?), + K_CHUNK_MTRL => mtrl = Some(Cursor::new(chunk_data).read_type(e)?), + K_CHUNK_MESH => mesh = Some(Cursor::new(chunk_data).read_type(e)?), + K_CHUNK_VBUF => vbuf = Some(Cursor::new(chunk_data).read_type(e)?), + K_CHUNK_IBUF => ibuf = Some(Cursor::new(chunk_data).read_type(e)?), + // GPU data decompressed via META + K_CHUNK_GPU => {} + id => bail!("Unknown model chunk ID {id:?}"), + } + cmdl_data = remain; + } + + let Some(head) = head else { bail!("Failed to locate HEAD") }; + let Some(mtrl) = mtrl else { bail!("Failed to locate MTRL") }; + let Some(mesh) = mesh else { bail!("Failed to locate MESH") }; + let Some(vbuf) = vbuf else { bail!("Failed to locate VBUF") }; + let Some(ibuf) = ibuf else { bail!("Failed to locate IBUF") }; + + // log::debug!("HEAD: {head:#?}"); + // log::debug!("MTRL: {mtrl:#?}"); + // log::debug!("MESH: {mesh:#?}"); + // log::debug!("VBUF: {vbuf:#?}"); + // log::debug!("IBUF: {ibuf:#?}"); + + Ok(ModelData { head, mtrl, mesh, vbuf, ibuf, vtx_buffers, idx_buffers }) + } +} diff --git a/lib/src/format/foot.rs b/lib/src/format/foot.rs new file mode 100644 index 0000000..44fd72d --- /dev/null +++ b/lib/src/format/foot.rs @@ -0,0 +1,30 @@ +use anyhow::{anyhow, ensure, Result}; +use binrw::Endian; + +use crate::format::{chunk::ChunkDescriptor, pack::K_CHUNK_META, rfrm::FormDescriptor, FourCC}; + +// Custom footer for extracted files +pub const K_FORM_FOOT: FourCC = FourCC(*b"FOOT"); +// Custom footer asset information +pub const K_CHUNK_AINF: FourCC = FourCC(*b"AINF"); +// Custom footer asset name +pub const K_CHUNK_NAME: FourCC = FourCC(*b"NAME"); + +/// Locate the meta section in extracted files +pub fn locate_meta(file_data: &[u8], e: Endian) -> Result<&[u8]> { + let (_, _, remain) = FormDescriptor::slice(file_data, e)?; + let (foot_desc, mut foot_data, remain) = FormDescriptor::slice(remain, Endian::Little)?; + ensure!(foot_desc.id == K_FORM_FOOT); + ensure!(foot_desc.version_a == 1); + ensure!(foot_desc.version_b == 1); + ensure!(remain.is_empty()); + + while !foot_data.is_empty() { + let (desc, data, remain) = ChunkDescriptor::slice(foot_data, e)?; + if desc.id == K_CHUNK_META { + return Ok(data); + } + foot_data = remain; + } + Err(anyhow!("Failed to locate META chunk")) +} diff --git a/src/format/mod.rs b/lib/src/format/mod.rs similarity index 51% rename from src/format/mod.rs rename to lib/src/format/mod.rs index f2e1cda..d1ef79d 100644 --- a/src/format/mod.rs +++ b/lib/src/format/mod.rs @@ -1,9 +1,14 @@ pub mod chunk; +pub mod cmdl; +pub mod foot; pub mod pack; pub mod rfrm; pub mod txtr; -use std::fmt::{Debug, Display, Formatter, Write}; +use std::{ + fmt::{Debug, Display, Formatter, Write}, + string::FromUtf8Error, +}; use binrw::binrw; @@ -54,3 +59,60 @@ impl PartialEq<[u8; 4]> for FourCC { #[inline] pub fn peek_four_cc(data: &[u8]) -> FourCC { FourCC(*array_ref!(data, 0, 4)) } + +#[binrw] +#[derive(Clone, Debug)] +pub struct CVector3f { + pub x: f32, + pub y: f32, + pub z: f32, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CColor4f { + pub r: f32, + pub g: f32, + pub b: f32, + pub a: f32, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CVector4i { + pub x: i32, + pub y: i32, + pub z: i32, + pub w: i32, +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CMatrix4f { + pub m: [f32; 16], +} + +#[binrw] +#[derive(Clone, Debug)] +pub struct CAABox { + pub min: CVector3f, + pub max: CVector3f, +} + +#[binrw] +#[derive(Clone, Debug, Default)] +pub struct CStringFixedName { + #[bw(try_calc = text.len().try_into())] + pub size: u32, + #[br(count = size)] + pub text: Vec, +} + +impl CStringFixedName { + fn from_string(str: &String) -> Self { + #[allow(clippy::needless_update)] + Self { text: str.as_bytes().to_vec(), ..Default::default() } + } + + fn into_string(self) -> Result { String::from_utf8(self.text) } +} diff --git a/src/format/pack.rs b/lib/src/format/pack.rs similarity index 59% rename from src/format/pack.rs rename to lib/src/format/pack.rs index b3e57f7..a2d3abf 100644 --- a/src/format/pack.rs +++ b/lib/src/format/pack.rs @@ -4,13 +4,18 @@ use std::{ io::{Cursor, Seek, SeekFrom, Write}, }; -use anyhow::{bail, ensure, Result}; +use anyhow::{anyhow, bail, ensure, Result}; use binrw::{binrw, BinReaderExt, BinWriterExt, Endian}; use uuid::Uuid; use crate::{ - format::{chunk::ChunkDescriptor, rfrm::FormDescriptor, FourCC}, - util::lzss::decompress_buffer, + format::{ + chunk::ChunkDescriptor, + foot::{K_CHUNK_AINF, K_CHUNK_NAME, K_FORM_FOOT}, + rfrm::FormDescriptor, + FourCC, + }, + util::compression::decompress_buffer, }; // Package file @@ -24,13 +29,6 @@ pub const K_CHUNK_STRG: FourCC = FourCC(*b"STRG"); // Asset directory pub const K_CHUNK_ADIR: FourCC = FourCC(*b"ADIR"); -// Custom footer for extracted files -pub const K_FORM_FOOT: FourCC = FourCC(*b"FOOT"); -// Custom footer asset information -pub const K_CHUNK_AINF: FourCC = FourCC(*b"AINF"); -// Custom footer asset name -pub const K_CHUNK_NAME: FourCC = FourCC(*b"NAME"); - /// PACK::TOCC::ADIR chunk #[binrw] #[derive(Clone, Debug, Default)] @@ -134,8 +132,201 @@ pub struct Package<'a> { pub assets: Vec>, } +/// Asset header information +#[derive(Debug, Clone)] +pub struct SparsePackageEntry { + pub id: Uuid, + pub kind: FourCC, + pub name: Option, + pub reader_version: u32, + pub writer_version: u32, +} + impl Package<'_> { - pub fn read(data: &[u8], e: Endian) -> Result { + pub fn read_header(data: &[u8], e: Endian) -> Result> { + let (mut pack, pack_data, _) = FormDescriptor::slice(data, e)?; + ensure!(pack.id == K_FORM_PACK); + ensure!(pack.version_a == 1); + let (mut tocc, tocc_data, _) = FormDescriptor::slice(pack_data, e)?; + ensure!(tocc.id == K_FORM_TOCC); + ensure!(tocc.version_a == 3); + + // Rewrite PACK with only TOCC chunk + let mut out = Cursor::new(Vec::new()); + pack.write(&mut out, e, |w| { + tocc.write(w, e, |w| { + w.write_all(tocc_data)?; + Ok(()) + }) + })?; + Ok(out.into_inner()) + } + + pub fn read_sparse(data: &[u8], e: Endian) -> Result> { + let (pack, pack_data, _) = FormDescriptor::slice(data, e)?; + ensure!(pack.id == K_FORM_PACK); + ensure!(pack.version_a == 1); + let (tocc, mut tocc_data, _) = FormDescriptor::slice(pack_data, e)?; + ensure!(tocc.id == K_FORM_TOCC); + ensure!(tocc.version_a == 3); + let mut adir: Option = None; + let mut strg: HashMap = HashMap::new(); + while !tocc_data.is_empty() { + let (desc, chunk_data, remain) = ChunkDescriptor::slice(tocc_data, e)?; + let mut reader = Cursor::new(chunk_data); + match desc.id { + K_CHUNK_ADIR => { + adir = Some(reader.read_type(e)?); + } + K_CHUNK_META => {} + K_CHUNK_STRG => { + let chunk: StringTable = reader.read_type(e)?; + for entry in chunk.entries { + strg.insert(entry.asset_id, String::from_utf8(entry.name)?); + } + } + kind => bail!("Unhandled TOCC chunk {:?}", kind), + } + tocc_data = remain; + } + + let Some(adir) = adir else { + bail!("Failed to locate asset directory"); + }; + let entries = adir + .entries + .into_iter() + .map(|asset_entry| SparsePackageEntry { + id: asset_entry.asset_id, + kind: asset_entry.asset_type, + name: strg.get(&asset_entry.asset_id).cloned(), + reader_version: asset_entry.version, + writer_version: asset_entry.other_version, + }) + .collect(); + Ok(entries) + } + + pub fn read_asset(data: &[u8], id: Uuid, e: Endian) -> Result> { + let (pack, pack_data, _) = FormDescriptor::slice(data, e)?; + ensure!(pack.id == K_FORM_PACK); + ensure!(pack.version_a == 1); + let (tocc, mut tocc_data, _) = FormDescriptor::slice(pack_data, e)?; + ensure!(tocc.id == K_FORM_TOCC); + ensure!(tocc.version_a == 3); + + let mut asset: Option = None; + let mut meta: Option<&[u8]> = None; + let mut name: Option = None; + while !tocc_data.is_empty() { + let (desc, chunk_data, remain) = ChunkDescriptor::slice(tocc_data, e)?; + let mut reader = Cursor::new(chunk_data); + match desc.id { + K_CHUNK_ADIR => { + let adir: AssetDirectory = reader.read_type(e)?; + asset = Some( + adir.entries + .into_iter() + .find(|asset| asset.asset_id == id) + .ok_or_else(|| anyhow!("Failed to locate asset {}", id))?, + ); + } + K_CHUNK_META => { + let chunk: MetadataTable = reader.read_type(e)?; + for entry in chunk.entries { + if entry.asset_id != id { + continue; + } + let meta_size = u32::from_le_bytes( + chunk_data[entry.offset as usize..entry.offset as usize + 4] + .try_into() + .unwrap(), + ); + let meta_data = &chunk_data + [entry.offset as usize + 4..(entry.offset + 4 + meta_size) as usize]; + meta = Some(meta_data); + } + } + K_CHUNK_STRG => { + let chunk: StringTable = reader.read_type(e)?; + for entry in chunk.entries { + if entry.asset_id != id { + continue; + } + name = Some(String::from_utf8(entry.name)?); + break; + } + } + kind => bail!("Unhandled TOCC chunk {:?}", kind), + } + tocc_data = remain; + } + + let Some(asset) = asset else { + bail!("Failed to locate asset directory"); + }; + let compressed_data = &data[asset.offset as usize..(asset.offset + asset.size) as usize]; + let (compression_mode, data) = if asset.size != asset.decompressed_size { + decompress_buffer(compressed_data, asset.decompressed_size)? + } else { + (0, Cow::Borrowed(compressed_data)) + }; + + // Validate RFRM + { + let (form, _, _) = FormDescriptor::slice(&data, Endian::Little)?; + ensure!(asset.asset_type == form.id); + ensure!(asset.version == form.version_a); + ensure!(asset.other_version == form.version_b); + ensure!(asset.decompressed_size == form.size + 32 /* RFRM */); + } + + let len = data.len() as u64; + let mut w = Cursor::new(data.into_owned()); + w.set_position(len); // set to append + + // Write custom footer + FormDescriptor { size: 0, unk: 0, id: K_FORM_FOOT, version_a: 1, version_b: 1 }.write( + &mut w, + Endian::Little, + |w| { + ChunkDescriptor { id: K_CHUNK_AINF, size: 0, unk: 0, skip: 0 }.write( + w, + Endian::Little, + |w| { + w.write_le(&AssetInfo { id, compression_mode, orig_offset: asset.offset })?; + Ok(()) + }, + )?; + if let Some(meta) = meta { + let meta_chunk = ChunkDescriptor { + id: K_CHUNK_META, + size: meta.len() as u64, + unk: 0, + skip: 0, + }; + w.write_le(&meta_chunk)?; + w.write_all(meta)?; + } + if let Some(name) = &name { + let bytes = name.as_bytes(); + let name_chunk = ChunkDescriptor { + id: K_CHUNK_NAME, + size: bytes.len() as u64, + unk: 0, + skip: 0, + }; + w.write_le(&name_chunk)?; + w.write_all(bytes)?; + } + Ok(()) + }, + )?; + + Ok(w.into_inner()) + } + + pub fn read_full(data: &[u8], e: Endian) -> Result { let (pack, pack_data, _) = FormDescriptor::slice(data, e)?; ensure!(pack.id == K_FORM_PACK); ensure!(pack.version_a == 1); diff --git a/src/format/rfrm.rs b/lib/src/format/rfrm.rs similarity index 100% rename from src/format/rfrm.rs rename to lib/src/format/rfrm.rs diff --git a/src/format/txtr.rs b/lib/src/format/txtr.rs similarity index 85% rename from src/format/txtr.rs rename to lib/src/format/txtr.rs index 75b5d9f..1146e7f 100644 --- a/src/format/txtr.rs +++ b/lib/src/format/txtr.rs @@ -1,9 +1,21 @@ -use std::num::NonZeroUsize; +use std::{io::Cursor, num::NonZeroUsize}; -use anyhow::{ensure, Result}; -use binrw::binrw; +use anyhow::{anyhow, ensure, Result}; +use binrw::{binrw, BinReaderExt, Endian}; use tegra_swizzle::surface::BlockDim; +use crate::{ + format::{chunk::ChunkDescriptor, rfrm::FormDescriptor, FourCC}, + util::compression::decompress_into, +}; + +// Texture +pub const K_FORM_TXTR: FourCC = FourCC(*b"TXTR"); +// Texture header +pub const K_CHUNK_HEAD: FourCC = FourCC(*b"HEAD"); +// GPU data +pub const K_CHUNK_GPU: FourCC = FourCC(*b"GPU "); + #[binrw] #[repr(u32)] #[brw(repr(u32))] @@ -370,7 +382,7 @@ impl ETextureFormat { } } -pub fn deswizzle(header: &STextureHeader, data: &[u8]) -> Result> { +fn deswizzle(header: &STextureHeader, data: &[u8]) -> Result> { let (bw, bh, bd) = header.format.block_size(); let block_dim = BlockDim { width: NonZeroUsize::new(bw as usize).unwrap(), @@ -401,3 +413,43 @@ pub fn deswizzle(header: &STextureHeader, data: &[u8]) -> Result> { header.layers as usize, )?) } + +#[derive(Debug, Clone)] +pub struct TextureData { + pub head: STextureHeader, + pub data: Vec, +} + +impl TextureData { + pub fn slice(data: &[u8], meta: &[u8], e: Endian) -> Result { + let (txtr_desc, txtr_data, _) = FormDescriptor::slice(data, e)?; + ensure!(txtr_desc.id == K_FORM_TXTR); + ensure!(txtr_desc.version_a == 47); + ensure!(txtr_desc.version_b == 51); + + let (head_desc, head_data, _) = ChunkDescriptor::slice(txtr_data, Endian::Little)?; + ensure!(head_desc.id == K_CHUNK_HEAD); + let head: STextureHeader = Cursor::new(head_data).read_type(Endian::Little)?; + + // log::debug!("META: {meta:#?}"); + // log::debug!("HEAD: {head:#?}"); + + let meta: STextureMetaData = Cursor::new(meta).read_type(e)?; + let mut buffer = vec![0u8; meta.decompressed_size as usize]; + for info in &meta.buffers { + let read = + meta.info.iter().find(|i| i.index as u32 == info.index).ok_or_else(|| { + anyhow!("Failed to locate read info for buffer {}", info.index) + })?; + let read_buf = &data[read.offset as usize..(read.offset + read.size) as usize]; + let comp_buf = &read_buf[info.offset as usize..(info.offset + info.size) as usize]; + decompress_into( + comp_buf, + &mut buffer + [info.dest_offset as usize..(info.dest_offset + info.dest_size) as usize], + )?; + } + let deswizzled = deswizzle(&head, &buffer)?; + Ok(TextureData { head, data: deswizzled }) + } +} diff --git a/lib/src/lib.rs b/lib/src/lib.rs new file mode 100644 index 0000000..bcba061 --- /dev/null +++ b/lib/src/lib.rs @@ -0,0 +1,2 @@ +pub mod format; +pub mod util; diff --git a/src/util/astc.rs b/lib/src/util/astc.rs similarity index 100% rename from src/util/astc.rs rename to lib/src/util/astc.rs diff --git a/lib/src/util/compression.rs b/lib/src/util/compression.rs new file mode 100644 index 0000000..40892fc --- /dev/null +++ b/lib/src/util/compression.rs @@ -0,0 +1,46 @@ +use std::borrow::Cow; + +use anyhow::{bail, Result}; + +use crate::util::lzss; + +pub fn decompress_buffer( + compressed_data: &[u8], + decompressed_size: u64, +) -> Result<(u32, Cow<[u8]>)> { + if compressed_data.len() < 4 { + bail!("Invalid compressed data size: {}", compressed_data.len()); + } + if compressed_data[0..4] == [0u8; 4] { + // Shortcut for uncompressed data + return Ok((0, Cow::Borrowed(&compressed_data[4..]))); + } + let mut out = vec![0u8; decompressed_size as usize]; + let mode = decompress_into(compressed_data, &mut out)?; + Ok((mode, Cow::Owned(out))) +} + +pub fn decompress_into(compressed_data: &[u8], out: &mut [u8]) -> Result { + if compressed_data.len() < 4 { + bail!("Invalid compressed data size: {}", compressed_data.len()); + } + let mode = u32::from_le_bytes(compressed_data[0..4].try_into().unwrap()); + let data = &compressed_data[4..]; + if !match mode { + 0 => { + if data.len() == out.len() { + out.copy_from_slice(data); + true + } else { + false + } + } + 1 => lzss::decompress::<1>(data, out), + 2 => lzss::decompress::<2>(data, out), + 3 => lzss::decompress::<3>(data, out), + _ => bail!("Unsupported compression mode {}", mode), + } { + bail!("Decompression failed"); + } + Ok(mode) +} diff --git a/src/util/dds.rs b/lib/src/util/dds.rs similarity index 100% rename from src/util/dds.rs rename to lib/src/util/dds.rs diff --git a/src/util/file.rs b/lib/src/util/file.rs similarity index 100% rename from src/util/file.rs rename to lib/src/util/file.rs diff --git a/lib/src/util/lzss.rs b/lib/src/util/lzss.rs new file mode 100644 index 0000000..b7578c3 --- /dev/null +++ b/lib/src/util/lzss.rs @@ -0,0 +1,36 @@ +/// https://wiki.axiodl.com/w/LZSS_Compression +pub fn decompress(mut input: &[u8], output: &mut [u8]) -> bool { + let group_len = 2usize.pow(M as u32 - 1); + let mut out_cur = 0usize; + + let mut header_byte = 0u8; + let mut group = 0u8; + while !input.is_empty() { + if group == 0 { + header_byte = input[0]; + input = &input[1..]; + group = 8; + } + + if header_byte & 0x80 == 0 { + output[out_cur..group_len + out_cur].copy_from_slice(&input[..group_len]); + input = &input[group_len..]; + out_cur += group_len; + } else { + let count = (input[0] as usize >> 4) + (4 - M as usize); + let length = (((input[0] as usize & 0xF) << 0x8) | input[1] as usize) << (M - 1); + input = &input[2..]; + + let seek = out_cur - length; + for n in 0..count * group_len { + output[out_cur + n] = output[seek + n]; + } + out_cur += count * group_len; + } + + header_byte <<= 1; + group -= 1; + } + + out_cur == output.len() +} diff --git a/src/util/mod.rs b/lib/src/util/mod.rs similarity index 95% rename from src/util/mod.rs rename to lib/src/util/mod.rs index 382095d..fff3197 100644 --- a/src/util/mod.rs +++ b/lib/src/util/mod.rs @@ -1,4 +1,5 @@ pub mod astc; +pub mod compression; pub mod dds; pub mod file; pub mod lzss; diff --git a/retrotool-gui/Cargo.toml b/retrotool-gui/Cargo.toml new file mode 100644 index 0000000..6e951ba --- /dev/null +++ b/retrotool-gui/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "retrotool-gui" +description = "Tools for working with Retro game formats." +authors = ["Luke Street "] +license = "MIT OR Apache-2.0" +version = "0.1.0" +edition = "2021" +publish = false +repository = "https://github.com/PrimeDecomp/retrotool" +readme = "README.md" + +[features] +default = [] +dynamic = ["bevy/dynamic"] + +[dependencies] +anyhow = "1.0.69" +astc-decode = "0.3.1" +bevy = "0.9.1" +bevy_egui = { git = "https://github.com/paul-hansen/bevy_egui", branch = "egui-0.21" } +binrw = "0.11.1" +egui = "0.21.0" +egui_dock = "0.4.0" +image = "0.24.5" +log = "0.4.17" +retrolib = { path = "../lib" } +uuid = "1.3.0" +walkdir = "2.3.2" diff --git a/retrotool-gui/src/loaders.rs b/retrotool-gui/src/loaders.rs new file mode 100644 index 0000000..22db65e --- /dev/null +++ b/retrotool-gui/src/loaders.rs @@ -0,0 +1,229 @@ +use std::{ + io::Cursor, + path::{Path, PathBuf}, + sync::{Arc, RwLock}, +}; + +use anyhow::Error; +use astc_decode::{astc_decode, Footprint}; +use bevy::{ + app::{App, Plugin}, + asset::{ + AddAsset, AssetIo, AssetIoError, AssetLoader, BoxedFuture, LoadContext, LoadedAsset, + Metadata, + }, + prelude::*, +}; +use binrw::Endian; +use image::{ImageBuffer, RgbaImage}; +use retrolib::{ + format::{ + foot::locate_meta, + pack::{Package, SparsePackageEntry}, + txtr::TextureData, + }, + util::file::map_file, +}; +use uuid::Uuid; + +#[derive(Debug, Clone, Resource)] +pub struct SharedPackageInfo { + packages: Arc>>, +} + +struct RetroAssetIo { + default: Box, + packages: SharedPackageInfo, +} + +fn read_pak_header(path: &Path) -> anyhow::Result> { + let data = map_file(path)?; + Package::read_header(&data, Endian::Little) +} + +fn read_asset(path: &Path, id: Uuid) -> anyhow::Result> { + let data = map_file(path)?; + Package::read_asset(&data, id, Endian::Little) +} + +impl AssetIo for RetroAssetIo { + fn load_path<'a>( + &'a self, + path: &'a Path, + ) -> BoxedFuture<'a, anyhow::Result, AssetIoError>> { + if let Some(id) = + path.file_stem().and_then(|name| Uuid::try_parse(&name.to_string_lossy()).ok()) + { + // Load pak header only + Box::pin(async move { + let mut package_path: Option = None; + if let Ok(packages) = self.packages.packages.read() { + if let Some(package) = + packages.iter().find(|p| p.entries.iter().any(|e| e.id == id)) + { + package_path = Some(package.path.clone()); + } + } + let Some(package_path) = package_path else { + return Err(AssetIoError::NotFound(path.to_owned())); + }; + read_asset(&package_path, id).map_err(|e| { + AssetIoError::Io(std::io::Error::new(std::io::ErrorKind::Other, e)) + }) + }) + } else if path.extension() == Some("pak".as_ref()) { + // Load pak header only + Box::pin(async move { + read_pak_header(path).map_err(|e| { + AssetIoError::Io(std::io::Error::new(std::io::ErrorKind::Other, e)) + }) + }) + } else { + self.default.load_path(path) + } + } + + fn read_directory( + &self, + path: &Path, + ) -> anyhow::Result>, AssetIoError> { + self.default.read_directory(path) + } + + fn get_metadata(&self, path: &Path) -> anyhow::Result { + self.default.get_metadata(path) + } + + fn watch_path_for_changes(&self, path: &Path) -> anyhow::Result<(), AssetIoError> { + self.default.watch_path_for_changes(path) + } + + fn watch_for_changes(&self) -> anyhow::Result<(), AssetIoError> { + self.default.watch_for_changes() + } +} + +pub struct RetroAssetIoPlugin; + +impl Plugin for RetroAssetIoPlugin { + fn build(&self, app: &mut App) { + let default = AssetPlugin::default().create_platform_default_asset_io(); + let shared_package_info = SharedPackageInfo { packages: Arc::new(Default::default()) }; + let asset_io = RetroAssetIo { default, packages: shared_package_info.clone() }; + app.insert_resource(shared_package_info); + app.insert_resource(AssetServer::new(asset_io)); + } +} + +pub fn package_loader_system( + mut ev_asset: EventReader>, + assets: Res>, + package_info: Res, +) { + for ev in ev_asset.iter() { + match ev { + AssetEvent::Created { handle } => { + let package = assets.get(handle).unwrap(); + println!("Loaded package {}", package.path.display()); + let mut package_info = + package_info.packages.write().expect("Failed to lock shared package info"); + package_info.push(package.clone()); + } + AssetEvent::Modified { .. } => {} + AssetEvent::Removed { handle } => { + let package = assets.get(handle).unwrap(); + let mut package_info = + package_info.packages.write().expect("Failed to lock shared package info"); + package_info.retain(|p| p.path != package.path); + } + } + } +} + +#[derive(Debug, Clone, bevy::reflect::TypeUuid)] +#[uuid = "83269869-1209-408e-8835-bc6f2496e827"] +pub struct PackageDirectory { + pub path: PathBuf, + pub name: String, + pub entries: Vec, +} + +pub struct PackageAssetLoader; + +impl Plugin for PackageAssetLoader { + fn build(&self, app: &mut App) { + app.add_asset::().add_asset_loader(PackageAssetLoader); + } +} + +impl AssetLoader for PackageAssetLoader { + fn load<'a>( + &'a self, + bytes: &'a [u8], + load_context: &'a mut LoadContext, + ) -> BoxedFuture<'a, anyhow::Result<(), Error>> { + Box::pin(async move { + load_context.set_default_asset(LoadedAsset::new(PackageDirectory { + path: load_context.path().to_owned(), + name: load_context + .path() + .file_stem() + .unwrap_or_default() + .to_string_lossy() + .to_string(), + entries: Package::read_sparse(bytes, Endian::Little)?, + })); + Ok(()) + }) + } + + fn extensions(&self) -> &[&str] { &["pak"] } +} + +#[derive(Debug, Clone, bevy::reflect::TypeUuid)] +#[uuid = "83269869-1209-408e-8835-bc6f2496e828"] +pub struct TxtrData { + pub data: TextureData, + pub rgba: Option>, +} + +pub struct TxtrAssetLoader; + +impl Plugin for TxtrAssetLoader { + fn build(&self, app: &mut App) { + app.add_asset::().add_asset_loader(TxtrAssetLoader); + } +} + +impl AssetLoader for TxtrAssetLoader { + fn load<'a>( + &'a self, + bytes: &'a [u8], + load_context: &'a mut LoadContext, + ) -> BoxedFuture<'a, anyhow::Result<(), Error>> { + Box::pin(async move { + let meta = locate_meta(bytes, Endian::Little)?; + let data = TextureData::slice(bytes, meta, Endian::Little)?; + let mut rgba = None; + if data.head.format.is_astc() { + let mut image = RgbaImage::new(data.head.width, data.head.height); + let (bx, by, _) = data.head.format.block_size(); + astc_decode( + Cursor::new(&data.data), + data.head.width, + data.head.height, + Footprint::new(bx as u32, by as u32), + |x, y, texel| { + image.put_pixel(x, y, texel.into()); + }, + )?; + rgba = Some(image.into_raw()); + } + println!("Loaded texture {:?}", data.head); + load_context.set_default_asset(LoadedAsset::new(TxtrData { data, rgba })); + Ok(()) + }) + } + + fn extensions(&self) -> &[&str] { &["txtr"] } +} diff --git a/retrotool-gui/src/main.rs b/retrotool-gui/src/main.rs new file mode 100644 index 0000000..119034f --- /dev/null +++ b/retrotool-gui/src/main.rs @@ -0,0 +1,278 @@ +mod loaders; + +use std::fs::FileType; + +use bevy::{ + asset::LoadState, + prelude::*, + render::render_resource::{ + Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, + }, +}; +use bevy_egui::{ + egui, + egui::{text::LayoutJob, Color32, FontId, TextFormat, Widget}, + EguiContext, EguiPlugin, EguiSettings, +}; +use egui::TextureId; +use retrolib::format::txtr::K_FORM_TXTR; +use walkdir::{DirEntry, WalkDir}; + +use crate::loaders::{ + package_loader_system, PackageAssetLoader, PackageDirectory, RetroAssetIoPlugin, + TxtrAssetLoader, TxtrData, +}; + +struct Images { + bevy_icon: Handle, + bevy_icon_inverted: Handle, +} + +impl FromWorld for Images { + fn from_world(world: &mut World) -> Self { + let asset_server = world.get_resource_mut::().unwrap(); + Self { + bevy_icon: asset_server.load("icon.png"), + bevy_icon_inverted: asset_server.load("icon_inverted.png"), + } + } +} + +/// This example demonstrates the following functionality and use-cases of bevy_egui: +/// - rendering loaded assets; +/// - toggling hidpi scaling (by pressing '/' button); +/// - configuring egui contexts during the startup. +fn main() { + App::new() + .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) + .insert_resource(Msaa { samples: 1 }) + .init_resource::() + .init_resource::() + .init_resource::() + .init_resource::() + .add_plugins( + DefaultPlugins + .build() + // the custom asset io plugin must be inserted in-between the + // `CorePlugin' and `AssetPlugin`. It needs to be after the + // CorePlugin, so that the IO task pool has already been constructed. + // And it must be before the `AssetPlugin` so that the asset plugin + // doesn't create another instance of an asset server. In general, + // the AssetPlugin should still run so that other aspects of the + // asset system are initialized correctly. + .add_before::(RetroAssetIoPlugin), + ) + .add_plugin(PackageAssetLoader) + .add_plugin(TxtrAssetLoader) + .add_plugin(EguiPlugin) + .add_startup_system(configure_visuals) + .add_startup_system(preload_package) + .add_system(update_ui_scale_factor) + .add_system(ui_example) + .add_system(package_loader_system) + .add_system(check_assets_ready) + .run(); +} + +enum TabType { + Directory, + Asset(HandleUntyped, Option), + Empty, +} + +#[derive(Resource)] +struct UiState { + tree: egui_dock::Tree, +} + +impl Default for UiState { + fn default() -> Self { + let mut tree = egui_dock::Tree::new(vec![TabType::Empty]); + tree.split_left(egui_dock::NodeIndex::root(), 0.3, vec![TabType::Directory]); + Self { tree } + } +} + +struct TabViewer<'a> { + server: Res<'a, AssetServer>, + packages: Res<'a, Assets>, + textures: Res<'a, Assets>, + open_asset: ResMut<'a, OpenAsset>, +} + +impl egui_dock::TabViewer for TabViewer<'_> { + type Tab = TabType; + + fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) { + match tab { + TabType::Directory => { + for (_, package) in self.packages.iter() { + egui::CollapsingHeader::new(&package.name).show(ui, |ui| { + for entry in &package.entries { + let mut job = LayoutJob::simple( + format!("{} {}", entry.kind, entry.id), + FontId::monospace(12.0), + Color32::GRAY, + 0.0, + ); + if let Some(name) = &entry.name { + job.append( + &format!("\n{name}"), + 0.0, + TextFormat::simple(FontId::monospace(12.0), Color32::WHITE), + ); + } + if egui::SelectableLabel::new(false, job).ui(ui).clicked() { + self.open_asset.0 = match entry.kind { + K_FORM_TXTR => Some( + self.server + .load::(format!( + "{}.{}", + entry.id, entry.kind + )) + .into(), + ), + _ => None, + }; + } + } + }); + } + } + TabType::Asset(handle, image) => { + if let Some(txtr) = self.textures.get(&handle.typed_weak::()) { + if let Some(image) = image { + ui.add(egui::widgets::Image::new(*image, egui::Vec2 { + x: txtr.data.head.width as f32, + y: txtr.data.head.height as f32, + })); + } + } + } + TabType::Empty => {} + } + } + + fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText { + match tab { + TabType::Directory => "Directory".into(), + TabType::Asset(_, _) => "Asset view".into(), + TabType::Empty => "Placeholder".into(), + } + } +} + +fn configure_visuals(mut egui_ctx: ResMut) { + // egui_ctx + // .ctx_mut() + // .set_visuals(egui::Visuals { window_rounding: 0.0.into(), ..Default::default() }); +} + +#[derive(Default, Resource)] +struct Packages(Vec>); +#[derive(Default, Resource)] +struct Textures(Vec>); + +fn is_hidden(entry: &DirEntry) -> bool { + entry.file_name().to_str().map(|s| s.starts_with('.')).unwrap_or(false) +} + +fn preload_package(server: Res, mut loading: ResMut) { + let walker = WalkDir::new("/home/lstreet/Development/mpr/extract/romfs").into_iter(); + for entry in walker.filter_entry(|e| !is_hidden(e)).filter_map(|e| e.ok()) { + if entry.file_type().is_file() && entry.path().extension() == Some("pak".as_ref()) { + loading.0.push(server.load(entry.path())); + } + } +} + +fn check_assets_ready( + server: Res, + mut loading: ResMut, + mut ui_state: ResMut, + textures: Res>, + mut egui_ctx: ResMut, + mut images: ResMut>, +) { + if let Some(handle) = &loading.0 { + let state = server.get_load_state(handle); + match state { + LoadState::NotLoaded => {} + LoadState::Loading => {} + LoadState::Loaded => { + let handle = std::mem::take(&mut loading.0).unwrap(); + let txtr = textures.get(&handle.typed_weak::()).unwrap(); + let image = if let Some(rgba) = &txtr.rgba { + let image_handle = images.add(Image { + data: rgba.clone(), + texture_descriptor: TextureDescriptor { + label: None, + size: Extent3d { + width: txtr.data.head.width, + height: txtr.data.head.height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8Unorm, + usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, + }, + sampler_descriptor: Default::default(), + texture_view_descriptor: None, + }); + Some(egui_ctx.add_image(image_handle)) + } else { + None + }; + ui_state.tree.push_to_first_leaf(TabType::Asset(handle, image)); + } + LoadState::Failed => {} + LoadState::Unloaded => {} + } + } +} + +fn update_ui_scale_factor( + keyboard_input: Res>, + mut toggle_scale_factor: Local>, + mut egui_settings: ResMut, + windows: Res, +) { + if keyboard_input.just_pressed(KeyCode::Slash) || toggle_scale_factor.is_none() { + *toggle_scale_factor = Some(!toggle_scale_factor.unwrap_or(true)); + + if let Some(window) = windows.get_primary() { + let scale_factor = + if toggle_scale_factor.unwrap() { 1.0 } else { 1.0 / window.scale_factor() }; + egui_settings.scale_factor = scale_factor; + } + } +} + +#[derive(Default, Resource)] +struct OpenAsset(Option); + +fn ui_example( + mut egui_ctx: ResMut, + mut ui_state: ResMut, + packages: Res>, + textures: Res>, + server: Res, + open_asset: ResMut, +) { + egui::TopBottomPanel::top("top_panel").show(egui_ctx.ctx_mut(), |ui| { + // The top panel is often a good place for a menu bar: + egui::menu::bar(ui, |ui| { + egui::menu::menu_button(ui, "File", |ui| { + if ui.button("Quit").clicked() { + std::process::exit(0); + } + }); + }); + }); + + egui_dock::DockArea::new(&mut ui_state.tree) + .style(egui_dock::Style::from_egui(egui_ctx.ctx_mut().style().as_ref())) + .show(egui_ctx.ctx_mut(), &mut TabViewer { server, packages, textures, open_asset }); +} diff --git a/retrotool/Cargo.toml b/retrotool/Cargo.toml new file mode 100644 index 0000000..867018c --- /dev/null +++ b/retrotool/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "retrotool" +description = "Tools for working with Retro game formats." +authors = ["Luke Street "] +license = "MIT OR Apache-2.0" +version = "0.1.0" +edition = "2021" +publish = false +repository = "https://github.com/PrimeDecomp/retrotool" +readme = "README.md" +categories = ["command-line-utilities"] + +[dependencies] +retrolib = { path = "../lib" } +anyhow = "1.0.69" +argh = "0.1.10" +# astc-decode = "0.3.1" +binrw = "0.11.1" +binrw_derive = "0.11.1" +ddsfile = { git = "https://github.com/encounter/ddsfile", rev = "880f04c1dffa680eab0e9e09cfa58591fe186a31" } +env_logger = "0.10.0" +gltf-json = { version = "1.1.0", features = ["names", "extras"] } +half = "2.2.1" +# image = "0.24.5" +log = "0.4.17" +memmap2 = "0.5.8" +serde_json = "1.0.93" +tegra_swizzle = "0.3.0" +uuid = "1.3.0" diff --git a/src/argh_version.rs b/retrotool/src/argh_version.rs similarity index 100% rename from src/argh_version.rs rename to retrotool/src/argh_version.rs diff --git a/src/cmd/cmdl.rs b/retrotool/src/cmd/cmdl.rs similarity index 60% rename from src/cmd/cmdl.rs rename to retrotool/src/cmd/cmdl.rs index 7bab561..e161066 100644 --- a/src/cmd/cmdl.rs +++ b/retrotool/src/cmd/cmdl.rs @@ -5,7 +5,6 @@ use std::{ fs::DirBuilder, io::{Cursor, Read, Write}, path::PathBuf, - string::FromUtf8Error, }; use anyhow::{bail, ensure, Result}; @@ -14,35 +13,19 @@ use binrw::{binrw, BinReaderExt, BinWriterExt, Endian}; use gltf_json as json; use half::f16; use json::validation::Checked::Valid; +use retrolib::{ + format::{ + cmdl::{ + CMaterialDataInner, CMaterialTextureTokenData, EBufferType, EMaterialDataId, + EVertexComponent, EVertexDataFormat, ModelData, + }, + foot::locate_meta, + }, + util::file::map_file, +}; use serde_json::json; use uuid::Uuid; -use crate::{ - format::{ - chunk::ChunkDescriptor, - pack::{K_CHUNK_META, K_FORM_FOOT}, - rfrm::FormDescriptor, - FourCC, - }, - util::{file::map_file, lzss::decompress_buffer}, -}; - -// Cooked model -pub const K_FORM_CMDL: FourCC = FourCC(*b"CMDL"); - -// Model header -pub const K_CHUNK_HEAD: FourCC = FourCC(*b"HEAD"); -// Material data -pub const K_CHUNK_MTRL: FourCC = FourCC(*b"MTRL"); -// Mesh data -pub const K_CHUNK_MESH: FourCC = FourCC(*b"MESH"); -// Vertex buffer -pub const K_CHUNK_VBUF: FourCC = FourCC(*b"VBUF"); -// Index buffer -pub const K_CHUNK_IBUF: FourCC = FourCC(*b"IBUF"); -// GPU data -pub const K_CHUNK_GPU: FourCC = FourCC(*b"GPU "); - #[derive(FromArgs, PartialEq, Debug)] /// process CMDL files #[argh(subcommand, name = "cmdl")] @@ -75,285 +58,22 @@ pub fn run(args: Args) -> Result<()> { } } -#[binrw] -#[derive(Clone, Debug)] -pub struct SModelReadBufferInfo { - pub size: u32, - pub offset: u32, +#[derive(Debug, Clone)] +struct VertexBufferAttribute { + pub in_offset: u32, + pub out_offset: u32, + pub in_format: EVertexDataFormat, + pub in_size: u32, + pub out_format: EVertexDataFormat, + pub component: EVertexComponent, } -#[binrw] -#[derive(Clone, Debug)] -pub struct SModelBufferInfo { - pub read_index: u32, - pub offset: u32, - pub size: u32, - pub dest_size: u32, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SModelMetaData { - pub unk: u32, - pub gpu_offset: u32, - #[bw(try_calc = read_info.len().try_into())] - pub read_info_count: u32, - #[br(count = read_info_count)] - pub read_info: Vec, - #[bw(try_calc = vtx_buffer_info.len().try_into())] - pub vtx_buffer_count: u32, - #[br(count = vtx_buffer_count)] - pub vtx_buffer_info: Vec, - #[bw(try_calc = idx_buffer_info.len().try_into())] - pub idx_info_count: u32, - #[br(count = idx_info_count)] - pub idx_buffer_info: Vec, -} - -#[binrw] -#[repr(u32)] -#[brw(repr(u32))] -#[derive(Copy, Clone, Debug)] -pub enum EBufferType { - U8 = 0, // ? - U16 = 1, - U32 = 2, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SIndexBufferInfoSection { - #[bw(try_calc = info.len().try_into())] - pub count: u32, - #[br(count = count)] - pub info: Vec, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SVertexBufferInfoSection { - #[bw(try_calc = info.len().try_into())] - pub count: u32, - #[br(count = count)] - pub info: Vec, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SVertexBufferInfo { - vertex_count: u32, - #[bw(try_calc = components.len().try_into())] - component_count: u32, - #[br(count = component_count)] - components: Vec, - unk: u8, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SVertexDataComponent { - buffer_index: u32, - offset: u32, - stride: u32, - format: EVertexDataFormat, - component: EVertexComponent, -} - -#[binrw] -#[repr(u32)] -#[brw(repr(u32))] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -enum EVertexDataFormat { - Unknown = u32::MAX, - R8Unorm = 0, - R8Uint = 1, - R8Snorm = 2, - R8Sint = 3, - R16Unorm = 4, - R16Uint = 5, - R16Snorm = 6, - R16Sint = 7, - R16Float = 8, - Rg8Unorm = 9, - Rg8Uint = 10, - Rg8Snorm = 11, - Rg8Sint = 12, - R32Uint = 13, - R32Sint = 14, - R32Float = 15, - Rg16Unorm = 16, - Rg16Uint = 17, - Rg16Snorm = 18, - Rg16Sint = 19, - Rg16Float = 20, - Rgba8Unorm = 21, - Rgba8Uint = 22, - Rgba8Snorm = 23, - Rgba8Sint = 24, - Rgb10a2Unorm = 25, - Rgb10a2Uint = 26, - Rg32Uint = 27, - Rg32Sint = 28, - Rg32Float = 29, - Rgba16Unorm = 30, - Rgba16Uint = 31, - Rgba16Snorm = 32, - Rgba16Sint = 33, - Rgba16Float = 34, - Rgb32Uint = 35, - Rgb32Sint = 36, - Rgb32Float = 37, - Rgba32Uint = 38, - Rgba32Sint = 39, - Rgba32Float = 40, -} - -impl EVertexDataFormat { - fn byte_size(self) -> u32 { - match self { - EVertexDataFormat::Unknown => 0, - EVertexDataFormat::R8Unorm => 1, - EVertexDataFormat::R8Uint => 1, - EVertexDataFormat::R8Snorm => 1, - EVertexDataFormat::R8Sint => 1, - EVertexDataFormat::R16Unorm => 2, - EVertexDataFormat::R16Uint => 2, - EVertexDataFormat::R16Snorm => 2, - EVertexDataFormat::R16Sint => 2, - EVertexDataFormat::R16Float => 2, - EVertexDataFormat::Rg8Unorm => 2, - EVertexDataFormat::Rg8Uint => 2, - EVertexDataFormat::Rg8Snorm => 2, - EVertexDataFormat::Rg8Sint => 2, - EVertexDataFormat::R32Uint => 4, - EVertexDataFormat::R32Sint => 4, - EVertexDataFormat::R32Float => 4, - EVertexDataFormat::Rg16Unorm => 4, - EVertexDataFormat::Rg16Uint => 4, - EVertexDataFormat::Rg16Snorm => 4, - EVertexDataFormat::Rg16Sint => 4, - EVertexDataFormat::Rg16Float => 4, - EVertexDataFormat::Rgba8Unorm => 4, - EVertexDataFormat::Rgba8Uint => 4, - EVertexDataFormat::Rgba8Snorm => 4, - EVertexDataFormat::Rgba8Sint => 4, - EVertexDataFormat::Rgb10a2Unorm => 4, - EVertexDataFormat::Rgb10a2Uint => 4, - EVertexDataFormat::Rg32Uint => 8, - EVertexDataFormat::Rg32Sint => 8, - EVertexDataFormat::Rg32Float => 8, - EVertexDataFormat::Rgba16Unorm => 8, - EVertexDataFormat::Rgba16Uint => 8, - EVertexDataFormat::Rgba16Snorm => 8, - EVertexDataFormat::Rgba16Sint => 8, - EVertexDataFormat::Rgba16Float => 8, - EVertexDataFormat::Rgb32Uint => 12, - EVertexDataFormat::Rgb32Sint => 12, - EVertexDataFormat::Rgb32Float => 12, - EVertexDataFormat::Rgba32Uint => 16, - EVertexDataFormat::Rgba32Sint => 16, - EVertexDataFormat::Rgba32Float => 16, - } - } - - fn normalized(self) -> bool { - matches!( - self, - EVertexDataFormat::R8Unorm - | EVertexDataFormat::R8Snorm - | EVertexDataFormat::R16Unorm - | EVertexDataFormat::R16Snorm - | EVertexDataFormat::Rg8Unorm - | EVertexDataFormat::Rg8Snorm - | EVertexDataFormat::Rg16Unorm - | EVertexDataFormat::Rg16Snorm - | EVertexDataFormat::Rgba8Unorm - | EVertexDataFormat::Rgba8Snorm - | EVertexDataFormat::Rgb10a2Unorm - | EVertexDataFormat::Rgba16Unorm - | EVertexDataFormat::Rgba16Snorm - ) - } -} - -#[binrw] -#[repr(u32)] -#[brw(repr(u32))] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -enum EVertexComponent { - Position = 0, // in_position - Normal = 1, // in_normal - Tangent0 = 2, // in_tangent[0] - Tangent1 = 3, // in_tangent[1] - Tangent2 = 4, // in_tangent[2] - TexCoord0 = 5, // in_texCoord[0] - TexCoord1 = 6, // in_texCoord[1] - TexCoord2 = 7, // in_texCoord[2] - TexCoord3 = 8, // in_texCoord[3] - Color = 9, // in_color - BoneIndices = 10, // in_boneIndices - BoneWeights = 11, // in_boneWeights - BakedLightingCoord = 12, // in_bakedLightingCoord - BakedLightingTangent = 13, // in_bakedLightingTangent - VertInstanceParams = 14, // in_vertInstanceParams - VertInstanceColor = 15, // in_vertInstanceColor - VertTransform0 = 16, // in_vertTransform[0] - VertTransform1 = 17, // in_vertTransform[1] - VertTransform2 = 18, // in_vertTransform[2] - CurrentPosition = 19, // in_currentPosition - VertInstanceOpacityParams = 20, // in_vertInstanceOpacityParams - VertInstanceColorIndexingParams = 21, // in_vertInstanceColorIndexingParams - VertInstanceOpacityIndexingParams = 22, // in_vertInstanceOpacityIndexingParams - VertInstancePaintParams = 23, // in_vertInstancePaintParams - BakedLightingLookup = 24, // in_bakedLightingLookup - MaterialChoice0 = 25, // in_materialChoice[0] - MaterialChoice1 = 26, // in_materialChoice[1] - MaterialChoice2 = 27, // in_materialChoice[2] - MaterialChoice3 = 28, // in_materialChoice[3] -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SMeshLoadInformation { - #[bw(try_calc = meshes.len().try_into())] - pub mesh_count: u32, - #[br(count = mesh_count)] - pub meshes: Vec, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CRenderMesh { - pub material_idx: u16, - pub vtx_buf_idx: u8, - pub idx_buf_idx: u8, - pub index_start: u32, - pub index_count: u32, - pub unk_c: u16, - pub unk_e: u16, // 64 -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CVector3f { - pub x: f32, - pub y: f32, - pub z: f32, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CAABox { - pub min: CVector3f, - pub max: CVector3f, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SModelHeader { - pub unk: u32, - pub bounds: CAABox, - // TODO +#[derive(Debug, Clone, Default)] +struct VertexBufferInfo { + pub vertex_count: u32, + pub in_stride: u32, + pub out_stride: u32, + pub attributes: Vec, } #[binrw] @@ -392,594 +112,11 @@ struct Rgba16F { pub a: f16, } -#[derive(Debug, Clone)] -struct VertexBufferAttribute { - pub in_offset: u32, - pub out_offset: u32, - pub in_format: EVertexDataFormat, - pub in_size: u32, - pub out_format: EVertexDataFormat, - pub component: EVertexComponent, -} - -#[derive(Debug, Clone, Default)] -struct VertexBufferInfo { - pub vertex_count: u32, - pub in_stride: u32, - pub out_stride: u32, - pub attributes: Vec, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SMaterialChunk { - pub unk: u32, - #[bw(try_calc = materials.len().try_into())] - pub material_count: u32, - #[br(count = material_count)] - pub materials: Vec, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CMaterialCache { - #[br(try_map = CStringFixedName::into_string)] - #[bw(map = CStringFixedName::from_string)] - pub name: String, - #[br(map = Uuid::from_bytes_le)] - #[bw(map = Uuid::to_bytes_le)] - pub shader_id: Uuid, - #[br(map = Uuid::from_bytes_le)] - #[bw(map = Uuid::to_bytes_le)] - pub unk_guid: Uuid, - pub unk1: u32, - pub unk2: u32, - #[bw(try_calc = types.len().try_into())] - pub type_count: u32, - #[br(count = type_count)] - pub types: Vec, - #[bw(try_calc = render_types.len().try_into())] - pub render_type_count: u32, - #[br(count = render_type_count)] - pub render_types: Vec, - #[bw(try_calc = data_types.len().try_into())] - pub data_count: u32, - #[br(count = data_count)] - pub data_types: Vec, - #[br(count = data_count)] - pub data: Vec, -} - -#[binrw] -#[derive(Clone, Debug, Default)] -pub struct CStringFixedName { - #[bw(try_calc = text.len().try_into())] - pub size: u32, - #[br(count = size)] - pub text: Vec, -} - -impl CStringFixedName { - fn from_string(str: &String) -> Self { - #[allow(clippy::needless_update)] - Self { text: str.as_bytes().to_vec(), ..Default::default() } - } - - fn into_string(self) -> Result { String::from_utf8(self.text) } -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SMaterialRenderTypes { - pub data_id: FourCC, - pub data_type: FourCC, - pub flag1: u8, - pub flag2: u8, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct SMaterialType { - pub data_id: EMaterialDataId, - pub data_type: EMaterialDataType, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CMaterialData { - pub data_id: EMaterialDataId, - pub data_type: EMaterialDataType, - #[br(args { id: data_id, ty: data_type })] - pub data: CMaterialDataInner, -} - -#[binrw] -#[br(import { id: EMaterialDataId, ty: EMaterialDataType })] -#[derive(Clone, Debug)] -pub enum CMaterialDataInner { - #[br(pre_assert(ty == EMaterialDataType::Texture))] - Texture(CMaterialTextureTokenData), - #[br(pre_assert(ty == EMaterialDataType::Color))] - Color(CColor4f), - #[br(pre_assert(ty == EMaterialDataType::Scalar))] - Scalar(f32), - #[br(pre_assert(ty == EMaterialDataType::Int1))] - Int1(i32), - #[br(pre_assert(ty == EMaterialDataType::Int4))] - Int4(CVector4i), - #[br(pre_assert(ty == EMaterialDataType::Mat4))] - Mat4(CMatrix4f), - #[br(pre_assert(ty == EMaterialDataType::Complex && id.is_texture_layered()))] - LayeredTexture(CLayeredTextureData), -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CMaterialTextureTokenData { - #[br(map = Uuid::from_bytes_le)] - #[bw(map = Uuid::to_bytes_le)] - pub id: Uuid, - #[br(if(!id.is_nil()))] - pub usage: Option, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CLayeredTextureBaseData { - unk: u32, - colors: [CColor4f; 3], - flags: u8, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CLayeredTextureData { - base: CLayeredTextureBaseData, - textures: [CMaterialTextureTokenData; 3], -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct STextureUsageInfo { - pub flags: u32, - pub filter: u32, - pub wrap_x: u32, - pub wrap_y: u32, - pub wrap_z: u32, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CColor4f { - pub r: f32, - pub g: f32, - pub b: f32, - pub a: f32, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CVector4i { - pub x: i32, - pub y: i32, - pub z: i32, - pub w: i32, -} - -#[binrw] -#[derive(Clone, Debug)] -pub struct CMatrix4f { - pub m: [f32; 16], -} - -#[binrw] -#[repr(u32)] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum EMaterialDataType { - #[brw(magic(b"TXTR"))] - Texture = 1, - #[brw(magic(b"COLR"))] - Color = 2, - #[brw(magic(b"SCLR"))] - Scalar = 3, - #[brw(magic(b"INT1"))] - Int1 = 4, - #[brw(magic(b"CPLX"))] - Complex = 5, - #[brw(magic(b"INT4"))] - Int4 = 6, - #[brw(magic(b"MAT4"))] - Mat4 = 7, -} - -#[binrw] -#[repr(u32)] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[allow(clippy::upper_case_acronyms)] -pub enum EMaterialDataId { - // TXTR data IDs - #[brw(magic(b"CBUF"))] - CBUF = 1, - #[brw(magic(b"ZBUF"))] - ZBUF = 2, - #[brw(magic(b"GBUF"))] - GBUF = 3, - #[brw(magic(b"GFLG"))] - GFLG = 4, - #[brw(magic(b"OPCT"))] - OPCT = 5, - #[brw(magic(b"DIFT"))] - DIFT = 6, - #[brw(magic(b"ICAN"))] - ICAN = 7, - #[brw(magic(b"SINC"))] - SINC = 8, - #[brw(magic(b"NMAP"))] - NMAP = 9, - #[brw(magic(b"MNMP"))] - MNMP = 10, - #[brw(magic(b"REFL"))] - REFL = 11, - #[brw(magic(b"REFS"))] - REFS = 12, - #[brw(magic(b"REFV"))] - REFV = 13, - #[brw(magic(b"SPCT"))] - SPCT = 14, - #[brw(magic(b"LIBD"))] - LIBD = 15, - #[brw(magic(b"LIBS"))] - LIBS = 16, - #[brw(magic(b"FOGR"))] - FOGR = 17, - #[brw(magic(b"INDI"))] - INDI = 18, - #[brw(magic(b"OTMP"))] - OTMP = 19, - #[brw(magic(b"CGMP"))] - CGMP = 20, - #[brw(magic(b"OGMP"))] - OGMP = 21, - #[brw(magic(b"VAND"))] - VAND = 22, - #[brw(magic(b"BLAT"))] - BLAT = 23, - #[brw(magic(b"BCLR"))] - BCLR = 24, - #[brw(magic(b"METL"))] - METL = 25, - #[brw(magic(b"TCH0"))] - TCH0 = 26, - #[brw(magic(b"TCH1"))] - TCH1 = 27, - #[brw(magic(b"TCH2"))] - TCH2 = 28, - #[brw(magic(b"TCH3"))] - TCH3 = 29, - #[brw(magic(b"TCH4"))] - TCH4 = 30, - #[brw(magic(b"TCH5"))] - TCH5 = 31, - // COLR data IDs - #[brw(magic(b"DIFC"))] - DIFC = 32, - #[brw(magic(b"SHRC"))] - SHRC = 33, - #[brw(magic(b"SPCC"))] - SPCC = 34, - #[brw(magic(b"ICNC"))] - ICNC = 35, - #[brw(magic(b"ICMC"))] - ICMC = 36, - #[brw(magic(b"ODAT"))] - ODAT = 37, - #[brw(magic(b"MDCI"))] - MDCI = 38, - #[brw(magic(b"MDOI"))] - MDOI = 39, - #[brw(magic(b"LODC"))] - LODC = 40, - #[brw(magic(b"LODP"))] - LODP = 41, - #[brw(magic(b"VANP"))] - VANP = 42, - #[brw(magic(b"BLAL"))] - BLAL = 43, - #[brw(magic(b"BLCM"))] - BLCM = 44, - #[brw(magic(b"INDP"))] - INDP = 45, - #[brw(magic(b"PVLO"))] - PVLO = 46, - #[brw(magic(b"PSXT"))] - PSXT = 47, - #[brw(magic(b"PTAI"))] - PTAI = 48, - #[brw(magic(b"PCMD"))] - PCMD = 49, - #[brw(magic(b"BSAO"))] - BSAO = 50, - #[brw(magic(b"CCH0"))] - CCH0 = 51, - #[brw(magic(b"CCH1"))] - CCH1 = 52, - #[brw(magic(b"CCH2"))] - CCH2 = 53, - #[brw(magic(b"CCH3"))] - CCH3 = 54, - #[brw(magic(b"CCH4"))] - CCH4 = 55, - #[brw(magic(b"CCH5"))] - CCH5 = 56, - #[brw(magic(b"CCH6"))] - CCH6 = 57, - #[brw(magic(b"BKLT"))] - BKLT = 58, - #[brw(magic(b"BKLB"))] - BKLB = 59, - #[brw(magic(b"BKLA"))] - BKLA = 60, - #[brw(magic(b"BKGL"))] - BKGL = 61, - #[brw(magic(b"DYIN"))] - DYIN = 62, - #[brw(magic(b"CLP0"))] - CLP0 = 63, - #[brw(magic(b"HOTP"))] - HOTP = 64, - // INT1 data IDs - #[brw(magic(b"SHID"))] - SHID = 65, - #[brw(magic(b"GBFF"))] - GBFF = 66, - #[brw(magic(b"PMOD"))] - PMOD = 67, - #[brw(magic(b"PFLG"))] - PFLG = 68, - #[brw(magic(b"BLPI"))] - BLPI = 69, - #[brw(magic(b"ICH0"))] - ICH0 = 70, - #[brw(magic(b"ICH1"))] - ICH1 = 71, - #[brw(magic(b"ICH2"))] - ICH2 = 72, - // INT4 data IDs - #[brw(magic(b"AUVI"))] - AUVI = 73, - #[brw(magic(b"ECH0"))] - ECH0 = 74, - // SCLR data IDs - #[brw(magic(b"OPCS"))] - OPCS = 75, - #[brw(magic(b"SPCP"))] - SPCP = 76, - #[brw(magic(b"INDS"))] - INDS = 77, - #[brw(magic(b"BLSM"))] - BLSM = 78, - #[brw(magic(b"LITS"))] - LITS = 79, - #[brw(magic(b"MDOE"))] - MDOE = 80, - #[brw(magic(b"VANF"))] - VANF = 81, - #[brw(magic(b"OTHS"))] - OTHS = 82, - #[brw(magic(b"PZSO"))] - PZSO = 83, - #[brw(magic(b"RCH0"))] - RCH0 = 84, - #[brw(magic(b"RCH1"))] - RCH1 = 85, - #[brw(magic(b"RCH2"))] - RCH2 = 86, - // MAT4 data IDs - #[brw(magic(b"PXFM"))] - PXFM = 87, - #[brw(magic(b"MCH0"))] - MCH0 = 88, - // CPLX data IDs - #[brw(magic(b"BCRL"))] - BCRL = 89, // texture_layered - #[brw(magic(b"MTLL"))] - MTLL = 90, // texture_layered - #[brw(magic(b"NRML"))] - NRML = 91, // texture_layered - #[brw(magic(b"SHDD"))] - SHDD = 92, - #[brw(magic(b"SKIN"))] - SKIN = 93, - #[brw(magic(b"DIMD"))] - DIMD = 94, - #[brw(magic(b"LIT "))] - LIT = 95, - #[brw(magic(b"ALLD"))] - ALLD = 96, - #[brw(magic(b"DLLD"))] - DLLD = 97, - #[brw(magic(b"CLLD"))] - CLLD = 98, - #[brw(magic(b"AUXF"))] - AUXF = 99, - #[brw(magic(b"WIND"))] - WIND = 100, - #[brw(magic(b"WATR"))] - WATR = 101, - #[brw(magic(b"DFXS"))] - DFXS = 102, - #[brw(magic(b"DFXN"))] - DFXN = 103, - #[brw(magic(b"MCDD"))] - MCDD = 104, - #[brw(magic(b"CAUS"))] - CAUS = 105, - #[brw(magic(b"BLPD"))] - BLPD = 106, - #[brw(magic(b"BLPT"))] - BLPT = 107, - #[brw(magic(b"FOGS"))] - FOGS = 108, - #[brw(magic(b"VOLF"))] - VOLF = 109, - #[brw(magic(b"VFXB"))] - VFXB = 110, - #[brw(magic(b"VFXD"))] - VFXD = 111, - #[brw(magic(b"REFP"))] - REFP = 112, - #[brw(magic(b"RAIN"))] - RAIN = 113, - #[brw(magic(b"XCH0"))] - XCH0 = 114, - #[brw(magic(b"XCH1"))] - XCH1 = 115, -} - -impl EMaterialDataId { - pub fn is_texture_layered(self) -> bool { - matches!(self, EMaterialDataId::BCRL | EMaterialDataId::MTLL | EMaterialDataId::NRML) - } -} - -#[binrw] -#[repr(u32)] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[allow(clippy::upper_case_acronyms)] -pub enum EMaterialFlag { - #[brw(magic(b"MFTR"))] - MFTR = 0, - #[brw(magic(b"MFMT"))] - MFMT = 1, - #[brw(magic(b"MFSR"))] - MFSR = 2, - #[brw(magic(b"MFSK"))] - MFSK = 3, - #[brw(magic(b"MFVC"))] - MFVC = 4, - #[brw(magic(b"MF1B"))] - MF1B = 5, - #[brw(magic(b"MFAV"))] - MFAV = 6, - #[brw(magic(b"MFIN"))] - MFIN = 7, - #[brw(magic(b"MFCA"))] - MFCA = 8, - #[brw(magic(b"MFIM"))] - MFIM = 9, - #[brw(magic(b"MTSM"))] - MTSM = 10, - #[brw(magic(b"MFRL"))] - MFRL = 11, - #[brw(magic(b"MFOE"))] - MFOE = 12, - #[brw(magic(b"MFOT"))] - MFOT = 13, - #[brw(magic(b"MFCI"))] - MFCI = 14, - #[brw(magic(b"MFOI"))] - MFOI = 15, - #[brw(magic(b"MFVA"))] - MFVA = 16, - #[brw(magic(b"MFSU"))] - MFSU = 17, - #[brw(magic(b"MFBP"))] - MFBP = 18, - #[brw(magic(b"MFBL"))] - MFBL = 19, - #[brw(magic(b"MFLB"))] - MFLB = 20, - #[brw(magic(b"MF1E"))] - MF1E = 21, - #[brw(magic(b"MFC0"))] - MFC0 = 22, - #[brw(magic(b"MFC1"))] - MFC1 = 23, - #[brw(magic(b"MFC2"))] - MFC2 = 24, - #[brw(magic(b"MFC3"))] - MFC3 = 25, - #[brw(magic(b"MFC4"))] - MFC4 = 26, -} - -fn decompress_gpu_buffers<'a>( - data: &'a [u8], - read_info: &[SModelReadBufferInfo], - buffer_info: &[SModelBufferInfo], -) -> Result>> { - let mut out = Vec::with_capacity(buffer_info.len()); - for info in buffer_info { - let read_info = &read_info[info.read_index as usize]; - let read_buffer = - &data[read_info.offset as usize..(read_info.offset + read_info.size) as usize]; - let comp_buf = &read_buffer[info.offset as usize..(info.offset + info.size) as usize]; - let (_, buf) = decompress_buffer(comp_buf, info.dest_size as u64)?; - out.push(buf); - } - Ok(out) -} - fn convert(args: ConvertArgs) -> Result<()> { let data = map_file(&args.input)?; - - let (cmdl_desc, mut cmdl_data, remain) = FormDescriptor::slice(&data, Endian::Little)?; - ensure!(cmdl_desc.id == K_FORM_CMDL); - ensure!(cmdl_desc.version_a == 114); - ensure!(cmdl_desc.version_b == 125); - let (foot_desc, mut foot_data, remain) = FormDescriptor::slice(remain, Endian::Little)?; - ensure!(foot_desc.id == K_FORM_FOOT); - ensure!(foot_desc.version_a == 1); - ensure!(foot_desc.version_b == 1); - ensure!(remain.is_empty()); - - let mut meta: Option = None; - while !foot_data.is_empty() { - let (desc, data, remain) = ChunkDescriptor::slice(foot_data, Endian::Little)?; - if desc.id == K_CHUNK_META { - meta = Some(Cursor::new(data).read_type(Endian::Little)?); - break; - } - foot_data = remain; - } - let Some(meta) = meta else { - bail!("Failed to locate meta chunk"); - }; - - let mut vtx_buffers = decompress_gpu_buffers(&data, &meta.read_info, &meta.vtx_buffer_info)?; - let idx_buffers = decompress_gpu_buffers(&data, &meta.read_info, &meta.idx_buffer_info)?; - - let mut head: Option = None; - let mut mtrl: Option = None; - let mut mesh: Option = None; - let mut vbuf: Option = None; - let mut ibuf: Option = None; - while !cmdl_data.is_empty() { - let (chunk_desc, chunk_data, remain) = ChunkDescriptor::slice(cmdl_data, Endian::Little)?; - match chunk_desc.id { - K_CHUNK_HEAD => head = Some(Cursor::new(chunk_data).read_type(Endian::Little)?), - K_CHUNK_MTRL => mtrl = Some(Cursor::new(chunk_data).read_type(Endian::Little)?), - K_CHUNK_MESH => mesh = Some(Cursor::new(chunk_data).read_type(Endian::Little)?), - K_CHUNK_VBUF => vbuf = Some(Cursor::new(chunk_data).read_type(Endian::Little)?), - K_CHUNK_IBUF => ibuf = Some(Cursor::new(chunk_data).read_type(Endian::Little)?), - // GPU data decompressed via META - K_CHUNK_GPU => {} - id => bail!("Unknown model chunk ID {id:?}"), - } - cmdl_data = remain; - } - - let Some(head) = head else { bail!("Failed to locate HEAD") }; - let Some(mtrl) = mtrl else { bail!("Failed to locate MTRL") }; - let Some(mesh) = mesh else { bail!("Failed to locate MESH") }; - let Some(vbuf) = vbuf else { bail!("Failed to locate VBUF") }; - let Some(ibuf) = ibuf else { bail!("Failed to locate IBUF") }; - - // log::debug!("HEAD: {head:#?}"); - // log::debug!("MTRL: {mtrl:#?}"); - // log::debug!("MESH: {mesh:#?}"); - // log::debug!("VBUF: {vbuf:#?}"); - // log::debug!("IBUF: {ibuf:#?}"); + let meta = locate_meta(&data, Endian::Little)?; + let ModelData { head, mtrl, mesh, vbuf, ibuf, mut vtx_buffers, idx_buffers } = + ModelData::slice(&data, meta, Endian::Little)?; // Build buffer to component index let mut buf_infos: Vec = Vec::with_capacity(vtx_buffers.len()); @@ -1566,7 +703,7 @@ fn convert(args: ConvertArgs) -> Result<()> { } _ => bail!("Unsupported data type for NRML"), }, - id => { + _id => { // log::debug!("Ignoring material data ID {id:?}"); continue; } diff --git a/src/cmd/fmv0.rs b/retrotool/src/cmd/fmv0.rs similarity index 97% rename from src/cmd/fmv0.rs rename to retrotool/src/cmd/fmv0.rs index 587c49a..aac2dc6 100644 --- a/src/cmd/fmv0.rs +++ b/retrotool/src/cmd/fmv0.rs @@ -8,9 +8,8 @@ use std::{ use anyhow::{ensure, Context, Result}; use argh::FromArgs; use binrw::Endian; - -use crate::{ - format::{pack::K_FORM_FOOT, rfrm::FormDescriptor, FourCC}, +use retrolib::{ + format::{foot::K_FORM_FOOT, rfrm::FormDescriptor, FourCC}, util::file::map_file, }; diff --git a/src/cmd/mod.rs b/retrotool/src/cmd/mod.rs similarity index 100% rename from src/cmd/mod.rs rename to retrotool/src/cmd/mod.rs diff --git a/src/cmd/pak.rs b/retrotool/src/cmd/pak.rs similarity index 96% rename from src/cmd/pak.rs rename to retrotool/src/cmd/pak.rs index 6a3d345..a4b2fcb 100644 --- a/src/cmd/pak.rs +++ b/retrotool/src/cmd/pak.rs @@ -2,20 +2,19 @@ use std::{ borrow::Cow, fmt::Debug, fs, - fs::File, + fs::{DirBuilder, File}, io::{BufWriter, Cursor, Write}, path::PathBuf, }; -use std::fs::DirBuilder; use anyhow::{bail, ensure, Context, Result}; use argh::FromArgs; use binrw::{BinReaderExt, BinWriterExt, Endian}; - -use crate::{ +use retrolib::{ format::{ chunk::ChunkDescriptor, - pack::{Asset, AssetInfo, Package, K_CHUNK_AINF, K_CHUNK_META, K_CHUNK_NAME, K_FORM_FOOT}, + foot::{K_CHUNK_AINF, K_CHUNK_NAME, K_FORM_FOOT}, + pack::{Asset, AssetInfo, Package, K_CHUNK_META}, rfrm::FormDescriptor, }, util::file::map_file, @@ -69,7 +68,7 @@ pub fn run(args: Args) -> Result<()> { fn extract(args: ExtractArgs) -> Result<()> { let data = map_file(args.input)?; - let package = Package::read(&data, Endian::Little)?; + let package = Package::read_full(&data, Endian::Little)?; for asset in &package.assets { let name = asset .name diff --git a/retrotool/src/cmd/txtr.rs b/retrotool/src/cmd/txtr.rs new file mode 100644 index 0000000..b8f41a5 --- /dev/null +++ b/retrotool/src/cmd/txtr.rs @@ -0,0 +1,80 @@ +use std::{ + fs::File, + io::{BufWriter, Write}, + path::PathBuf, +}; + +use anyhow::{bail, Context, Result}; +use argh::FromArgs; +use binrw::Endian; +use retrolib::{ + format::{foot::locate_meta, txtr::TextureData}, + util::{astc::write_astc, dds::write_dds, file::map_file}, +}; + +#[derive(FromArgs, PartialEq, Debug)] +/// process TXTR files +#[argh(subcommand, name = "txtr")] +pub struct Args { + #[argh(subcommand)] + command: SubCommand, +} + +#[derive(FromArgs, PartialEq, Debug)] +#[argh(subcommand)] +enum SubCommand { + Convert(ConvertArgs), +} + +#[derive(FromArgs, PartialEq, Eq, Debug)] +/// converts a TXTR file to DDS/ASTC +#[argh(subcommand, name = "convert")] +pub struct ConvertArgs { + #[argh(positional)] + /// input TXTR + input: PathBuf, + #[argh(switch, short = 'a')] + /// write ASTC file instead of DDS (no mips) + astc: bool, +} + +#[allow(unused)] +pub fn run(args: Args) -> Result<()> { + match args.command { + SubCommand::Convert(c_args) => convert(c_args), + } +} + +fn convert(args: ConvertArgs) -> Result<()> { + let data = map_file(&args.input)?; + let meta = locate_meta(&data, Endian::Little)?; + let TextureData { head, data } = TextureData::slice(&data, meta, Endian::Little)?; + + log::info!("Texture info:"); + log::info!(" Type: {:?}", head.kind); + log::info!(" Format: {:?}", head.format); + log::info!(" Size: {}x{}x{}", head.width, head.height, head.layers); + log::info!(" Mip count: {}", head.mip_sizes.len()); + + let path = if args.astc { + if !head.format.is_astc() { + bail!("Expected ASTC format, got {:?}", head.format); + } + args.input.with_extension("astc") + } else { + args.input.with_extension("dds") + }; + let mut file = BufWriter::new( + File::create(&path) + .with_context(|| format!("Failed to create output file '{}'", path.display()))?, + ); + log::info!("Writing {}", path.display()); + if args.astc { + write_astc(&mut file, &head, &data)?; + } else { + write_dds(&mut file, &head, data)?; + } + file.flush()?; + + Ok(()) +} diff --git a/src/main.rs b/retrotool/src/main.rs similarity index 97% rename from src/main.rs rename to retrotool/src/main.rs index e0a4de9..1c89ea7 100644 --- a/src/main.rs +++ b/retrotool/src/main.rs @@ -1,7 +1,5 @@ mod argh_version; mod cmd; -mod format; -mod util; use argh::FromArgs; diff --git a/src/cmd/txtr.rs b/src/cmd/txtr.rs deleted file mode 100644 index 319a914..0000000 --- a/src/cmd/txtr.rs +++ /dev/null @@ -1,141 +0,0 @@ -use std::{ - fs::File, - io::{BufWriter, Cursor, Write}, - path::PathBuf, -}; - -use anyhow::{anyhow, bail, ensure, Context, Result}; -use argh::FromArgs; -use binrw::{BinReaderExt, Endian}; - -use crate::{ - format::{ - chunk::ChunkDescriptor, - pack::{K_CHUNK_META, K_FORM_FOOT}, - rfrm::FormDescriptor, - txtr::{deswizzle, STextureHeader, STextureMetaData}, - FourCC, - }, - util::{astc::write_astc, dds::write_dds, file::map_file, lzss::decompress_into}, -}; - -// Texture -pub const K_FORM_TXTR: FourCC = FourCC(*b"TXTR"); -// Texture header -pub const K_CHUNK_HEAD: FourCC = FourCC(*b"HEAD"); -// GPU data -pub const K_CHUNK_GPU: FourCC = FourCC(*b"GPU "); - -#[derive(FromArgs, PartialEq, Debug)] -/// process TXTR files -#[argh(subcommand, name = "txtr")] -pub struct Args { - #[argh(subcommand)] - command: SubCommand, -} - -#[derive(FromArgs, PartialEq, Debug)] -#[argh(subcommand)] -enum SubCommand { - Convert(ConvertArgs), -} - -#[derive(FromArgs, PartialEq, Eq, Debug)] -/// converts a TXTR file to DDS/ASTC -#[argh(subcommand, name = "convert")] -pub struct ConvertArgs { - #[argh(positional)] - /// input TXTR - input: PathBuf, - #[argh(switch, short = 'a')] - /// write ASTC file instead of DDS (no mips) - astc: bool, -} - -#[allow(unused)] -pub fn run(args: Args) -> Result<()> { - match args.command { - SubCommand::Convert(c_args) => convert(c_args), - } -} - -fn convert(args: ConvertArgs) -> Result<()> { - let data = map_file(&args.input)?; - - let (txtr_desc, txtr_data, remain) = FormDescriptor::slice(&data, Endian::Little)?; - ensure!(txtr_desc.id == K_FORM_TXTR); - ensure!(txtr_desc.version_a == 47); - ensure!(txtr_desc.version_b == 51); - let (foot_desc, mut foot_data, remain) = FormDescriptor::slice(remain, Endian::Little)?; - ensure!(foot_desc.id == K_FORM_FOOT); - ensure!(foot_desc.version_a == 1); - ensure!(foot_desc.version_b == 1); - ensure!(remain.is_empty()); - - let mut meta: Option = None; - while !foot_data.is_empty() { - let (desc, data, remain) = ChunkDescriptor::slice(foot_data, Endian::Little)?; - if desc.id == K_CHUNK_META { - meta = Some(Cursor::new(data).read_type(Endian::Little)?); - break; - } - foot_data = remain; - } - let Some(meta) = meta else { - bail!("Failed to locate meta chunk"); - }; - - let (head_desc, head_data, remain) = ChunkDescriptor::slice(txtr_data, Endian::Little)?; - ensure!(head_desc.id == K_CHUNK_HEAD); - let head: STextureHeader = Cursor::new(head_data).read_type(Endian::Little)?; - let (gpu_desc, _, remain) = ChunkDescriptor::slice(remain, Endian::Little)?; - ensure!(gpu_desc.id == K_CHUNK_GPU); - ensure!(remain.is_empty()); - - log::debug!("META: {meta:#?}"); - log::debug!("HEAD: {head:#?}"); - - log::info!("Texture info:"); - log::info!(" Type: {:?}", head.kind); - log::info!(" Format: {:?}", head.format); - log::info!(" Size: {}x{}x{}", head.width, head.height, head.layers); - log::info!(" Mip count: {}", head.mip_sizes.len()); - - let mut buffer = vec![0u8; meta.decompressed_size as usize]; - for info in &meta.buffers { - let read = meta - .info - .iter() - .find(|i| i.index as u32 == info.index) - .ok_or_else(|| anyhow!("Failed to locate read info for buffer {}", info.index))?; - let read_buf = &data[read.offset as usize..(read.offset + read.size) as usize]; - let comp_buf = &read_buf[info.offset as usize..(info.offset + info.size) as usize]; - decompress_into( - comp_buf, - &mut buffer[info.dest_offset as usize..(info.dest_offset + info.dest_size) as usize], - )?; - } - - let deswizzled = deswizzle(&head, &buffer)?; - let path = if args.astc { - if !head.format.is_astc() { - bail!("Expected ASTC format, got {:?}", head.format); - } - args.input.with_extension("astc") - } else { - args.input.with_extension("dds") - }; - let mut file = BufWriter::new( - File::create(&path) - .with_context(|| format!("Failed to create output file '{}'", path.display()))?, - ); - log::info!("Writing {}", path.display()); - if args.astc { - write_astc(&mut file, &head, &deswizzled)?; - } else { - write_dds(&mut file, &head, deswizzled)?; - } - file.flush()?; - - Ok(()) -} diff --git a/src/util/lzss.rs b/src/util/lzss.rs deleted file mode 100644 index a3081ad..0000000 --- a/src/util/lzss.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::borrow::Cow; - -use anyhow::{bail, Result}; - -/// https://wiki.axiodl.com/w/LZSS_Compression -pub fn decompress(mut input: &[u8], output: &mut [u8]) -> bool { - let group_len = 2usize.pow(M as u32 - 1); - let mut out_cur = 0usize; - - let mut header_byte = 0u8; - let mut group = 0u8; - while !input.is_empty() { - if group == 0 { - header_byte = input[0]; - input = &input[1..]; - group = 8; - } - - if header_byte & 0x80 == 0 { - output[out_cur..group_len + out_cur].copy_from_slice(&input[..group_len]); - input = &input[group_len..]; - out_cur += group_len; - } else { - let count = (input[0] as usize >> 4) + (4 - M as usize); - let length = (((input[0] as usize & 0xF) << 0x8) | input[1] as usize) << (M - 1); - input = &input[2..]; - - let seek = out_cur - length; - for n in 0..count * group_len { - output[out_cur + n] = output[seek + n]; - } - out_cur += count * group_len; - } - - header_byte <<= 1; - group -= 1; - } - - out_cur == output.len() -} - -pub fn decompress_buffer( - compressed_data: &[u8], - decompressed_size: u64, -) -> Result<(u32, Cow<[u8]>)> { - if compressed_data.len() < 4 { - bail!("Invalid compressed data size: {}", compressed_data.len()); - } - if compressed_data[0..4] == [0u8; 4] { - // Shortcut for uncompressed data - return Ok((0, Cow::Borrowed(&compressed_data[4..]))); - } - let mut out = vec![0u8; decompressed_size as usize]; - let mode = decompress_into(compressed_data, &mut out)?; - Ok((mode, Cow::Owned(out))) -} - -pub fn decompress_into(compressed_data: &[u8], out: &mut [u8]) -> Result { - if compressed_data.len() < 4 { - bail!("Invalid compressed data size: {}", compressed_data.len()); - } - let mode = u32::from_le_bytes(compressed_data[0..4].try_into().unwrap()); - let data = &compressed_data[4..]; - if !match mode { - 0 => { - if data.len() == out.len() { - out.copy_from_slice(data); - true - } else { - false - } - } - 1 => decompress::<1>(data, out), - 2 => decompress::<2>(data, out), - 3 => decompress::<3>(data, out), - _ => bail!("Unsupported compression mode {}", mode), - } { - bail!("Decompression failed"); - } - Ok(mode) -}