summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock971
-rw-r--r--Makefile9
-rw-r--r--crates/renderer/Cargo.toml2
-rw-r--r--crates/renderer/src/assets.rs16
-rw-r--r--crates/renderer/src/assets/acs/bonzi.acsbin0 -> 5249795 bytes
-rw-r--r--crates/renderer/src/assets/acs/clippy.acsbin0 -> 2904417 bytes
-rw-r--r--crates/renderer/src/assets/acs/pikachu.acsbin0 -> 890717 bytes
-rw-r--r--crates/renderer/src/assets/shaders/acs/frag.glsl8
-rw-r--r--crates/renderer/src/assets/shaders/acs/vert.glsl4
-rw-r--r--crates/renderer/src/assets/shaders/flat_noflip/frag.glsl7
-rw-r--r--crates/renderer/src/assets/shaders/flat_noflip/vert.glsl4
-rw-r--r--crates/renderer/src/assets/textures/clippyborder.pngbin0 -> 1063 bytes
-rw-r--r--crates/renderer/src/assets/textures/combo/a.webpbin0 -> 1538 bytes
-rw-r--r--crates/renderer/src/assets/textures/combo/b.webpbin0 -> 1100 bytes
-rw-r--r--crates/renderer/src/assets/textures/combo/c.webpbin0 -> 1126 bytes
-rw-r--r--crates/renderer/src/assets/textures/combo/d.webpbin0 -> 1470 bytes
-rw-r--r--crates/renderer/src/assets/textures/combo/s.webpbin0 -> 1304 bytes
-rw-r--r--crates/renderer/src/assets/textures/combo/ss.webpbin0 -> 2068 bytes
-rw-r--r--crates/renderer/src/assets/textures/combo/sss.webpbin0 -> 2806 bytes
-rw-r--r--crates/renderer/src/ffi/egl.rs41
-rw-r--r--crates/renderer/src/ffi/glfw.rs7
-rw-r--r--crates/renderer/src/ffi/mod.rs2
-rw-r--r--crates/renderer/src/main.rs43
-rw-r--r--crates/renderer/src/overlay.rs21
-rw-r--r--crates/renderer/src/overlay/automata.rs6
-rw-r--r--crates/renderer/src/overlay/clippy.rs605
-rw-r--r--crates/renderer/src/overlay/combo.rs216
-rw-r--r--crates/renderer/src/overlay/model.rs2
-rw-r--r--crates/renderer/src/overlay/shader.rs32
-rw-r--r--crates/renderer/src/overlay/tcg.rs122
-rw-r--r--crates/renderer/src/texture_server.rs80
-rw-r--r--crates/renderer/src/toggle.rs4
-rw-r--r--crates/video_player/Cargo.toml20
-rw-r--r--crates/video_player/src/main.rs13
-rw-r--r--flake.lock12
-rw-r--r--flake.nix1
-rwxr-xr-xlaunch.sh11
37 files changed, 1675 insertions, 584 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5ee52a0..5c4811e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -31,7 +31,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
- "getrandom 0.2.15",
+ "getrandom 0.2.12",
"once_cell",
"version_check",
"zerocopy",
@@ -47,15 +47,6 @@ dependencies = [
]
[[package]]
-name = "aligned-vec"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b"
-dependencies = [
- "equator",
-]
-
-[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -161,12 +152,6 @@ dependencies = [
]
[[package]]
-name = "anyhow"
-version = "1.0.99"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
-
-[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -176,23 +161,6 @@ dependencies = [
]
[[package]]
-name = "arbitrary"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
-
-[[package]]
-name = "arg_enum_proc_macro"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "arrayref"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -223,29 +191,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
-name = "av1-grain"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f3efb2ca85bc610acfa917b5aaa36f3fcbebed5b3182d7f877b02531c4b80c8"
-dependencies = [
- "anyhow",
- "arrayvec",
- "log",
- "nom",
- "num-rational",
- "v_frame",
-]
-
-[[package]]
-name = "avif-serialize"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f"
-dependencies = [
- "arrayvec",
-]
-
-[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -292,7 +237,7 @@ dependencies = [
"bitflags 2.8.0",
"cexpr",
"clang-sys",
- "itertools 0.13.0",
+ "itertools",
"proc-macro2",
"quote",
"regex",
@@ -324,12 +269,27 @@ name = "bitflags"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
+dependencies = [
+ "serde",
+]
[[package]]
-name = "bitstream-io"
-version = "2.6.0"
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2"
+checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be"
+dependencies = [
+ "hybrid-array",
+]
[[package]]
name = "block-sys"
@@ -351,12 +311,6 @@ dependencies = [
]
[[package]]
-name = "built"
-version = "0.7.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b"
-
-[[package]]
name = "bumpalo"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -367,20 +321,6 @@ name = "bytemuck"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
-dependencies = [
- "bytemuck_derive",
-]
-
-[[package]]
-name = "bytemuck_derive"
-version = "1.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
[[package]]
name = "byteorder"
@@ -409,7 +349,7 @@ dependencies = [
"bitflags 2.8.0",
"log",
"polling",
- "rustix",
+ "rustix 0.38.44",
"slab",
"thiserror 1.0.69",
]
@@ -421,7 +361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02"
dependencies = [
"calloop",
- "rustix",
+ "rustix 0.38.44",
"wayland-backend",
"wayland-client",
]
@@ -453,16 +393,6 @@ dependencies = [
]
[[package]]
-name = "cfg-expr"
-version = "0.15.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
-dependencies = [
- "smallvec",
- "target-lexicon",
-]
-
-[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -564,6 +494,12 @@ dependencies = [
]
[[package]]
+name = "const-oid"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
+
+[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -588,7 +524,7 @@ dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-graphics-types",
- "foreign-types",
+ "foreign-types 0.5.0",
"libc",
]
@@ -624,29 +560,6 @@ dependencies = [
]
[[package]]
-name = "cosmic-text"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da46a9d5a8905cc538a4a5bceb6a4510de7a51049c5588c0114efce102bcbbe8"
-dependencies = [
- "bitflags 2.8.0",
- "fontdb",
- "log",
- "rangemap",
- "rustc-hash 1.1.0",
- "rustybuzz",
- "self_cell",
- "smol_str",
- "swash",
- "sys-locale",
- "ttf-parser 0.21.1",
- "unicode-bidi",
- "unicode-linebreak",
- "unicode-script",
- "unicode-segmentation",
-]
-
-[[package]]
name = "cpal"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -670,6 +583,24 @@ dependencies = [
]
[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "cpufeatures"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -741,6 +672,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
+name = "crypto-common"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710"
+dependencies = [
+ "hybrid-array",
+]
+
+[[package]]
name = "cursor-icon"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -756,6 +706,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
[[package]]
+name = "data-encoding"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
+
+[[package]]
name = "device_query"
version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -770,6 +726,27 @@ dependencies = [
]
[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer 0.10.4",
+ "crypto-common 0.1.7",
+]
+
+[[package]]
+name = "digest"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c"
+dependencies = [
+ "block-buffer 0.12.0",
+ "const-oid",
+ "crypto-common 0.2.1",
+]
+
+[[package]]
name = "directories"
version = "6.0.0"
source = "git+https://github.com/lcolonq/directories-rs#164536daab2c07265167715934081cb1942387b0"
@@ -786,7 +763,7 @@ dependencies = [
"libc",
"option-ext",
"redox_users",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -852,6 +829,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9"
dependencies = [
"enum-map-derive",
+ "serde",
]
[[package]]
@@ -889,26 +867,6 @@ dependencies = [
]
[[package]]
-name = "equator"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc"
-dependencies = [
- "equator-macro",
-]
-
-[[package]]
-name = "equator-macro"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -956,6 +914,12 @@ dependencies = [
]
[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
name = "fdeflate"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -981,25 +945,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
[[package]]
-name = "font-types"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39a654f404bbcbd48ea58c617c2993ee91d1cb63727a37bf2323a4edeed1b8c5"
-dependencies = [
- "bytemuck",
-]
-
-[[package]]
-name = "fontdb"
-version = "0.16.2"
+name = "foreign-types"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
- "log",
- "memmap2",
- "slotmap",
- "tinyvec",
- "ttf-parser 0.20.0",
+ "foreign-types-shared 0.1.1",
]
[[package]]
@@ -1009,7 +960,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
dependencies = [
"foreign-types-macros",
- "foreign-types-shared",
+ "foreign-types-shared 0.3.1",
]
[[package]]
@@ -1025,6 +976,12 @@ dependencies = [
[[package]]
name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "foreign-types-shared"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
@@ -1039,6 +996,16 @@ dependencies = [
]
[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
name = "gethostname"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1050,9 +1017,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.15"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if",
"js-sys",
@@ -1095,7 +1062,7 @@ dependencies = [
[[package]]
name = "glfw"
version = "0.59.0"
-source = "git+https://github.com/lcolonq/glfw-rs#1ce13a2bcf3ef3bf6184bcb4c2a90d9034956841"
+source = "git+https://github.com/lcolonq/glfw-rs#e7904991ea1ef6d34501d9d31c2d6f27b3ca957e"
dependencies = [
"bitflags 1.3.2",
"objc2 0.5.2",
@@ -1130,7 +1097,7 @@ dependencies = [
"base64 0.13.1",
"byteorder",
"gltf-json",
- "image",
+ "image 0.25.10",
"lazy_static",
"serde_json",
"urlencoding",
@@ -1206,9 +1173,25 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
-version = "0.4.0"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
+
+[[package]]
+name = "http"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
+dependencies = [
+ "bytes",
+ "itoa",
+]
+
+[[package]]
+name = "httparse"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "humantime"
@@ -1217,6 +1200,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
+name = "hybrid-array"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214"
+dependencies = [
+ "typenum",
+]
+
+[[package]]
name = "icrate"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1368,44 +1360,38 @@ dependencies = [
[[package]]
name = "image"
-version = "0.25.5"
+version = "0.24.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b"
+checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
dependencies = [
"bytemuck",
- "byteorder-lite",
+ "byteorder",
"color_quant",
"exr",
"gif",
- "image-webp",
+ "jpeg-decoder",
"num-traits",
- "png",
+ "png 0.17.16",
"qoi",
- "ravif",
- "rayon",
- "rgb",
"tiff",
- "zune-core",
- "zune-jpeg",
]
[[package]]
-name = "image-webp"
-version = "0.2.4"
+name = "image"
+version = "0.25.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3"
+checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104"
dependencies = [
+ "bytemuck",
"byteorder-lite",
- "quick-error",
+ "moxcms",
+ "num-traits",
+ "png 0.18.1",
+ "zune-core",
+ "zune-jpeg",
]
[[package]]
-name = "imgref"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
-
-[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1428,17 +1414,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a"
[[package]]
-name = "interpolate_name"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1446,15 +1421,6 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
@@ -1589,16 +1555,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
-name = "libfuzzer-sys"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404"
-dependencies = [
- "arbitrary",
- "cc",
-]
-
-[[package]]
name = "libloading"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1632,6 +1588,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
+name = "linux-raw-sys"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
+
+[[package]]
name = "litemap"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1644,15 +1606,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]]
-name = "loop9"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
-dependencies = [
- "imgref",
-]
-
-[[package]]
name = "mach2"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1682,16 +1635,6 @@ dependencies = [
]
[[package]]
-name = "maybe-rayon"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
-dependencies = [
- "cfg-if",
- "rayon",
-]
-
-[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1729,6 +1672,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff"
[[package]]
+name = "moxcms"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b"
+dependencies = [
+ "num-traits",
+ "pxfm",
+]
+
+[[package]]
name = "mutate_once"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1763,6 +1716,23 @@ dependencies = [
]
[[package]]
+name = "native-tls"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
+dependencies = [
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
+[[package]]
name = "ndk"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1793,12 +1763,6 @@ dependencies = [
]
[[package]]
-name = "new_debug_unreachable"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
-
-[[package]]
name = "newton_client"
version = "0.1.0"
dependencies = [
@@ -1806,6 +1770,7 @@ dependencies = [
"bitflags 2.8.0",
"clap",
"env_logger",
+ "getrandom 0.2.12",
"glam",
"glow",
"lazy_static",
@@ -1846,18 +1811,22 @@ dependencies = [
"clap",
"cpal",
"device_query",
+ "enum-map",
"env_logger",
"glam",
+ "glfw",
"glow",
- "image",
+ "image 0.24.9",
"lazy_static",
"lexpr",
+ "libc",
"log",
"newton_shader",
- "png",
+ "png 0.17.16",
"polling",
"rand",
"redis",
+ "sha2",
"strum",
"teleia",
"termion",
@@ -1886,6 +1855,21 @@ dependencies = [
]
[[package]]
+name = "newton_video_player"
+version = "0.1.0"
+dependencies = [
+ "bitflags 2.8.0",
+ "env_logger",
+ "glam",
+ "glow",
+ "lazy_static",
+ "log",
+ "rand",
+ "teleia",
+ "uuid",
+]
+
+[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1896,12 +1880,6 @@ dependencies = [
]
[[package]]
-name = "noop_proc_macro"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
-
-[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2056,6 +2034,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
[[package]]
+name = "openssl"
+version = "0.10.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
+dependencies = [
+ "bitflags 2.8.0",
+ "cfg-if",
+ "foreign-types 0.3.2",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.111"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2085,7 +2107,7 @@ version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4"
dependencies = [
- "ttf-parser 0.25.1",
+ "ttf-parser",
]
[[package]]
@@ -2152,18 +2174,30 @@ dependencies = [
]
[[package]]
+name = "png"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61"
+dependencies = [
+ "bitflags 2.8.0",
+ "crc32fast",
+ "fdeflate",
+ "flate2",
+ "miniz_oxide",
+]
+
+[[package]]
name = "polling"
-version = "3.7.4"
+version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f"
+checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi",
"pin-project-lite",
- "rustix",
- "tracing",
- "windows-sys 0.59.0",
+ "rustix 1.0.8",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -2213,6 +2247,12 @@ dependencies = [
]
[[package]]
+name = "pxfm"
+version = "0.1.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f"
+
+[[package]]
name = "qoi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2222,12 +2262,6 @@ dependencies = [
]
[[package]]
-name = "quick-error"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
-
-[[package]]
name = "quick-xml"
version = "0.37.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2272,16 +2306,10 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
- "getrandom 0.2.15",
+ "getrandom 0.2.12",
]
[[package]]
-name = "rangemap"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acbbbbea733ec66275512d0b9694f34102e7d5406fdbe2ad8d21b28dce92887c"
-
-[[package]]
name = "rapier3d"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2306,56 +2334,6 @@ dependencies = [
]
[[package]]
-name = "rav1e"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9"
-dependencies = [
- "arbitrary",
- "arg_enum_proc_macro",
- "arrayvec",
- "av1-grain",
- "bitstream-io",
- "built",
- "cfg-if",
- "interpolate_name",
- "itertools 0.12.1",
- "libc",
- "libfuzzer-sys",
- "log",
- "maybe-rayon",
- "new_debug_unreachable",
- "noop_proc_macro",
- "num-derive",
- "num-traits",
- "once_cell",
- "paste",
- "profiling",
- "rand",
- "rand_chacha",
- "simd_helpers",
- "system-deps",
- "thiserror 1.0.69",
- "v_frame",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "ravif"
-version = "0.11.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5825c26fddd16ab9f515930d49028a630efec172e903483c94796cfe31893e6b"
-dependencies = [
- "avif-serialize",
- "imgref",
- "loop9",
- "quick-error",
- "rav1e",
- "rayon",
- "rgb",
-]
-
-[[package]]
name = "raw-window-handle"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2388,16 +2366,6 @@ dependencies = [
]
[[package]]
-name = "read-fonts"
-version = "0.35.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358"
-dependencies = [
- "bytemuck",
- "font-types",
-]
-
-[[package]]
name = "readkey"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2455,7 +2423,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [
- "getrandom 0.2.15",
+ "getrandom 0.2.12",
"libredox",
"thiserror 2.0.11",
]
@@ -2490,12 +2458,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
-name = "rgb"
-version = "0.8.52"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
-
-[[package]]
name = "ringbuf"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2542,34 +2504,30 @@ dependencies = [
"bitflags 2.8.0",
"errno",
"libc",
- "linux-raw-sys",
+ "linux-raw-sys 0.4.15",
"windows-sys 0.59.0",
]
[[package]]
-name = "rustversion"
-version = "1.0.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
-
-[[package]]
-name = "rustybuzz"
-version = "0.14.1"
+name = "rustix"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c"
+checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
dependencies = [
"bitflags 2.8.0",
- "bytemuck",
- "libm",
- "smallvec",
- "ttf-parser 0.21.1",
- "unicode-bidi-mirroring",
- "unicode-ccc",
- "unicode-properties",
- "unicode-script",
+ "errno",
+ "libc",
+ "linux-raw-sys 0.9.4",
+ "windows-sys 0.59.0",
]
[[package]]
+name = "rustversion"
+version = "1.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
+
+[[package]]
name = "ryu"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2594,6 +2552,15 @@ dependencies = [
]
[[package]]
+name = "schannel"
+version = "0.1.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2613,10 +2580,27 @@ dependencies = [
]
[[package]]
-name = "self_cell"
-version = "1.2.1"
+name = "security-framework"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
+dependencies = [
+ "bitflags 2.8.0",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33"
+checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
[[package]]
name = "send_wrapper"
@@ -2626,18 +2610,28 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
[[package]]
name = "serde"
-version = "1.0.217"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.217"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
@@ -2657,12 +2651,14 @@ dependencies = [
]
[[package]]
-name = "serde_spanned"
-version = "0.6.9"
+name = "sha1"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
- "serde",
+ "cfg-if",
+ "cpufeatures 0.2.17",
+ "digest 0.10.7",
]
[[package]]
@@ -2672,6 +2668,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d"
[[package]]
+name = "sha2"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.3.0",
+ "digest 0.11.2",
+]
+
+[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2706,15 +2713,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
-name = "simd_helpers"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
-dependencies = [
- "quote",
-]
-
-[[package]]
name = "simple-eyre"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2725,16 +2723,6 @@ dependencies = [
]
[[package]]
-name = "skrifa"
-version = "0.37.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841"
-dependencies = [
- "bytemuck",
- "read-fonts",
-]
-
-[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2771,7 +2759,7 @@ dependencies = [
"libc",
"log",
"memmap2",
- "rustix",
+ "rustix 0.38.44",
"thiserror 1.0.69",
"wayland-backend",
"wayland-client",
@@ -2855,17 +2843,6 @@ dependencies = [
]
[[package]]
-name = "swash"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a"
-dependencies = [
- "skrifa",
- "yazi",
- "zeno",
-]
-
-[[package]]
name = "symphonia"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2983,34 +2960,6 @@ dependencies = [
]
[[package]]
-name = "sys-locale"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "system-deps"
-version = "6.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
-dependencies = [
- "cfg-expr",
- "heck",
- "pkg-config",
- "toml",
- "version-compare",
-]
-
-[[package]]
-name = "target-lexicon"
-version = "0.12.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
-
-[[package]]
name = "teleia"
version = "0.1.0"
dependencies = [
@@ -3022,16 +2971,15 @@ dependencies = [
"bytes",
"console_error_panic_hook",
"console_log",
- "cosmic-text",
"directories",
"enum-map",
"env_logger",
- "getrandom 0.2.15",
+ "getrandom 0.2.12",
"glam",
"glfw",
"glow",
"gltf",
- "image",
+ "image 0.25.10",
"js-sys",
"kira",
"log",
@@ -3046,6 +2994,7 @@ dependencies = [
"strum",
"tobj",
"tracing-wasm",
+ "tungstenite",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
@@ -3053,6 +3002,19 @@ dependencies = [
]
[[package]]
+name = "tempfile"
+version = "3.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
+dependencies = [
+ "fastrand",
+ "getrandom 0.3.1",
+ "once_cell",
+ "rustix 1.0.8",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
name = "termion"
version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3161,21 +3123,6 @@ dependencies = [
]
[[package]]
-name = "tinyvec"
-version = "1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
-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 = "tobj"
version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3185,25 +3132,10 @@ dependencies = [
]
[[package]]
-name = "toml"
-version = "0.8.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
-dependencies = [
- "serde",
- "serde_spanned",
- "toml_datetime",
- "toml_edit",
-]
-
-[[package]]
name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
-dependencies = [
- "serde",
-]
[[package]]
name = "toml_edit"
@@ -3212,8 +3144,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
dependencies = [
"indexmap",
- "serde",
- "serde_spanned",
"toml_datetime",
"winnow",
]
@@ -3282,21 +3212,28 @@ dependencies = [
[[package]]
name = "ttf-parser"
-version = "0.20.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
-
-[[package]]
-name = "ttf-parser"
-version = "0.21.1"
+version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
+checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
[[package]]
-name = "ttf-parser"
-version = "0.25.1"
+name = "tungstenite"
+version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
+checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a"
+dependencies = [
+ "byteorder",
+ "bytes",
+ "data-encoding",
+ "http",
+ "httparse",
+ "log",
+ "native-tls",
+ "rand",
+ "sha1",
+ "thiserror 1.0.69",
+ "utf-8",
+]
[[package]]
name = "typenum"
@@ -3305,48 +3242,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
-name = "unicode-bidi"
-version = "0.3.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
-
-[[package]]
-name = "unicode-bidi-mirroring"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86"
-
-[[package]]
-name = "unicode-ccc"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656"
-
-[[package]]
name = "unicode-ident"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
[[package]]
-name = "unicode-linebreak"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
-
-[[package]]
-name = "unicode-properties"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d"
-
-[[package]]
-name = "unicode-script"
-version = "0.5.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f"
-
-[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3376,6 +3277,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
name = "utf16_iter"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3405,21 +3312,10 @@ dependencies = [
]
[[package]]
-name = "v_frame"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2"
-dependencies = [
- "aligned-vec",
- "num-traits",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "version-compare"
-version = "0.2.0"
+name = "vcpkg"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
@@ -3537,7 +3433,7 @@ checksum = "b7208998eaa3870dad37ec8836979581506e0c5c64c20c9e79e9d2a10d6f47bf"
dependencies = [
"cc",
"downcast-rs",
- "rustix",
+ "rustix 0.38.44",
"scoped-tls",
"smallvec",
"wayland-sys",
@@ -3550,7 +3446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f"
dependencies = [
"bitflags 2.8.0",
- "rustix",
+ "rustix 0.38.44",
"wayland-backend",
"wayland-scanner",
]
@@ -3572,7 +3468,7 @@ version = "0.31.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a93029cbb6650748881a00e4922b076092a6a08c11e7fbdb923f064b23968c5d"
dependencies = [
- "rustix",
+ "rustix 0.38.44",
"wayland-client",
"xcursor",
]
@@ -3649,7 +3545,7 @@ dependencies = [
"jpeg-decoder",
"jpeg-encoder",
"kamadak-exif",
- "png",
+ "png 0.17.16",
"thiserror 1.0.69",
]
@@ -3750,6 +3646,12 @@ dependencies = [
]
[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
name = "windows-result"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3795,6 +3697,15 @@ dependencies = [
]
[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4001,7 +3912,7 @@ dependencies = [
"percent-encoding",
"raw-window-handle",
"redox_syscall 0.3.5",
- "rustix",
+ "rustix 0.38.44",
"sctk-adwaita",
"serde",
"smithay-client-toolkit",
@@ -4083,7 +3994,7 @@ dependencies = [
"libc",
"libloading",
"once_cell",
- "rustix",
+ "rustix 0.38.44",
"x11rb-protocol",
]
@@ -4119,12 +4030,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56"
[[package]]
-name = "yazi"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5"
-
-[[package]]
name = "yoke"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4149,12 +4054,6 @@ dependencies = [
]
[[package]]
-name = "zeno"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"
-
-[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4220,9 +4119,9 @@ dependencies = [
[[package]]
name = "zune-core"
-version = "0.4.12"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
+checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9"
[[package]]
name = "zune-inflate"
@@ -4235,9 +4134,9 @@ dependencies = [
[[package]]
name = "zune-jpeg"
-version = "0.4.14"
+version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028"
+checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296"
dependencies = [
"zune-core",
]
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 3cddfcd..0000000
--- a/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-CARGO_OPTS = --config 'patch."https://github.com/lcolonq/teleia".teleia.path="../teleia/crates/teleia"'
-
-.PHONY: build
-
-build:
- @mkdir -p .tmp/
- @cp Cargo.lock .tmp/Cargo.lock
- @cargo build $(CARGO_OPTS)
- @cp .tmp/Cargo.lock Cargo.lock
diff --git a/crates/renderer/Cargo.toml b/crates/renderer/Cargo.toml
index 8c98cd4..3f197e9 100644
--- a/crates/renderer/Cargo.toml
+++ b/crates/renderer/Cargo.toml
@@ -31,4 +31,4 @@ png = { workspace = true }
cpal = { workspace = true }
redis = { workspace = true }
web-image-meta = { workspace = true }
-uuid = { workspace = true } \ No newline at end of file
+uuid = { workspace = true }
diff --git a/crates/renderer/src/assets.rs b/crates/renderer/src/assets.rs
index bfcaa0d..4eb681a 100644
--- a/crates/renderer/src/assets.rs
+++ b/crates/renderer/src/assets.rs
@@ -3,6 +3,8 @@ use teleia::*;
pub struct Assets {
pub font: font::Bitmap,
pub shader_flat: shader::Shader,
+ pub shader_flat_noflip: shader::Shader,
+ pub shader_acs: shader::Shader,
pub shader_scene: shader::Shader,
pub shader_color: shader::Shader,
pub shader_tcg: shader::Shader,
@@ -13,17 +15,28 @@ pub struct Assets {
pub texture_mod: texture::Texture,
pub texture_operatop: texture::Texture,
pub texture_operabottom: texture::Texture,
+ pub texture_clippyborder: texture::Texture,
}
impl Assets {
pub fn new(ctx: &context::Context) -> Self {
Self {
- font: font::Bitmap::new(ctx),
+ font: font::Bitmap::default(ctx),
shader_flat: shader::Shader::new(
ctx,
include_str!("assets/shaders/flat/vert.glsl"),
include_str!("assets/shaders/flat/frag.glsl"),
),
+ shader_flat_noflip: shader::Shader::new(
+ ctx,
+ include_str!("assets/shaders/flat_noflip/vert.glsl"),
+ include_str!("assets/shaders/flat_noflip/frag.glsl"),
+ ),
+ shader_acs: shader::Shader::new(
+ ctx,
+ include_str!("assets/shaders/acs/vert.glsl"),
+ include_str!("assets/shaders/acs/frag.glsl"),
+ ),
shader_scene: shader::Shader::new(
ctx,
include_str!("assets/shaders/scene/vert.glsl"),
@@ -58,6 +71,7 @@ impl Assets {
texture_mod: texture::Texture::new(ctx, include_bytes!("assets/textures/mod.png")),
texture_operatop: texture::Texture::new(ctx, include_bytes!("assets/textures/operatop.png")),
texture_operabottom: texture::Texture::new(ctx, include_bytes!("assets/textures/operabottom.png")),
+ texture_clippyborder: texture::Texture::new(ctx, include_bytes!("assets/textures/clippyborder.png")),
}
}
}
diff --git a/crates/renderer/src/assets/acs/bonzi.acs b/crates/renderer/src/assets/acs/bonzi.acs
new file mode 100644
index 0000000..b463dc8
--- /dev/null
+++ b/crates/renderer/src/assets/acs/bonzi.acs
Binary files differ
diff --git a/crates/renderer/src/assets/acs/clippy.acs b/crates/renderer/src/assets/acs/clippy.acs
new file mode 100644
index 0000000..0dbc388
--- /dev/null
+++ b/crates/renderer/src/assets/acs/clippy.acs
Binary files differ
diff --git a/crates/renderer/src/assets/acs/pikachu.acs b/crates/renderer/src/assets/acs/pikachu.acs
new file mode 100644
index 0000000..4e7615d
--- /dev/null
+++ b/crates/renderer/src/assets/acs/pikachu.acs
Binary files differ
diff --git a/crates/renderer/src/assets/shaders/acs/frag.glsl b/crates/renderer/src/assets/shaders/acs/frag.glsl
new file mode 100644
index 0000000..8fba8bf
--- /dev/null
+++ b/crates/renderer/src/assets/shaders/acs/frag.glsl
@@ -0,0 +1,8 @@
+uniform sampler2D texture_data;
+
+void main()
+{
+ vec2 tcfull = vec2(vertex_texcoord.x, vertex_texcoord.y);
+ vec4 texel = texture(texture_data, tcfull);
+ frag_color = texel;
+}
diff --git a/crates/renderer/src/assets/shaders/acs/vert.glsl b/crates/renderer/src/assets/shaders/acs/vert.glsl
new file mode 100644
index 0000000..e324f7e
--- /dev/null
+++ b/crates/renderer/src/assets/shaders/acs/vert.glsl
@@ -0,0 +1,4 @@
+void main()
+{
+ default_main();
+} \ No newline at end of file
diff --git a/crates/renderer/src/assets/shaders/flat_noflip/frag.glsl b/crates/renderer/src/assets/shaders/flat_noflip/frag.glsl
new file mode 100644
index 0000000..e20995c
--- /dev/null
+++ b/crates/renderer/src/assets/shaders/flat_noflip/frag.glsl
@@ -0,0 +1,7 @@
+uniform sampler2D texture_data;
+
+void main()
+{
+ vec4 texel = texture(texture_data, vertex_texcoord);
+ frag_color = texel;
+}
diff --git a/crates/renderer/src/assets/shaders/flat_noflip/vert.glsl b/crates/renderer/src/assets/shaders/flat_noflip/vert.glsl
new file mode 100644
index 0000000..e324f7e
--- /dev/null
+++ b/crates/renderer/src/assets/shaders/flat_noflip/vert.glsl
@@ -0,0 +1,4 @@
+void main()
+{
+ default_main();
+} \ No newline at end of file
diff --git a/crates/renderer/src/assets/textures/clippyborder.png b/crates/renderer/src/assets/textures/clippyborder.png
new file mode 100644
index 0000000..3bb3089
--- /dev/null
+++ b/crates/renderer/src/assets/textures/clippyborder.png
Binary files differ
diff --git a/crates/renderer/src/assets/textures/combo/a.webp b/crates/renderer/src/assets/textures/combo/a.webp
new file mode 100644
index 0000000..15d4042
--- /dev/null
+++ b/crates/renderer/src/assets/textures/combo/a.webp
Binary files differ
diff --git a/crates/renderer/src/assets/textures/combo/b.webp b/crates/renderer/src/assets/textures/combo/b.webp
new file mode 100644
index 0000000..3eec6b1
--- /dev/null
+++ b/crates/renderer/src/assets/textures/combo/b.webp
Binary files differ
diff --git a/crates/renderer/src/assets/textures/combo/c.webp b/crates/renderer/src/assets/textures/combo/c.webp
new file mode 100644
index 0000000..1babbdf
--- /dev/null
+++ b/crates/renderer/src/assets/textures/combo/c.webp
Binary files differ
diff --git a/crates/renderer/src/assets/textures/combo/d.webp b/crates/renderer/src/assets/textures/combo/d.webp
new file mode 100644
index 0000000..1d08e9c
--- /dev/null
+++ b/crates/renderer/src/assets/textures/combo/d.webp
Binary files differ
diff --git a/crates/renderer/src/assets/textures/combo/s.webp b/crates/renderer/src/assets/textures/combo/s.webp
new file mode 100644
index 0000000..faec75a
--- /dev/null
+++ b/crates/renderer/src/assets/textures/combo/s.webp
Binary files differ
diff --git a/crates/renderer/src/assets/textures/combo/ss.webp b/crates/renderer/src/assets/textures/combo/ss.webp
new file mode 100644
index 0000000..62fec55
--- /dev/null
+++ b/crates/renderer/src/assets/textures/combo/ss.webp
Binary files differ
diff --git a/crates/renderer/src/assets/textures/combo/sss.webp b/crates/renderer/src/assets/textures/combo/sss.webp
new file mode 100644
index 0000000..f1ecb80
--- /dev/null
+++ b/crates/renderer/src/assets/textures/combo/sss.webp
Binary files differ
diff --git a/crates/renderer/src/ffi/egl.rs b/crates/renderer/src/ffi/egl.rs
new file mode 100644
index 0000000..33a39d4
--- /dev/null
+++ b/crates/renderer/src/ffi/egl.rs
@@ -0,0 +1,41 @@
+// from <EGL/egl.h>
+pub const EGL_NONE: EGLenum = 0x3038;
+pub const EGL_WIDTH: EGLenum = 0x3057;
+pub const EGL_HEIGHT: EGLenum = 0x3056;
+
+// from <EGL/eglext.h>
+pub const EGL_LINUX_DMA_BUF_EXT: EGLenum = 0x3270;
+pub const EGL_LINUX_DRM_FOURCC_EXT: EGLenum = 0x3271;
+pub const EGL_DMA_BUF_PLANE0_FD_EXT: EGLenum = 0x3272;
+pub const EGL_DMA_BUF_PLANE0_OFFSET_EXT: EGLenum = 0x3273;
+pub const EGL_DMA_BUF_PLANE0_PITCH_EXT: EGLenum = 0x3274;
+
+#[repr(C)]
+pub struct EGLDisplayTarget(());
+pub type EGLDisplay = *mut EGLDisplayTarget;
+
+#[repr(C)]
+pub struct EGLContextTarget(());
+pub type EGLContext = *mut EGLContextTarget;
+
+#[repr(C)]
+pub struct EGLClientBufferTarget(());
+pub type EGLClientBuffer = *mut EGLClientBufferTarget;
+
+#[repr(C)]
+pub struct EGLImageTarget(());
+pub type EGLImage = *mut EGLImageTarget;
+
+pub type EGLenum = core::ffi::c_uint;
+
+pub type EGLAttrib = libc::intptr_t;
+
+#[link(name = "EGL")]
+extern "C" {
+ pub fn eglCreateImage(d: EGLDisplay, c: EGLContext, t: EGLenum, buf: EGLClientBuffer, attribs: *const EGLAttrib) -> EGLImage;
+}
+
+#[link(name = "GL")]
+extern "C" {
+ pub fn glEGLImageTargetTexture2DOES(t: u32, img: EGLImage);
+}
diff --git a/crates/renderer/src/ffi/glfw.rs b/crates/renderer/src/ffi/glfw.rs
new file mode 100644
index 0000000..1b79089
--- /dev/null
+++ b/crates/renderer/src/ffi/glfw.rs
@@ -0,0 +1,7 @@
+use super::egl::*;
+
+#[link(name = "glfw")]
+extern "C" {
+ pub fn glfwGetEGLDisplay() -> EGLDisplay;
+ pub fn glfwGetEGLContext(w: *mut glfw::ffi::GLFWwindow) -> EGLContext;
+}
diff --git a/crates/renderer/src/ffi/mod.rs b/crates/renderer/src/ffi/mod.rs
new file mode 100644
index 0000000..a98fd71
--- /dev/null
+++ b/crates/renderer/src/ffi/mod.rs
@@ -0,0 +1,2 @@
+pub mod egl;
+pub mod glfw;
diff --git a/crates/renderer/src/main.rs b/crates/renderer/src/main.rs
index ae8cc03..b71a836 100644
--- a/crates/renderer/src/main.rs
+++ b/crates/renderer/src/main.rs
@@ -1,3 +1,6 @@
+#![feature(unix_socket_ancillary_data)]
+#![feature(str_from_utf16_endian)]
+#![feature(try_blocks)]
#![allow(dead_code, unused_variables)]
mod assets;
mod terminal;
@@ -5,9 +8,12 @@ mod background;
mod toggle;
mod overlay;
mod input;
+mod ffi;
+mod texture_server;
use teleia::*;
-use clap::{command, Command};
+use clap::{command, Command, Arg};
+use std::io::Write as _;
pub fn main() -> Erm<()> {
let matches = command!()
@@ -22,6 +28,16 @@ pub fn main() -> Erm<()> {
Command::new("model-terminal")
.about("Run the LCOLONQ model renderer in a terminal")
)
+ .subcommand(
+ Command::new("validate-card")
+ .arg(Arg::new("path"))
+ .about("Validate the TCG card at the given path.")
+ )
+ .subcommand(
+ Command::new("repair-card")
+ .arg(Arg::new("path"))
+ .about("Repair the TCG card at the given path.")
+ )
.get_matches();
match matches.subcommand() {
Some(("overlay", _cm)) => {
@@ -29,8 +45,10 @@ pub fn main() -> Erm<()> {
overlay::Overlays::new(ctx, vec![
Box::new(overlay::automata::Overlay::new(ctx)),
Box::new(overlay::shader::Overlay::new(ctx)),
- Box::new(overlay::drawing::Overlay::new(ctx)),
Box::new(overlay::tcg::Overlay::new(ctx)),
+ Box::new(overlay::clippy::Overlay::new(ctx)),
+ Box::new(overlay::combo::Overlay::new(ctx)),
+ Box::new(overlay::drawing::Overlay::new(ctx)),
// Box::new(overlay::model::Overlay::new(ctx)),
// Box::new(overlay::loopback::Overlay::new(ctx)),
])
@@ -39,6 +57,27 @@ pub fn main() -> Erm<()> {
Some(("model-terminal", _cm)) => {
teleia::run("LCOLONQ", 1920, 1080, teleia::Options::HIDDEN, overlay::model::Terminal::new)?;
},
+ Some(("validate-card", cm)) => {
+ if let Some(path) = cm.get_one::<String>("path") {
+ if overlay::tcg::validate_card(&std::fs::read(path)?)? {
+ println!("signatures match!");
+ std::process::exit(0);
+ } else {
+ println!("signatures do not match");
+ std::process::exit(1);
+ }
+ } else {
+ eprintln!("no path specified");
+ }
+ },
+ Some(("repair-card", cm)) => {
+ if let Some(path) = cm.get_one::<String>("path") {
+ let res = overlay::tcg::repair_card(&std::fs::read(path)?)?;
+ std::io::stdout().write_all(&res)?;
+ } else {
+ eprintln!("no path specified");
+ }
+ },
_ => unreachable!("no subcommand"),
}
Ok(())
diff --git a/crates/renderer/src/overlay.rs b/crates/renderer/src/overlay.rs
index 049d788..5abeb04 100644
--- a/crates/renderer/src/overlay.rs
+++ b/crates/renderer/src/overlay.rs
@@ -4,13 +4,17 @@ pub mod drawing;
pub mod automata;
pub mod tcg;
pub mod loopback;
+pub mod clippy;
+pub mod combo;
+use redis::Commands;
use teleia::*;
use std::f32::consts::PI;
use byteorder::{LE, ReadBytesExt};
+use sha2::Digest;
-use crate::{assets, fig, toggle, input, background};
+use crate::{assets, background, input, net::fig, texture_server, toggle};
pub struct Chat {
author: String,
@@ -49,6 +53,7 @@ pub struct State {
model: scene::Scene,
model_neck_base: glam::Mat4,
fig_binary: fig::BinaryClient,
+ texture_server: texture_server::Server,
tracking: Tracking,
info: Info,
chat: Chat,
@@ -87,7 +92,12 @@ impl State {
b"overlay shader chat",
b"overlay automata spawn",
b"overlay tcg generate",
+ b"overlay clippy animate",
+ b"overlay clippy border on",
+ b"overlay clippy border off",
+ b"overlay combo message",
]).expect("failed to connect to bus"),
+ texture_server: texture_server::Server::new(ctx),
tracking: Tracking {
eyes: (1.0, 1.0),
mouth: 0.0,
@@ -121,6 +131,7 @@ impl State {
if let Some(n) = self.model.nodes_by_name.get("J_Bip_C_Neck").and_then(|i| self.model.nodes.get_mut(*i)) {
n.transform = self.model_neck_base * glam::Mat4::from_quat(self.tracking.neck);
}
+ self.texture_server.update(ctx);
Ok(())
}
}
@@ -256,6 +267,14 @@ impl teleia::state::Game for Overlays {
for ov in self.overlays.iter_mut() {
ov.render(ctx, st, &mut self.state)?;
}
+ // st.bind_2d(ctx, &self.state.assets.shader_flat);
+ // self.state.assets.shader_flat.set_f32(ctx, "transparency", 0.0);
+ // self.state.assets.shader_flat.set_position_2d(ctx, st,
+ // &glam::Vec2::new(0.0, 0.0),
+ // &glam::Vec2::new(200.0, 200.0),
+ // );
+ // self.state.texture_server.tex.bind(ctx);
+ // st.mesh_square.render(ctx);
Ok(())
}
}
diff --git a/crates/renderer/src/overlay/automata.rs b/crates/renderer/src/overlay/automata.rs
index 224a783..f48ed9d 100644
--- a/crates/renderer/src/overlay/automata.rs
+++ b/crates/renderer/src/overlay/automata.rs
@@ -249,13 +249,13 @@ impl overlay::Overlay for Overlay {
}
fn handle_binary(
&mut self, ctx: &context::Context, st: &mut state::State, _ost: &mut overlay::State,
- msg: &fig::BinaryMessage,
+ msg: &net::fig::BinaryMessage,
) -> Erm<()> {
if msg.event == b"overlay automata spawn" {
let res: Erm<()> = (|| {
let mut reader = std::io::Cursor::new(&msg.data);
- let rle = fig::read_length_prefixed_utf8(&mut reader)?;
- let _user = fig::read_length_prefixed_utf8(&mut reader)?;
+ let rle = net::fig::read_length_prefixed_utf8(&mut reader)?;
+ let _user = net::fig::read_length_prefixed_utf8(&mut reader)?;
let col = reader.read_u32::<LE>()?;
log::info!("col: {}", col);
let r = (col >> 16 & 0xff) as u8;
diff --git a/crates/renderer/src/overlay/clippy.rs b/crates/renderer/src/overlay/clippy.rs
new file mode 100644
index 0000000..e1ddb0e
--- /dev/null
+++ b/crates/renderer/src/overlay/clippy.rs
@@ -0,0 +1,605 @@
+use teleia::*;
+
+use crate::overlay;
+
+use rand::Rng;
+use std::{collections::HashMap, io::{Seek, SeekFrom}};
+use byteorder::{LE, ReadBytesExt};
+
+struct Bitstream {
+ bytes: Vec<u8>,
+ idx: usize,
+ bidx: usize,
+}
+impl Bitstream {
+ pub fn new(bytes: Vec<u8>) -> Self { Self { bytes, idx: 0, bidx: 0 } }
+ fn pop_bit(&mut self) -> Option<bool> {
+ let w = self.bytes.get(self.idx)?;
+ let ret = (w >> self.bidx) & 0b1;
+ self.bidx += 1;
+ if self.bidx > 7 { self.bidx = 0; self.idx += 1; }
+ Some(ret == 1)
+ }
+ fn pop_bits(&mut self, count: usize) -> Option<u32> {
+ let mut ret = 0;
+ for shift in 0..count {
+ ret |= (self.pop_bit()? as u32) << shift;
+ }
+ Some(ret)
+ }
+ fn pop_byte(&mut self) -> Option<u8> { Some(self.pop_bits(8)? as u8) }
+}
+
+fn decompress(bytes: Vec<u8>) -> Option<Vec<u8>> {
+ let mut ret = Vec::new();
+ let mut bits = Bitstream::new(bytes);
+ if bits.pop_byte()? != 0 {
+ panic!("no leading 0 byte");
+ }
+ while let Some(bty) = bits.pop_bit() { match bty {
+ false => ret.push(bits.pop_byte()?),
+ true => {
+ let mut bytes_to_read = 2;
+ let mut off_sequential_ones = 0;
+ for _ in 0..3 {
+ if bits.pop_bit()? { off_sequential_ones += 1; }
+ else { break; }
+ }
+ let (bitcount, addend) = match off_sequential_ones {
+ 0 => (6, 1),
+ 1 => (9, 65),
+ 2 => (12, 577),
+ 3 => (20, 4673),
+ _ => unreachable!("bad sequential bits"),
+ };
+ let mut num = bits.pop_bits(bitcount)?;
+ if bitcount == 20 {
+ if num == 0x000FFFFF { break; }
+ else { bytes_to_read += 1; }
+ }
+ num += addend;
+ let idx = ret.len() - num as usize;
+ let mut sequential_ones = 0;
+ for i in 0..12 {
+ if i == 11 {
+ if bits.pop_bit()? { panic!("malformed data! expected 0-bit terminator!"); }
+ break;
+ } else {
+ if bits.pop_bit()? { sequential_ones += 1; } else { break; }
+ }
+ }
+ bytes_to_read += (1 << sequential_ones) - 1;
+ bytes_to_read += bits.pop_bits(sequential_ones)? as usize;
+ for i in 0..bytes_to_read {
+ ret.push(ret[idx + i]);
+ }
+ },
+ }}
+ Some(ret)
+}
+
+fn parse_string<R>(r: &mut R) -> Erm<String> where R: ReadBytesExt + Seek {
+ let len = r.read_u32::<LE>()?; // account for null terminator
+ if len == 0 { return Ok(String::new()) }
+ let mut bs = vec![0; (len * 2 + 2) as usize];
+ r.read_exact(&mut bs)?;
+ Ok(String::from_utf16le(&bs[0..bs.len() - 2])?)
+}
+
+type RGB = [u8; 3];
+fn parse_rgb<R>(r: &mut R) -> Erm<RGB> where R: ReadBytesExt + Seek {
+ let cb = r.read_u8()?;
+ let cg = r.read_u8()?;
+ let cr = r.read_u8()?;
+ let _ = r.read_u8()?;
+ Ok([cr, cg, cb])
+}
+
+#[derive(Debug)]
+struct Locator {
+ offset: u32,
+ size: u32,
+}
+impl Locator {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ Ok(Self {
+ offset: r.read_u32::<LE>()?,
+ size: r.read_u32::<LE>()?,
+ })
+ }
+ fn seek<R>(&self, r: &mut R) -> Erm<()> where R: Seek {
+ r.seek(SeekFrom::Start(self.offset as _))?;
+ Ok(())
+ }
+}
+
+#[derive(Debug)]
+struct GUID(u32, u16, u16, [u8; 8]);
+impl GUID {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ Ok(Self(
+ r.read_u32::<LE>()?,
+ r.read_u16::<LE>()?,
+ r.read_u16::<LE>()?,
+ [ r.read_u8()?, r.read_u8()?, r.read_u8()?, r.read_u8()?,
+ r.read_u8()?, r.read_u8()?, r.read_u8()?, r.read_u8()? ]
+ ))
+ }
+}
+
+#[derive(Debug)]
+struct VoiceInfoExtra {
+ lang_id: u16,
+ dialect: String,
+ gender: u16,
+ age: u16,
+ style: String,
+}
+impl VoiceInfoExtra {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ Ok(Self {
+ lang_id: r.read_u16::<LE>()?,
+ dialect: parse_string(r)?,
+ gender: r.read_u16::<LE>()?,
+ age: r.read_u16::<LE>()?,
+ style: parse_string(r)?,
+ })
+ }
+}
+#[derive(Debug)]
+struct VoiceInfo {
+ engine_id: GUID,
+ mode_id: GUID,
+ speed: u32,
+ pitch: u16,
+ extra: Option<VoiceInfoExtra>,
+}
+impl VoiceInfo {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ let engine_id = GUID::parse(r)?;
+ let mode_id = GUID::parse(r)?;
+ let speed = r.read_u32::<LE>()?;
+ let pitch = r.read_u16::<LE>()?;
+ let is_extra = r.read_u8()? == 1;
+ let extra = if is_extra { Some(VoiceInfoExtra::parse(r)?) } else { None };
+ Ok(Self {
+ engine_id, mode_id,
+ speed, pitch,
+ extra
+ })
+ }
+}
+
+#[derive(Debug)]
+struct BalloonInfo {
+ lines: u8,
+ chars_per_line: u8,
+ foreground: RGB,
+ background: RGB,
+ border: RGB,
+ font_name: String,
+ font_height: i32,
+ font_weight: i32,
+ font_italic: bool,
+ font_underline: bool,
+}
+impl BalloonInfo {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ Ok(Self {
+ lines: r.read_u8()?,
+ chars_per_line: r.read_u8()?,
+ foreground: parse_rgb(r)?,
+ background: parse_rgb(r)?,
+ border: parse_rgb(r)?,
+ font_name: parse_string(r)?,
+ font_height: r.read_i32::<LE>()?,
+ font_weight: r.read_i32::<LE>()?,
+ font_italic: r.read_u8()? == 1,
+ font_underline: r.read_u8()? == 1,
+ })
+ }
+}
+
+#[derive(Debug)]
+struct CharacterInfo {
+ minor_version: u16,
+ major_version: u16,
+ localized_info: Locator,
+ id: GUID,
+ width: u16,
+ height: u16,
+ transparent_index: u8,
+ flags: u32,
+ animation_major_version: u16,
+ animation_minor_version: u16,
+ voice_info: Option<VoiceInfo>,
+ balloon_info: Option<BalloonInfo>,
+ palette: Vec<RGB>,
+}
+impl CharacterInfo {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ let minor_version = r.read_u16::<LE>()?;
+ let major_version = r.read_u16::<LE>()?;
+ let localized_info = Locator::parse(r)?;
+ let id = GUID::parse(r)?;
+ let width = r.read_u16::<LE>()?;
+ let height = r.read_u16::<LE>()?;
+ let transparent_index = r.read_u8()?;
+ let flags = r.read_u32::<LE>()?;
+ let animation_major_version = r.read_u16::<LE>()?;
+ let animation_minor_version = r.read_u16::<LE>()?;
+ let voice_info = if flags >> 4 & 1 == 1 { None } else { Some(VoiceInfo::parse(r)?) };
+ let balloon_info = if flags >> 8 & 1 == 1 { None } else { Some(BalloonInfo::parse(r)?) };
+ let palette = {
+ let len = r.read_u32::<LE>()?;
+ (0..len).map(|_| parse_rgb(r)).collect::<Erm<Vec<RGB>>>()?
+ };
+ Ok(Self {
+ minor_version, major_version,
+ localized_info, id,
+ width, height,
+ transparent_index,
+ flags,
+ animation_major_version, animation_minor_version,
+ voice_info,
+ balloon_info,
+ palette,
+ })
+ }
+}
+
+#[derive(Debug)]
+struct FrameImage {
+ index: u32,
+ x_off: i16,
+ y_off: i16,
+}
+impl FrameImage {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ Ok(Self {
+ index: r.read_u32::<LE>()?,
+ x_off: r.read_i16::<LE>()?,
+ y_off: r.read_i16::<LE>()?,
+ })
+ }
+ fn parse_list<R>(r: &mut R) -> Erm<Vec<Self>> where R: ReadBytesExt + Seek {
+ let len = r.read_u16::<LE>()?;
+ (0..len).map(|_| Self::parse(r)).collect()
+ }
+}
+
+#[derive(Debug)]
+struct BranchInfo {
+ index: u16,
+ probability: u16,
+}
+impl BranchInfo {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ Ok(Self {
+ index: r.read_u16::<LE>()?,
+ probability: r.read_u16::<LE>()?,
+ })
+ }
+ fn parse_list<R>(r: &mut R) -> Erm<Vec<Self>> where R: ReadBytesExt + Seek {
+ let len = r.read_u8()?;
+ (0..len).map(|_| Self::parse(r)).collect()
+ }
+}
+
+#[derive(Debug)]
+enum OverlayType {
+ MouthClosed,
+ MouthWideOpen1,
+ MouthWideOpen2,
+ MouthWideOpen3,
+ MouthWideOpen4,
+ MouthMedium,
+ MouthNarrow,
+}
+#[derive(Debug)]
+struct OverlayInfo {
+ ty: OverlayType,
+ replace_top_image: bool,
+ index: u16,
+ x_off: i16,
+ y_off: i16,
+ width: u16,
+ height: u16,
+ data: Option<Vec<u8>>,
+}
+impl OverlayInfo {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ let ty = match r.read_u8()? {
+ 0 => OverlayType::MouthClosed,
+ 1 => OverlayType::MouthWideOpen1,
+ 2 => OverlayType::MouthWideOpen2,
+ 3 => OverlayType::MouthWideOpen3,
+ 4 => OverlayType::MouthWideOpen4,
+ 5 => OverlayType::MouthMedium,
+ 6 => OverlayType::MouthNarrow,
+ _ => { return utils::erm_msg("invalid overlay type"); }
+ };
+ let replace_top_image = r.read_u8()? == 1;
+ let index = r.read_u16::<LE>()?;
+ let _ = r.read_u8()?;
+ let has_data = r.read_u8()? == 1;
+ let x_off = r.read_i16::<LE>()?;
+ let y_off = r.read_i16::<LE>()?;
+ let width = r.read_u16::<LE>()?;
+ let height = r.read_u16::<LE>()?;
+ let data = if has_data {
+ let len = r.read_u32::<LE>()?;
+ let mut buf = vec![0; len as usize];
+ r.read_exact(&mut buf)?;
+ Some(buf)
+ } else { None };
+ Ok(Self {
+ ty,
+ replace_top_image,
+ index,
+ x_off, y_off,
+ width, height,
+ data,
+ })
+ }
+ fn parse_list<R>(r: &mut R) -> Erm<Vec<Self>> where R: ReadBytesExt + Seek {
+ let len = r.read_u8()?;
+ (0..len).map(|_| Self::parse(r)).collect()
+ }
+}
+
+#[derive(Debug)]
+struct FrameInfo {
+ images: Vec<FrameImage>,
+ audio_index: u16,
+ duration: u16,
+ exit_frame: i16,
+ branches: Vec<BranchInfo>,
+ mouth_overlays: Vec<OverlayInfo>,
+}
+impl FrameInfo {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ Ok(Self {
+ images: FrameImage::parse_list(r)?,
+ audio_index: r.read_u16::<LE>()?,
+ duration: r.read_u16::<LE>()?,
+ exit_frame: r.read_i16::<LE>()?,
+ branches: BranchInfo::parse_list(r)?,
+ mouth_overlays: OverlayInfo::parse_list(r)?,
+ })
+ }
+ fn parse_list<R>(r: &mut R) -> Erm<Vec<Self>> where R: ReadBytesExt + Seek {
+ let len = r.read_u16::<LE>()?;
+ (0..len).map(|_| Self::parse(r)).collect()
+ }
+}
+
+#[derive(Debug)]
+enum AnimationTransition {Return, ExitBranch, None}
+#[derive(Debug)]
+struct AnimationInfo {
+ name: String,
+ transition: AnimationTransition,
+ return_name: String,
+ frames: Vec<FrameInfo>
+}
+impl AnimationInfo {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ let _name = parse_string(r)?;
+ let loc = Locator::parse(r)?;
+ let pos = r.stream_position()?;
+ loc.seek(r)?;
+ let name = parse_string(r)?;
+ let transition = match r.read_u8()? {
+ 0 => AnimationTransition::Return,
+ 1 => AnimationTransition::ExitBranch,
+ 2 => AnimationTransition::None,
+ _ => { return utils::erm_msg("invalid animation transition type"); }
+ };
+ let return_name = parse_string(r)?;
+ let frames = FrameInfo::parse_list(r)?;
+ r.seek(SeekFrom::Start(pos))?;
+ Ok(Self {
+ name, transition, return_name, frames
+ })
+ }
+ fn parse_map<R>(r: &mut R) -> Erm<HashMap<String, Self>> where R: ReadBytesExt + Seek {
+ let mut ret = HashMap::new();
+ let len = r.read_u32::<LE>()?;
+ for _ in 0..len {
+ let v = Self::parse(r)?;
+ ret.insert(v.name.clone(), v);
+ }
+ Ok(ret)
+ }
+}
+
+struct ImageInfo {
+ width: u16,
+ height: u16,
+ image: Vec<u8>,
+}
+impl std::fmt::Debug for ImageInfo {
+ fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+ fmt.write_fmt(format_args!("<image w: {}, h: {}>", self.width, self.height))?;
+ Ok(())
+ }
+}
+impl ImageInfo {
+ fn size() -> u32 { 3 }
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ let loc = Locator::parse(r)?;
+ let _ = r.read_u32::<LE>()?;
+ let pos = r.stream_position()?;
+ loc.seek(r)?;
+ let _ = r.read_u8()?;
+ let width = r.read_u16::<LE>()?;
+ let height = r.read_u16::<LE>()?;
+ let compressed = r.read_u8()? == 1;
+ let img_len = r.read_u32::<LE>()?;
+ let mut img_bytes = vec![0; img_len as usize];
+ r.read_exact(&mut img_bytes)?;
+ r.seek(SeekFrom::Start(pos))?;
+ Ok(Self {
+ width, height,
+ image: if compressed {
+ decompress(img_bytes).ok_or_else(
+ || utils::Error { msg: "failed to decompress".to_owned()}
+ )?
+ } else { img_bytes }
+ })
+ }
+ fn parse_list<R>(r: &mut R) -> Erm<Vec<Self>> where R: ReadBytesExt + Seek {
+ let len = r.read_u32::<LE>()?;
+ (0..len).map(|_| Self::parse(r)).collect()
+ }
+}
+
+#[derive(Debug)]
+struct ACS {
+ character_info: CharacterInfo,
+ animation_info: HashMap<String, AnimationInfo>,
+ image_info: Vec<ImageInfo>,
+ audio_info: Locator,
+}
+impl ACS {
+ fn parse<R>(r: &mut R) -> Erm<Self> where R: ReadBytesExt + Seek {
+ if r.read_u32::<LE>()? != 0xabcdabc3 {
+ return utils::erm_msg("invalid magic bytes");
+ }
+ let character_info_loc = Locator::parse(r)?;
+ let animation_info_loc = Locator::parse(r)?;
+ let image_info_loc = Locator::parse(r)?;
+ let audio_info = Locator::parse(r)?;
+ Ok(Self {
+ character_info: { character_info_loc.seek(r)?; CharacterInfo::parse(r)? },
+ animation_info: { animation_info_loc.seek(r)?; AnimationInfo::parse_map(r)? },
+ image_info: { image_info_loc.seek(r)?; ImageInfo::parse_list(r)? },
+ audio_info,
+ })
+ }
+}
+
+pub struct Overlay {
+ tex: texture::Texture,
+ acs: ACS,
+ anim: Option<String>,
+ anim_idx: usize,
+ border: bool,
+}
+impl Overlay {
+ pub fn new(ctx: &context::Context) -> Self {
+ let tex = texture::Texture::new_empty(ctx);
+ let bytes = include_bytes!("../assets/acs/clippy.acs");
+ let mut r = std::io::Cursor::new(bytes);
+ let acs = ACS::parse(&mut r).unwrap();
+ log::info!("{:#?}", acs.animation_info.keys().collect::<Vec<&String>>());
+ Self {
+ tex,
+ acs,
+ anim: Some("EMPTYTRASH".to_owned()),
+ anim_idx: 0,
+ border: false,
+ }
+ }
+ pub fn reset_animation(&mut self) {
+ self.anim = None;
+ self.anim_idx = 0;
+ }
+ pub fn play_animation(&mut self, anim: &str) {
+ self.anim = Some(anim.to_owned());
+ self.anim_idx = 0;
+ }
+ pub fn play_idle_animation(&mut self) {
+ let idle = [
+ "IDLEEYEBROWRAISE",
+ "IDLE1_1",
+ "IDLESIDETOSIDE",
+ "IDLEFINGERTAP",
+ "IDLEHEADSCRATCH",
+ ];
+ let idx = rand::thread_rng().gen_range(0..idle.len());
+ self.play_animation(idle[idx]);
+ }
+}
+impl overlay::Overlay for Overlay {
+ fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &net::fig::BinaryMessage) -> Erm<()> {
+ match &*msg.event {
+ b"overlay clippy animate" => {
+ let res: Erm<()> = try {
+ let mut reader = std::io::Cursor::new(&msg.data);
+ let anim = net::fig::read_length_prefixed_utf8(&mut reader)?;
+ self.play_animation(&anim);
+ ()
+ };
+ if let Err(e) = res { log::warn!("malformed clippy update: {}", e); }
+ },
+ b"overlay clippy border on" => self.border = true,
+ b"overlay clippy border off" => self.border = false,
+ _ => {},
+ }
+ Ok(())
+ }
+ fn update(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
+ let anim = self.anim.as_deref().unwrap_or("RESTPOSE");
+ if let Some(ainfo) = &self.acs.animation_info.get(anim) {
+ let frames = &ainfo.frames;
+ let f = &frames[self.anim_idx];
+ if f.images.len() > 0 {
+ let idx = f.images[0].index as usize;
+ let colors: Vec<u8> = self.acs.image_info[idx].image.iter().flat_map(|idx| {
+ if *idx == self.acs.character_info.transparent_index {
+ [0, 0, 0, 0]
+ } else {
+ let c = self.acs.character_info.palette[*idx as usize];
+ [c[0], c[1], c[2], 255]
+ }
+ }).collect();
+ self.tex.upload_rgba8(ctx,
+ self.acs.image_info[idx].width as _,
+ self.acs.image_info[idx].height as _,
+ &colors
+ );
+ }
+ if st.tick % 6 == 0 {
+ if self.anim_idx < frames.len() - 1 {
+ self.anim_idx += 1;
+ } else {
+ self.reset_animation();
+ }
+ }
+ } else {
+ self.reset_animation();
+ }
+ if self.anim.is_none() {
+ if rand::thread_rng().gen_ratio(1, 10 * 60) {
+ self.play_idle_animation();
+ }
+ }
+ Ok(())
+ }
+ fn render(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
+ st.bind_2d(ctx, &ost.assets.shader_acs);
+ let w = 3.0 * self.acs.character_info.width as f32;
+ let h = 3.0 * self.acs.character_info.height as f32;
+ ost.assets.shader_acs.set_position_2d_helper(ctx, st,
+ &(st.render_dims - glam::Vec2::new(w, h)),
+ &glam::Vec2::new(w, h),
+ // &glam::Quat::from_rotation_z(st.tick as f32 / 100.0),
+ &glam::Quat::IDENTITY,
+ );
+ self.tex.bind(ctx);
+ st.mesh_square.render(ctx);
+ if self.border {
+ st.bind_2d(ctx, &ost.assets.shader_flat);
+ ost.assets.shader_flat.set_position_2d_helper(ctx, st,
+ &glam::Vec2::new(1590.0, 541.0),
+ &glam::Vec2::new(295.0, 238.0),
+ &glam::Quat::IDENTITY,
+ );
+ ost.assets.texture_clippyborder.bind(ctx);
+ st.mesh_square.render(ctx);
+ }
+ Ok(())
+ }
+}
diff --git a/crates/renderer/src/overlay/combo.rs b/crates/renderer/src/overlay/combo.rs
new file mode 100644
index 0000000..f200e22
--- /dev/null
+++ b/crates/renderer/src/overlay/combo.rs
@@ -0,0 +1,216 @@
+use std::collections::HashMap;
+
+use rand::Rng;
+use teleia::*;
+
+use crate::overlay;
+
+use enum_map::{enum_map, Enum, EnumMap};
+use strum::{EnumIter, IntoEnumIterator};
+
+const MAX_SCORE: f32 = 12800.0;
+
+const WIDTH: i64 = 250;
+const HEIGHT: i64 = 400;
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Enum, EnumIter)]
+enum Rank {SSS, SS, S, A, B, C, D, None}
+impl Rank {
+ fn threshold(self) -> f32 {
+ match self {
+ Self::SSS => 2800.0,
+ Self::SS => 2100.0,
+ Self::S => 1500.0,
+ Self::A => 1000.0,
+ Self::B => 600.0,
+ Self::C => 300.0,
+ Self::D => 100.0,
+ Self::None => 0.0,
+ }
+ }
+ fn multiplier(self) -> f32 {
+ match self {
+ Self::SSS => 16.0,
+ Self::SS => 6.0,
+ Self::S => 5.0,
+ Self::A => 4.0,
+ Self::B => 3.0,
+ Self::C => 2.0,
+ Self::D => 1.5,
+ Self::None => 1.0,
+ }
+ }
+}
+
+pub struct Overlay {
+ font: font::Bitmap,
+ fb: framebuffer::Framebuffer,
+ rank_textures: EnumMap<Rank, texture::Texture>,
+ shake: u64,
+ score: f32,
+ tags: HashMap<String, u64>,
+}
+impl Overlay {
+ pub fn new(ctx: &context::Context) -> Self {
+ let fb = framebuffer::Framebuffer::new(ctx, &glam::Vec2::new(WIDTH as f32, HEIGHT as f32), &glam::Vec2::new(0.0, 0.0));
+ Self {
+ fb,
+ font: font::Bitmap::from_image(ctx, 6, 12, 96, 72, include_bytes!("../assets/fonts/terminus.png")),
+ rank_textures: enum_map! {
+ Rank::SSS => texture::Texture::new(ctx, include_bytes!("../assets/textures/combo/sss.webp")),
+ Rank::SS => texture::Texture::new(ctx, include_bytes!("../assets/textures/combo/ss.webp")),
+ Rank::S => texture::Texture::new(ctx, include_bytes!("../assets/textures/combo/s.webp")),
+ Rank::A => texture::Texture::new(ctx, include_bytes!("../assets/textures/combo/a.webp")),
+ Rank::B => texture::Texture::new(ctx, include_bytes!("../assets/textures/combo/b.webp")),
+ Rank::C => texture::Texture::new(ctx, include_bytes!("../assets/textures/combo/c.webp")),
+ Rank::D => texture::Texture::new(ctx, include_bytes!("../assets/textures/combo/d.webp")),
+ Rank::None => texture::Texture::new(ctx, include_bytes!("../assets/textures/test.png")),
+ },
+ shake: 0,
+ score: 0.0,
+ tags: HashMap::new(),
+ }
+ }
+ fn rank(&self) -> (Rank, f32) {
+ let mut prev = MAX_SCORE;
+ for r in Rank::iter() {
+ let thresh = r.threshold();
+ if self.score > thresh {
+ return (r, (self.score - thresh) / (prev - thresh));
+ }
+ prev = thresh;
+ }
+ return (Rank::None, 0.0);
+ }
+ fn tag_multiplier(&self) -> f32 {
+ return 1.0 + self.tags.len() as f32;
+ }
+ fn shake_offset(&self, r: Rank) -> f32 {
+ rand::thread_rng().gen_range(0..10) as f32 / 100.0 * r.multiplier()
+ }
+}
+impl overlay::Overlay for Overlay {
+ fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &net::fig::BinaryMessage) -> Erm<()> {
+ match &*msg.event {
+ b"overlay combo message" => {
+ let (oldrank, _) = self.rank();
+ self.score += 267.0 * self.tag_multiplier();
+ let (newrank, _) = self.rank();
+ if oldrank != newrank {
+ self.shake = 20;
+ }
+ if let Ok(ts) = String::from_utf8(msg.data.clone()) {
+ for t in ts.split(",") {
+ if t.len() > 0 {
+ self.tags.entry(t.to_owned()).and_modify(|x| *x += 1).or_insert(1);
+ }
+ }
+ }
+ },
+ _ => {},
+ }
+ Ok(())
+ }
+ fn update(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
+ let (rank, _) = self.rank();
+ self.score -= 2.0 * rank.multiplier();
+ if self.score < 0.0 {
+ self.score = 0.0;
+ self.tags.clear();
+ }
+ if self.score > MAX_SCORE { self.score = MAX_SCORE; }
+ if self.shake > 0 { self.shake -= 1; }
+ Ok(())
+ }
+ fn render(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
+ let (rank, meter) = self.rank();
+ if rank == Rank::None { return Ok(()); }
+
+ st.bind_framebuffer(ctx, &self.fb);
+ ctx.clear_color(glam::Vec4::new(0.0, 0.0, 0.0, 0.8));
+ ctx.clear();
+
+ // rank name
+ st.bind_2d(ctx, &ost.assets.shader_flat);
+ ost.assets.shader_flat.set_position_2d(
+ ctx, st,
+ &glam::Vec2::new(-4.0, 4.0),
+ &glam::Vec2::new(WIDTH as f32, WIDTH as f32 / 3.0),
+ );
+ self.rank_textures[rank].bind(ctx);
+ st.mesh_square.render(ctx);
+
+ // meter
+ st.bind_2d(ctx, &ost.assets.shader_color);
+ ost.assets.shader_color.set_position_2d(
+ ctx, st,
+ &glam::Vec2::new(0.0, 100.0),
+ &glam::Vec2::new(WIDTH as f32, 16.0),
+ );
+ ost.assets.shader_color.set_vec4(ctx, "color", &glam::Vec4::new(0.0, 0.0, 0.0, 1.0));
+ st.mesh_square.render(ctx);
+ ost.assets.shader_color.set_position_2d(
+ ctx, st,
+ &glam::Vec2::new(0.0, 100.0),
+ &glam::Vec2::new(WIDTH as f32 * meter, 16.0),
+ );
+ ost.assets.shader_color.set_vec4(ctx, "color", &glam::Vec4::new(1.0, 1.0, 1.0, 1.0));
+ st.mesh_square.render(ctx);
+
+ // tags
+ let mut tagy = 124.0;
+ for (t, count) in self.tags.iter() {
+ self.font.render_text_parameterized(
+ ctx, st,
+ &glam::Vec2::new(4.0, tagy),
+ &format!("+ {t} (x{count})"),
+ font::BitmapParams {
+ color: &[glam::Vec3::new(1.0, 1.0, 1.0)],
+ scale: glam::Vec2::new(2.0, 2.0),
+ },
+ );
+ tagy += 24.0;
+ }
+
+ // multiplier
+ self.font.render_text_parameterized(
+ ctx, st,
+ &glam::Vec2::new(4.0, HEIGHT as f32 - 50.0),
+ &format!("MULT:"),
+ font::BitmapParams {
+ color: &[glam::Vec3::new(1.0, 1.0, 1.0)],
+ scale: glam::Vec2::new(4.0, 4.0),
+ },
+ );
+ self.font.render_text_parameterized(
+ ctx, st,
+ &glam::Vec2::new(128.0, HEIGHT as f32 - 50.0),
+ &format!("{}x", self.tag_multiplier()),
+ font::BitmapParams {
+ color: &[glam::Vec3::new(1.0, 0.7, 0.0)],
+ scale: glam::Vec2::new(4.0, 4.0),
+ },
+ );
+
+ // actually draw box to screen
+ st.bind_render_framebuffer(ctx);
+ ctx.clear_depth();
+ st.bind_3d(ctx, &ost.assets.shader_flat_noflip);
+ let shake_offset = if self.shake > 0 {
+ glam::Vec3::new(self.shake_offset(rank), 0.0, self.shake_offset(rank))
+ } else {
+ glam::Vec3::ZERO
+ };
+ ost.assets.shader_flat_noflip.set_position_3d(
+ ctx, st,
+ &glam::Mat4::from_scale_rotation_translation(
+ glam::Vec3::new(WIDTH as f32 / HEIGHT as f32, 1.0, 1.0),
+ glam::Quat::from_rotation_y(std::f32::consts::PI + 0.7),
+ glam::Vec3::new(-5.5, 1.0, -8.0) + shake_offset,
+ ),
+ );
+ self.fb.bind_texture(ctx);
+ st.mesh_square.render(ctx);
+ Ok(())
+ }
+}
diff --git a/crates/renderer/src/overlay/model.rs b/crates/renderer/src/overlay/model.rs
index d74870e..9c4b51b 100644
--- a/crates/renderer/src/overlay/model.rs
+++ b/crates/renderer/src/overlay/model.rs
@@ -81,7 +81,7 @@ impl Overlay {
}
impl overlay::Overlay for Overlay {
- fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &fig::BinaryMessage) -> Erm<()> {
+ fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &net::fig::BinaryMessage) -> Erm<()> {
if msg.event == b"overlay avatar text" {
match str::from_utf8(&msg.data) {
Ok(s) => self.terminal.fill_string(s),
diff --git a/crates/renderer/src/overlay/shader.rs b/crates/renderer/src/overlay/shader.rs
index 2bed8d6..b30242f 100644
--- a/crates/renderer/src/overlay/shader.rs
+++ b/crates/renderer/src/overlay/shader.rs
@@ -2,8 +2,11 @@ use teleia::*;
use crate::{overlay, toggle};
+use glow::HasContext;
+
pub struct Overlay {
visualizer: newton_shader::Visualizer,
+ fb: framebuffer::Framebuffer,
}
impl Overlay {
@@ -11,6 +14,7 @@ impl Overlay {
let visualizer = newton_shader::Visualizer::new();
Self {
visualizer,
+ fb: framebuffer::Framebuffer::new(ctx, &glam::Vec2::new(640.0, 360.0), &glam::Vec2::ZERO),
}
}
}
@@ -21,12 +25,12 @@ impl overlay::Overlay for Overlay {
self.visualizer.shader = None;
Ok(())
}
- fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &fig::BinaryMessage) -> Erm<()> {
+ fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &net::fig::BinaryMessage) -> Erm<()> {
if msg.event == b"overlay shader" {
let res: Erm<()> = (|| {
let mut reader = std::io::Cursor::new(&msg.data);
- let author = fig::read_length_prefixed_utf8(&mut reader)?;
- let shader = fig::read_length_prefixed_utf8(&mut reader)?;
+ let author = net::fig::read_length_prefixed_utf8(&mut reader)?;
+ let shader = net::fig::read_length_prefixed_utf8(&mut reader)?;
self.visualizer.author = author.to_string();
if let Err(e) = self.visualizer.set(ctx, st, &shader) {
log::warn!("error compiling shader: {}", e);
@@ -40,6 +44,11 @@ impl overlay::Overlay for Overlay {
}
fn render(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
if let Some(s) = &self.visualizer.shader {
+ self.fb.bind(ctx);
+ unsafe {
+ ctx.gl.disable(glow::BLEND);
+ }
+ ctx.clear();
s.bind(ctx);
s.set_f32(
ctx, "opacity",
@@ -51,17 +60,30 @@ impl overlay::Overlay for Overlay {
0.5
}
);
- s.set_vec2(ctx, "resolution", &glam::Vec2::new(ctx.render_width, ctx.render_height));
+ s.set_vec2(ctx, "resolution", &st.render_dims);
let elapsed = (st.tick - self.visualizer.tickset) as f32 / 60.0;
s.set_f32(ctx, "time", elapsed);
s.set_f32(ctx, "chat_time", ost.chat.time - self.visualizer.timeset as f32);
- ctx.render_no_geometry();
s.set_f32(ctx, "tracking_mouth", ost.tracking.mouth);
s.set_vec2(ctx, "tracking_eyes", &glam::Vec2::new(ost.tracking.eyes.0, ost.tracking.eyes.1));
s.set_mat4(ctx, "tracking_neck", &glam::Mat4::from_quat(ost.tracking.neck));
s.set_vec2(ctx, "emacs_cursor", &glam::Vec2::new(ost.info.emacs_cursor.0, ost.info.emacs_cursor.1));
s.set_vec2(ctx, "mouse_cursor", &glam::Vec2::new(ost.info.mouse_cursor.0, ost.info.mouse_cursor.1));
s.set_i32(ctx, "heartrate", ost.info.emacs_heartrate);
+ ctx.render_no_geometry();
+ unsafe {
+ ctx.gl.enable(glow::BLEND);
+ }
+
+ st.render_framebuffer.bind(ctx);
+ st.bind_2d(ctx, &ost.assets.shader_flat_noflip);
+ self.fb.bind_texture(ctx);
+ ost.assets.shader_flat_noflip.set_position_2d(
+ ctx, st,
+ &glam::Vec2::new(0.0, 0.0),
+ &glam::Vec2::new(1920.0, 1080.0)
+ );
+ st.mesh_square.render(ctx);
}
if let Some(t@toggle::Toggle { val: true, .. }) = ost.toggles.get(ctx, st, "adblock") {
st.bind_2d(ctx, &ost.assets.shader_flat);
diff --git a/crates/renderer/src/overlay/tcg.rs b/crates/renderer/src/overlay/tcg.rs
index 7361e86..ece01e8 100644
--- a/crates/renderer/src/overlay/tcg.rs
+++ b/crates/renderer/src/overlay/tcg.rs
@@ -1,6 +1,8 @@
+use sha2::Digest;
use teleia::*;
-use std::{cell::RefCell, io::Write, rc::Rc};
+use std::{cell::RefCell, rc::Rc};
+use std::fmt::Write as _;
use redis::Commands;
use image::EncodableLayout;
@@ -129,7 +131,7 @@ impl RenderedCardSlot {
struct ImageWrite {
buf: Rc<RefCell<Vec<u8>>>,
}
-impl Write for ImageWrite {
+impl std::io::Write for ImageWrite {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.buf.borrow_mut().write(buf)
}
@@ -138,6 +140,7 @@ impl Write for ImageWrite {
struct ImageEncoder {
frames: u32,
frames_left: u32,
+ frame_hashes: Vec<u8>,
buf: Rc<RefCell<Vec<u8>>>,
writer: png::Writer<ImageWrite>,
}
@@ -164,12 +167,14 @@ impl ImageEncoder {
Some(Self {
frames,
frames_left: frames,
+ frame_hashes: Vec::new(),
buf,
writer,
})
}
fn write_frame(&mut self, pixels: &[u8]) {
if self.frames_left > 0 {
+ self.frame_hashes.extend_from_slice(sha2::Sha256::digest(pixels).as_slice());
let _ = self.writer.write_image_data(&pixels);
self.frames_left -= 1;
}
@@ -177,10 +182,10 @@ impl ImageEncoder {
fn is_finished(&self) -> bool {
self.frames_left == 0
}
- fn finish(self) -> Option<Vec<u8>> {
+ fn finish(self) -> Option<(Vec<u8>, Vec<u8>)> {
if self.is_finished() {
self.writer.finish().expect("failed to finish");
- Some(self.buf.replace(Vec::new()))
+ Some((self.buf.replace(Vec::new()), self.frame_hashes))
} else { None }
}
}
@@ -283,15 +288,24 @@ impl Marquee {
}
}
fn upload_card(ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State,
- c: &Card, buf: &[u8]
+ c: &Card, buf: &[u8], hashes: &[u8],
) -> Erm<()> {
- let with_meta = web_image_meta::png::add_text_chunk(
- buf, "lcolonqtcg", &c.encoded,
+ let mut signed = Vec::from(c.encoded.as_bytes());
+ signed.extend(hashes);
+ let signature = sign(&mut ost.redis_conn, &signed)?;
+ let mut res = "+SIGNED+".to_owned();
+ for s in signature {
+ write!(res, "{:02x}", s)?;
+ }
+ res.push_str("+");
+ res.push_str(&c.encoded);
+ let with_signature = web_image_meta::png::add_text_chunk(
+ buf, "lcolonqtcg", &res,
)?;
let uuid = uuid::Uuid::new_v4();
- let _: () = ost.redis_conn.hset("tcg:cards", uuid.to_string(), &with_meta)?;
+ let () = ost.redis_conn.hset("tcg:cards", uuid.to_string(), &with_signature)?;
let inventory_key = format!("tcg-inventory:{}", c.owner_id);
- let _: () = ost.redis_conn.lpush(inventory_key, uuid.to_string())?;
+ let () = ost.redis_conn.lpush(inventory_key, uuid.to_string())?;
Ok(())
}
pub fn render(&mut self,
@@ -299,9 +313,9 @@ impl Marquee {
renderer: &CardRenderer,
) {
for s in self.slots.iter_mut() {
- if let Some(b) = s.encoder.take_if(|e| e.is_finished()).and_then(|enc| enc.finish()) {
+ if let Some((b, h)) = s.encoder.take_if(|e| e.is_finished()).and_then(|enc| enc.finish()) {
if let Some(c) = &s.card.card {
- let _ = Self::upload_card(ctx, st, ost, &c, &b).expect("failed to upload");
+ let _ = Self::upload_card(ctx, st, ost, &c, &b, &h).expect("failed to upload");
}
}
}
@@ -554,7 +568,7 @@ impl overlay::Overlay for Overlay {
fn reset(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
Ok(())
}
- fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &fig::BinaryMessage) -> Erm<()> {
+ fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &net::fig::BinaryMessage) -> Erm<()> {
match &*msg.event {
b"overlay tcg generate" => {
let res: Erm<()> = (|| {
@@ -621,3 +635,87 @@ impl overlay::Overlay for Overlay {
Ok(())
}
}
+
+pub fn sign(conn: &mut redis::Connection, data: &[u8]) -> Erm<Vec<u8>> {
+ let mut secret: Vec<u8> = conn.get("tcg:secret")?;
+ secret.extend_from_slice(data);
+ Ok(Vec::from(sha2::Sha256::digest(&secret).as_slice()))
+}
+
+pub fn validate_card(png: &[u8]) -> Erm<bool> {
+ let decoder = png::Decoder::new(png);
+ let mut reader = decoder.read_info()?;
+ let mut buf = vec![0; reader.output_buffer_size()];
+ let mut frame_hashes = Vec::new();
+ while let Ok(f) = reader.next_frame(&mut buf) {
+ frame_hashes.extend_from_slice(sha2::Sha256::digest(&buf).as_slice());
+ }
+ reader.finish()?;
+ for tc in reader.info().uncompressed_latin1_text.iter() {
+ if tc.keyword == "lcolonqtcg" {
+ eprintln!("{}", tc.text);
+ let (sig, meta) = if let Some(suffix) = tc.text.strip_prefix("+SIGNED+") {
+ suffix.split_once("+").unwrap_or(("", suffix))
+ } else {
+ ("", &*tc.text)
+ };
+ let mut to_sign = Vec::from(meta);
+ to_sign.extend_from_slice(&frame_hashes);
+ eprintln!("to_sign: {:?}", to_sign);
+ let signed = {
+ let redis = redis::Client::open("redis://shiro").unwrap();
+ let mut redis_conn = redis.get_connection().unwrap();
+ sign(&mut redis_conn, &to_sign)?
+ };
+ let mut computed_sig = String::new();
+ for s in signed {
+ write!(computed_sig, "{:02x}", s)?;
+ }
+ eprintln!("attached signature: {}", sig);
+ eprintln!("computed signature: {}", computed_sig);
+ return Ok(sig == computed_sig);
+ }
+ }
+ Ok(false)
+}
+
+pub fn repair_card(png: &[u8]) -> Erm<Vec<u8>> {
+ let decoder = png::Decoder::new(png);
+ let mut reader = decoder.read_info()?;
+ let mut buf = vec![0; reader.output_buffer_size()];
+ let mut frame_hashes = Vec::new();
+ while let Ok(f) = reader.next_frame(&mut buf) {
+ frame_hashes.extend_from_slice(sha2::Sha256::digest(&buf).as_slice());
+ }
+ reader.finish()?;
+ for tc in reader.info().uncompressed_latin1_text.iter() {
+ if tc.keyword == "lcolonqtcg" {
+ let (sig, meta) = if let Some(suffix) = tc.text.strip_prefix("+SIGNED+") {
+ suffix.split_once("+").unwrap_or(("", suffix))
+ } else {
+ ("", &*tc.text)
+ };
+ let mut to_sign = Vec::from(meta);
+ to_sign.extend_from_slice(&frame_hashes);
+ eprintln!("to_sign: {:?}", to_sign);
+ let signed = {
+ let redis = redis::Client::open("redis://shiro").unwrap();
+ let mut redis_conn = redis.get_connection().unwrap();
+ sign(&mut redis_conn, &to_sign)?
+ };
+ let mut computed_sig = String::new();
+ for s in signed {
+ write!(computed_sig, "{:02x}", s)?;
+ }
+ if sig != computed_sig {
+ eprintln!("repairing, new signature: {}", computed_sig);
+ eprintln!("old signature: {}", sig);
+ let clean = web_image_meta::png::clean_chunks(png)?;
+ return Ok(web_image_meta::png::add_text_chunk(
+ &clean, "lcolonqtcg", &format!("+SIGNED+{}+{}", computed_sig, meta),
+ )?);
+ }
+ }
+ }
+ Ok(Vec::from(png))
+}
diff --git a/crates/renderer/src/texture_server.rs b/crates/renderer/src/texture_server.rs
new file mode 100644
index 0000000..5afad70
--- /dev/null
+++ b/crates/renderer/src/texture_server.rs
@@ -0,0 +1,80 @@
+use teleia::*;
+
+use std::io::Write;
+use std::os::fd::FromRawFd;
+use std::os::unix::net::{AncillaryData, SocketAncillary};
+use std::sync::mpsc::{Receiver, channel};
+use std::{os::unix::net::UnixDatagram, thread::{spawn, JoinHandle}};
+
+use glow::HasContext;
+use crate::ffi::egl;
+use crate::ffi::glfw;
+
+const KEY: usize = 42;
+const SOCK_PATH: &'static str = "/tmp/newton.sock";
+
+
+pub struct Server {
+ pub tex: texture::Texture,
+ thread: JoinHandle<()>,
+ receiver: Receiver<i32>,
+}
+impl Server {
+ pub fn new(ctx: &context::Context) -> Self {
+ std::fs::remove_file(SOCK_PATH).expect("failed to remove socket");
+ let sock = UnixDatagram::bind(SOCK_PATH).expect("failed to bind texture server socket");
+
+ let (sender, receiver) = channel::<i32>();
+ let thread = spawn(move || {
+ let mut ancillary_buf = [0; 128];
+ let mut ancillary = SocketAncillary::new(&mut ancillary_buf);
+ loop {
+ match sock.recv_vectored_with_ancillary(&mut [], &mut ancillary) {
+ Ok(_) => {
+ for ar in ancillary.messages() {
+ match ar {
+ Ok(AncillaryData::ScmRights(mut sr)) => {
+ if let Some(fd) = sr.next() {
+ if let Err(e) = sender.send(fd) {
+ log::warn!("error on channel: {:?}", e);
+ }
+ }
+ },
+ Ok(_) => log::info!("message is not SCM_RIGHTS"),
+ Err(e) => log::warn!("failed to read ancillary message: {:?}", e),
+ }
+ }
+ },
+ Err(e) => log::warn!("texture server failed to receive: {}", e),
+ }
+ }
+ });
+ Self {
+ tex: texture::Texture::new_empty(ctx),
+ thread,
+ receiver,
+ }
+ }
+ pub fn update(&self, ctx: &context::Context) {
+ if let Ok(fd) = self.receiver.try_recv() {
+ log::info!("received file descriptor: {}", fd);
+ unsafe {
+ let window = ctx.window.borrow_mut().0.ptr;
+ let d = glfw::glfwGetEGLDisplay();
+ let c = glfw::glfwGetEGLContext(window);
+ let img = egl::eglCreateImage(d, c, egl::EGL_LINUX_DMA_BUF_EXT, std::ptr::null_mut(), [
+ egl::EGL_WIDTH as _, 16,
+ egl::EGL_HEIGHT as _, 16,
+ egl::EGL_LINUX_DRM_FOURCC_EXT as _, 875708993,
+ egl::EGL_DMA_BUF_PLANE0_FD_EXT as _, fd as _,
+ egl::EGL_DMA_BUF_PLANE0_OFFSET_EXT as _, 0,
+ egl::EGL_DMA_BUF_PLANE0_PITCH_EXT as _, 128,
+ egl::EGL_NONE as _,
+ ].as_ptr());
+ self.tex.bind(ctx);
+ egl::glEGLImageTargetTexture2DOES(glow::TEXTURE_2D, img);
+ log::info!("set up texture");
+ }
+ }
+ }
+}
diff --git a/crates/renderer/src/toggle.rs b/crates/renderer/src/toggle.rs
index 8468fc4..7add3ca 100644
--- a/crates/renderer/src/toggle.rs
+++ b/crates/renderer/src/toggle.rs
@@ -27,7 +27,7 @@ impl Toggles {
}
pub fn handle(&mut self,
ctx: &context::Context, st: &state::State,
- msg: fig::BinaryMessage
+ msg: net::fig::BinaryMessage
) {
let nm = if let Ok(s) = str::from_utf8(&msg.data) { s } else {
log::warn!("failed to decode toggle name");
@@ -38,7 +38,7 @@ impl Toggles {
}
pub fn handle_set(&mut self,
ctx: &context::Context, st: &state::State,
- msg: fig::BinaryMessage, val: bool
+ msg: net::fig::BinaryMessage, val: bool
) {
let nm = if let Ok(s) = str::from_utf8(&msg.data) { s } else {
log::warn!("failed to decode toggle name");
diff --git a/crates/video_player/Cargo.toml b/crates/video_player/Cargo.toml
new file mode 100644
index 0000000..df0e2bc
--- /dev/null
+++ b/crates/video_player/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "newton_video_player"
+version.workspace = true
+edition.workspace = true
+authors.workspace = true
+
+[[bin]]
+name = "newton_video_player"
+path = "src/main.rs"
+
+[dependencies]
+teleia = {workspace = true}
+glam = "*" # linear algebra
+glow = "*" # gl bindings
+bitflags = "*" # C-style bitwise flags
+rand = { version = "=0.8.5", features = ["small_rng"] } # rng
+log = "*" # logging
+env_logger = "*" # native logging
+lazy_static = "*" # global constants
+uuid = {version = "*", features = ["v4"]} # generate uuids \ No newline at end of file
diff --git a/crates/video_player/src/main.rs b/crates/video_player/src/main.rs
new file mode 100644
index 0000000..e9fc5e1
--- /dev/null
+++ b/crates/video_player/src/main.rs
@@ -0,0 +1,13 @@
+#![feature(unix_socket_ancillary_data)]
+use std::os::unix::net::{SocketAncillary, UnixDatagram};
+
+fn main() {
+ let sock = UnixDatagram::unbound().expect("failed to create socket");
+ sock.connect("/tmp/newton.sock").expect("failed to connect");
+ let mut ancillary_buffer = [0; 128];
+ let mut ancillary = SocketAncillary::new(&mut ancillary_buffer);
+ ancillary.add_fds(&[1]);
+ sock.send_vectored_with_ancillary(&mut [], &mut ancillary).expect("failed to send");
+ println!("hi");
+ loop {}
+}
diff --git a/flake.lock b/flake.lock
index 79977cf..e9c4144 100644
--- a/flake.lock
+++ b/flake.lock
@@ -67,11 +67,11 @@
]
},
"locked": {
- "lastModified": 1753584741,
- "narHash": "sha256-i147iFSy4K4PJvID+zoszLbRi2o+YV8AyG4TUiDQ3+I=",
+ "lastModified": 1766717007,
+ "narHash": "sha256-ZjLiHCHgoH2maP5ZAKn0anrHymbjGOS5/PZqfJUK8Ik=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "69dfe029679e73b8d159011c9547f6148a85ca6b",
+ "rev": "a18efe8a9112175e43397cf870fb6bc1ca480548",
"type": "github"
},
"original": {
@@ -123,11 +123,11 @@
"rust-overlay": "rust-overlay"
},
"locked": {
- "lastModified": 1755248408,
- "narHash": "sha256-fSdigxPV4/fASh0e32GGso1TuQVBbv9m7oNmLdWeUOQ=",
+ "lastModified": 1766795639,
+ "narHash": "sha256-dujt59KKcTW7h+VqjG9+I962Qh1rvRKr4jzKfIgAjBA=",
"owner": "lcolonq",
"repo": "teleia",
- "rev": "d8b65583864e57c6702283ee19d18c2421bbc8fb",
+ "rev": "ff3317bee0584b89758bbda6712396d35ba82153",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index b24daab..12bfb72 100644
--- a/flake.nix
+++ b/flake.nix
@@ -46,6 +46,7 @@
};
devShells.${system}.default = inputs.teleia.shell.overrideAttrs (final: prev: {
buildInputs = prev.buildInputs ++ [
+ pkgs.glfw
];
});
};
diff --git a/launch.sh b/launch.sh
index b1aa8cf..72b6cbc 100755
--- a/launch.sh
+++ b/launch.sh
@@ -1,8 +1,9 @@
#!/bin/sh
set -xu
-pactl load-module module-null-sink sink_name=lcolonq-hls
-./target/debug/newton_renderer overlay &
-sleep 3
-pw-link lcolonq-hls:monitor_FL alsa_capture.newton_renderer:input_FL
-pw-link lcolonq-hls:monitor_FR alsa_capture.newton_renderer:input_FR
+# pactl load-module module-null-sink sink_name=lcolonq-hls
+# ./target/debug/newton_renderer overlay &
+# sleep 3
+# pw-link lcolonq-hls:monitor_FL alsa_capture.newton_renderer:input_FL
+# pw-link lcolonq-hls:monitor_FR alsa_capture.newton_renderer:input_FR
+cargo run -p newton_renderer overlay
wait