From e63685632f5fa560f5ebc8190f670f41d9218879 Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Tue, 10 Dec 2024 15:10:00 -0500 Subject: Native done --- .dir-locals.el | 2 + .envrc | 1 + Cargo.lock | 533 ++++++++++++++++++++++++++++++++++++++++++---------- Cargo.toml | 6 +- nix/flake.nix | 27 +-- rust-toolchain.toml | 2 +- src/audio.rs | 52 ++++- src/context.rs | 64 +++++-- src/framebuffer.rs | 6 + src/lib.rs | 327 +++++++++++++++++--------------- src/state.rs | 47 +++-- 11 files changed, 760 insertions(+), 307 deletions(-) create mode 100644 .dir-locals.el create mode 100644 .envrc diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..23a499f --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,2 @@ +;; ((rust-mode . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:target "wasm32-unknown-unknown"))))))) +((rust-mode . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:target "x86_64-unknown-linux-gnu"))))))) diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..7efd1f8 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use_flake path:nix diff --git a/Cargo.lock b/Cargo.lock index a7ec47c..29ac2b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,28 @@ dependencies = [ "memchr", ] +[[package]] +name = "alsa" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" +dependencies = [ + "alsa-sys", + "bitflags 2.6.0", + "cfg-if", + "libc", +] + +[[package]] +name = "alsa-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "android-activity" version = "0.5.2" @@ -188,6 +210,24 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + [[package]] name = "bit_field" version = "0.10.2" @@ -292,6 +332,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -305,12 +354,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] -name = "cgl" -version = "0.3.2" +name = "clang-sys" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ + "glob", "libc", + "libloading", ] [[package]] @@ -404,6 +455,49 @@ dependencies = [ "libc", ] +[[package]] +name = "coreaudio-rs" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" +dependencies = [ + "bitflags 1.3.2", + "core-foundation-sys", + "coreaudio-sys", +] + +[[package]] +name = "coreaudio-sys" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ce857aa0b77d77287acc1ac3e37a05a8c95a2af3647d23b15f263bdaeb7562b" +dependencies = [ + "bindgen", +] + +[[package]] +name = "cpal" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" +dependencies = [ + "alsa", + "core-foundation-sys", + "coreaudio-rs", + "dasp_sample", + "jni", + "js-sys", + "libc", + "mach2", + "ndk", + "ndk-context", + "oboe", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows", +] + [[package]] name = "crc32fast" version = "1.4.0" @@ -450,6 +544,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + [[package]] name = "dispatch" version = "0.2.0" @@ -561,6 +661,12 @@ dependencies = [ "zune-inflate", ] +[[package]] +name = "extended" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" + [[package]] name = "fastrand" version = "2.1.1" @@ -731,21 +837,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] -name = "gl_generator" -version = "0.14.0" +name = "glam" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" + +[[package]] +name = "glam" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" dependencies = [ - "khronos_api", - "log", - "xml-rs", + "mint", ] [[package]] -name = "glam" -version = "0.25.0" +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "glow" @@ -759,71 +869,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "glutin" -version = "0.31.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" -dependencies = [ - "bitflags 2.6.0", - "cfg_aliases", - "cgl", - "core-foundation", - "dispatch", - "glutin_egl_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "icrate", - "libloading", - "objc2", - "once_cell", - "raw-window-handle 0.5.2", - "wayland-sys", - "windows-sys 0.48.0", - "x11-dl", -] - -[[package]] -name = "glutin-winit" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebcdfba24f73b8412c5181e56f092b5eff16671c514ce896b258a0a64bd7735" -dependencies = [ - "cfg_aliases", - "glutin", - "raw-window-handle 0.5.2", - "winit", -] - -[[package]] -name = "glutin_egl_sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77cc5623f5309ef433c3dd4ca1223195347fe62c413da8e2fdd0eb76db2d9bcd" -dependencies = [ - "gl_generator", - "windows-sys 0.48.0", -] - -[[package]] -name = "glutin_glx_sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a165fd686c10dcc2d45380b35796e577eacfd43d4660ee741ec8ebe2201b3b4f" -dependencies = [ - "gl_generator", - "x11-dl", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" -dependencies = [ - "gl_generator", -] - [[package]] name = "h2" version = "0.4.6" @@ -1044,6 +1089,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1100,10 +1154,20 @@ dependencies = [ ] [[package]] -name = "khronos_api" -version = "3.1.0" +name = "kira" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +checksum = "fb5a9f9dff5e262540b628b00d5e1a772270a962d6869f8695bb24832ff3b394" +dependencies = [ + "cpal", + "glam 0.29.2", + "mint", + "paste", + "ringbuf", + "send_wrapper", + "symphonia", + "triple_buffer", +] [[package]] name = "lazy_static" @@ -1166,6 +1230,15 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + [[package]] name = "memchr" version = "2.7.1" @@ -1187,6 +1260,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -1197,6 +1276,12 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mint" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff" + [[package]] name = "mio" version = "1.0.2" @@ -1237,8 +1322,7 @@ dependencies = [ "log", "ndk-sys", "num_enum", - "raw-window-handle 0.5.2", - "raw-window-handle 0.6.0", + "raw-window-handle", "thiserror", ] @@ -1257,6 +1341,27 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -1318,6 +1423,29 @@ dependencies = [ "memchr", ] +[[package]] +name = "oboe" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" +dependencies = [ + "jni", + "ndk", + "ndk-context", + "num-derive", + "num-traits", + "oboe-sys", +] + +[[package]] +name = "oboe-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d" +dependencies = [ + "cc", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -1386,6 +1514,12 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1518,12 +1652,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "raw-window-handle" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" - [[package]] name = "raw-window-handle" version = "0.6.0" @@ -1655,12 +1783,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ringbuf" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79abed428d1fd2a128201cec72c5f6938e2da607c6f3745f769fabea399d950a" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.31" @@ -1762,6 +1905,29 @@ dependencies = [ "tiny-skia", ] +[[package]] +name = "sdl2" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b498da7d14d1ad6c839729bd4ad6fc11d90a57583605f3b4df2cd709a9cd380" +dependencies = [ + "bitflags 1.3.2", + "lazy_static", + "libc", + "sdl2-sys", +] + +[[package]] +name = "sdl2-sys" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951deab27af08ed9c6068b7b0d05a93c91f0a8eb16b6b816a5e73452a43521d3" +dependencies = [ + "cfg-if", + "libc", + "version-compare", +] + [[package]] name = "security-framework" version = "2.10.0" @@ -1785,6 +1951,12 @@ dependencies = [ "libc", ] +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + [[package]] name = "serde" version = "1.0.197" @@ -1939,6 +2111,127 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "symphonia" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9" +dependencies = [ + "lazy_static", + "symphonia-bundle-flac", + "symphonia-bundle-mp3", + "symphonia-codec-pcm", + "symphonia-codec-vorbis", + "symphonia-core", + "symphonia-format-ogg", + "symphonia-format-riff", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-bundle-flac" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e34f34298a7308d4397a6c7fbf5b84c5d491231ce3dd379707ba673ab3bd97" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-bundle-mp3" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01c2aae70f0f1fb096b6f0ff112a930b1fb3626178fba3ae68b09dce71706d4" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-codec-pcm" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f395a67057c2ebc5e84d7bb1be71cce1a7ba99f64e0f0f0e303a03f79116f89b" +dependencies = [ + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-vorbis" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a98765fb46a0a6732b007f7e2870c2129b6f78d87db7987e6533c8f164a9f30" +dependencies = [ + "log", + "symphonia-core", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-core" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3" +dependencies = [ + "arrayvec", + "bitflags 1.3.2", + "bytemuck", + "lazy_static", + "log", +] + +[[package]] +name = "symphonia-format-ogg" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada3505789516bcf00fc1157c67729eded428b455c27ca370e41f4d785bfa931" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-riff" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f7be232f962f937f4b7115cbe62c330929345434c834359425e043bfd15f50" +dependencies = [ + "extended", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-metadata" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c" +dependencies = [ + "encoding_rs", + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-utils-xiph" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe" +dependencies = [ + "symphonia-core", + "symphonia-metadata", +] + [[package]] name = "syn" version = "2.0.52" @@ -1991,16 +2284,15 @@ dependencies = [ "enum-map", "env_logger", "getrandom", - "glam", + "glam 0.25.0", "glow", - "glutin", - "glutin-winit", "image", "js-sys", + "kira", "log", "rand", - "raw-window-handle 0.5.2", "reqwest", + "sdl2", "serde", "tobj", "tracing-wasm", @@ -2238,6 +2530,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "triple_buffer" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e66931c8eca6381f0d34656a9341f09bd462010488c1a3bc0acd3f2d08dffce" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -2306,6 +2607,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + [[package]] name = "version_check" version = "0.9.4" @@ -2569,17 +2876,46 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + [[package]] name = "windows-registry" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-strings", "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.2.0" @@ -2595,7 +2931,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-targets 0.52.6", ] @@ -2840,8 +3176,7 @@ dependencies = [ "once_cell", "orbclient", "percent-encoding", - "raw-window-handle 0.5.2", - "raw-window-handle 0.6.0", + "raw-window-handle", "redox_syscall 0.3.5", "rustix", "sctk-adwaita", @@ -2928,12 +3263,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" -[[package]] -name = "xml-rs" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" - [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index 3ea5ef3..1f5db5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,5 @@ web-sys = { version = "*", features = ["Document", "Window", "Element", "HtmlCan [target.'cfg(not(target_arch = "wasm32"))'.dependencies] env_logger = "*" -winit = { version = "0.29", features = ["x11", "rwh_05"], default-features = false } # windowing and events -raw-window-handle = { version = "0.5" } # get window handle -glutin = { version = "0.31" } # obtain opengl context -glutin-winit = { version = "0.4" } # obtain opengl context \ No newline at end of file +sdl2 = "*" +kira = "*" \ No newline at end of file diff --git a/nix/flake.nix b/nix/flake.nix index 3f5071a..ed649a8 100644 --- a/nix/flake.nix +++ b/nix/flake.nix @@ -15,18 +15,23 @@ pkgs.clang pkgs.llvmPackages.libclang pkgs.openssl + pkgs.pkg-config + pkgs.SDL2 + pkgs.glxinfo + pkgs.alsa-lib ]; - LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${ - with pkgs; - pkgs.lib.makeLibraryPath [ - libGL - xorg.libX11 - xorg.libXcursor - xorg.libXi - libxkbcommon - xorg.libxcb - ] - }"; + # LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${ + # with pkgs; + # pkgs.lib.makeLibraryPath [ + # libGL + # xorg.libX11 + # xorg.libXcursor + # xorg.libXi + # libxkbcommon + # xorg.libxcb + # libglvnd + # ] + # }"; }; }; } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index a09cf93..054a092 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -targets = [ "wasm32-unknown-unknown" ] \ No newline at end of file +targets = [ "x86_64-unknown-linux-gnu", "wasm32-unknown-unknown" ] \ No newline at end of file diff --git a/src/audio.rs b/src/audio.rs index 5cbce90..0dca32e 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -103,28 +103,53 @@ impl Assets { #[cfg(not(target_arch = "wasm32"))] pub struct Context { + manager: kira::manager::AudioManager, } #[cfg(not(target_arch = "wasm32"))] impl Context { pub fn new() -> Self { Self { + manager: kira::manager::AudioManager::new(kira::manager::AudioManagerSettings::default()) + .expect("failed to create audio manager"), } } } #[cfg(not(target_arch = "wasm32"))] pub struct Audio { + data: kira::sound::static_sound::StaticSoundData, } #[cfg(not(target_arch = "wasm32"))] impl Audio { - pub fn new(ctx: &Context, _bytes: &[u8]) -> Self { + pub fn new(_ctx: &Context, bytes: &'static [u8]) -> Self { Self { + data: kira::sound::static_sound::StaticSoundData::from_cursor(std::io::Cursor::new(bytes)) + .expect("failed to decode audio"), } } - pub fn play(&self, ctx: &Context, looping: Option<(Option, Option)>) { + pub fn play( + &self, + ctx: &mut Context, + looping: Option<(Option, Option)> + ) -> Result + { + let sd = if let Some((ss, se)) = looping { + let start = if let Some(s) = ss { s } else { 0.0 }; + if let Some(e) = se { + self.data.loop_region(start..e) + } else { + self.data.loop_region(start..) + } + } else { + self.data.clone() + }; + match ctx.manager.play(sd) { + Ok(h) => Ok(h), + Err(e) => Err(e.to_string()), + } } } @@ -132,6 +157,7 @@ impl Audio { pub struct Assets { pub ctx: Context, pub audio: HashMap, + pub music_handle: Option, } #[cfg(not(target_arch = "wasm32"))] @@ -144,19 +170,37 @@ impl Assets { Self { ctx, audio, + music_handle: None, } } pub fn play_sfx(&mut self, name: &str) { if let Some(a) = self.audio.get(name) { - a.play(&self.ctx, None); + if let Err(e) = a.play(&mut self.ctx, None) { + log::warn!("failed to play sound {}: {}", name, e); + } } } pub fn is_music_playing(&self) -> bool { - false + if let Some(mh) = &self.music_handle { + mh.state() == kira::sound::PlaybackState::Playing + } else { false } } pub fn play_music(&mut self, name: &str, start: Option, end: Option) { + if let Some(s) = &mut self.music_handle { + let _ = s.stop(kira::tween::Tween::default()); + } + if let Some(a) = self.audio.get(name) { + match a.play(&mut self.ctx, Some((start, end))) { + Ok(h) => { + self.music_handle = Some(h); + }, + Err(e) => { + log::warn!("failed to play music {}: {}", name, e); + } + } + } } } diff --git a/src/context.rs b/src/context.rs index c6c68bc..28d0a79 100644 --- a/src/context.rs +++ b/src/context.rs @@ -26,32 +26,41 @@ pub fn compute_upscale(windoww: u32, windowh: u32) -> u32 { (ratio - 1).max(1) } +#[cfg(not(target_arch = "wasm32"))] pub struct Context { - pub window: winit::window::Window, + pub window: sdl2::video::Window, pub gl: glow::Context, pub emptyvao: glow::VertexArray, + pub timer: sdl2::TimerSubsystem, +} - #[cfg(target_arch = "wasm32")] + +#[cfg(target_arch = "wasm32")] +pub struct Context { + pub window: winit::window::Window, + pub gl: glow::Context, + pub emptyvao: glow::VertexArray, pub performance: web_sys::Performance, } impl Context { - pub fn new(window: winit::window::Window, gl: glow::Context) -> Self { - unsafe { - gl.clear_color(0.1, 0.1, 0.1, 1.0); - gl.clear_depth_f32(1.0); - - gl.enable(glow::DEPTH_TEST); - gl.depth_func(glow::LEQUAL); - - gl.enable(glow::BLEND); - gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA); - - gl.enable(glow::STENCIL_TEST); - - gl.cull_face(glow::FRONT); - } + #[cfg(not(target_arch = "wasm32"))] + pub fn new(sdl: sdl2::Sdl, window: sdl2::video::Window, gl: glow::Context) -> Self { + let emptyvao = unsafe { + gl.create_vertex_array().expect("failed to initialize vao") + }; + let ret = Self { + window, + gl, + emptyvao, + timer: sdl.timer().expect("failed to initialize timer subsystem"), + }; + ret.init(); + ret + } + #[cfg(target_arch = "wasm32")] + pub fn new(window: winit::window::Window, gl: glow::Context) -> Self { let emptyvao = unsafe { gl.create_vertex_array().expect("failed to initialize vao") }; @@ -59,7 +68,7 @@ impl Context { #[cfg(target_arch = "wasm32")] unsafe { js_track_resized_setup(); } - Self { + let ret = Self { window, gl, emptyvao, @@ -67,6 +76,25 @@ impl Context { #[cfg(target_arch = "wasm32")] performance: web_sys::window().expect("failed to find window") .performance().expect("failed to get performance"), + }; + ret.init(); + ret + } + + pub fn init(&self) { + unsafe { + self.gl.clear_color(0.1, 0.1, 0.1, 1.0); + self.gl.clear_depth_f32(1.0); + + self.gl.enable(glow::DEPTH_TEST); + self.gl.depth_func(glow::LEQUAL); + + self.gl.enable(glow::BLEND); + self.gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA); + + self.gl.enable(glow::STENCIL_TEST); + + self.gl.cull_face(glow::FRONT); } } diff --git a/src/framebuffer.rs b/src/framebuffer.rs index c0ac72b..fb6ab02 100644 --- a/src/framebuffer.rs +++ b/src/framebuffer.rs @@ -11,7 +11,13 @@ pub struct Framebuffer { impl Framebuffer { pub fn screen(ctx: &context::Context) -> Self { + #[cfg(target_arch = "wasm32")] let (windoww, windowh): (f32, f32) = ctx.window.inner_size().into(); + #[cfg(not(target_arch = "wasm32"))] + let (windoww, windowh) = { + let (w, h) = ctx.window.size(); + (w as f32, h as f32) + }; let ratio = context::compute_upscale(windoww as _, windowh as _) as f32; let upscalew = context::RENDER_WIDTH * ratio; let upscaleh = context::RENDER_HEIGHT * ratio; diff --git a/src/lib.rs b/src/lib.rs index b89b27e..d0fdfc0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,113 +35,123 @@ where } } -pub fn event_loop_body(event: winit::event::Event<()>, elwt: &winit::event_loop::EventLoopWindowTarget<()>) - where G: state::Game + 'static, +#[cfg(not(target_arch = "wasm32"))] +pub async fn run<'a, F, G, Fut>(title: &str, gnew: F) +where + Fut: std::future::Future, + G: state::Game + 'static, + F: (Fn(&'a context::Context) -> Fut), { - contextualize(|ctx, st, game: &mut G| { - match &event { - winit::event::Event::WindowEvent { - event: wev, - window_id, - .. - } => match wev { - winit::event::WindowEvent::CloseRequested - if *window_id == ctx.window.id() => elwt.exit(), - winit::event::WindowEvent::Resized{..} => { - #[cfg(target_arch = "wasm32")] - ctx.maximize_canvas(); + env_logger::Builder::new() + .filter(None, log::LevelFilter::Info) + .init(); + + log::info!("hello computer, starting up..."); + + let (sdl, window, gl, mut event_loop, _gl_context) = { + let sdl = sdl2::init().expect("failed to initialize SDL2"); + let video = sdl.video().expect("failed to initialize SDL2 video"); + // let gl_attr = video.gl_attr(); + // gl_attr.set_context_profile(sdl2::video::GLProfile::Core); + // gl_attr.set_context_version(3, 0); + let window = video + .window(title, 640, 360) + .opengl() + // .fullscreen_desktop() + .resizable() + .build() + .unwrap(); + let gl_context = window.gl_create_context().unwrap(); + let gl = unsafe { + glow::Context::from_loader_function(|s| video.gl_get_proc_address(s) as *const _) + }; + let event_loop = sdl.event_pump().unwrap(); + (sdl, window, gl, event_loop, gl_context) + }; + + let ctx = Box::leak(Box::new(context::Context::new(sdl, window, gl))); + let game = Box::leak(Box::new(gnew(ctx).await)); + let st = Box::leak(Box::new(state::State::new(&ctx))); + + unsafe { + CTX = Some(ctx as _); + ST = Some(st as _); + G = Some(game as *mut G as *mut std::ffi::c_void); + } + + 'running: loop { + for event in event_loop.poll_iter() { + match event { + sdl2::event::Event::Quit {..} => { + log::info!("bye!"); + break 'running; + }, + sdl2::event::Event::Window { win_event: sdl2::event::WindowEvent::Resized(_, _), .. } => { st.handle_resize(&ctx); }, - winit::event::WindowEvent::Focused(false) => { + sdl2::event::Event::Window { win_event: sdl2::event::WindowEvent::FocusLost, .. } => { st.keys = state::Keys::new(); }, - winit::event::WindowEvent::CursorMoved { position, ..} => { - st.mouse_moved(&ctx, position.x as f32, position.y as f32, game); + sdl2::event::Event::MouseMotion { x, y, .. } => { + st.mouse_moved(&ctx, x as f32, y as f32, game); + }, + sdl2::event::Event::MouseButtonDown {..} => { + st.mouse_pressed(&ctx, game) + }, + sdl2::event::Event::MouseButtonUp {..} => { + st.mouse_released(&ctx) + }, + sdl2::event::Event::KeyDown { keycode: Some(key), repeat: false, .. } => { + st.key_pressed(&ctx, key) + }, + sdl2::event::Event::KeyUp { keycode: Some(key), repeat: false, .. } => { + st.key_released(&ctx, key) }, - winit::event::WindowEvent::MouseInput { - button, - state, - .. - } => match state { - winit::event::ElementState::Pressed => { - st.mouse_pressed(&ctx, *button, game) - }, - winit::event::ElementState::Released => { - st.mouse_released(&ctx, *button) - }, - } - winit::event::WindowEvent::KeyboardInput { - event: winit::event::KeyEvent { - physical_key: winit::keyboard::PhysicalKey::Code(key), - state, - repeat: false, - .. - }, - .. - } => match state { - winit::event::ElementState::Pressed => { - st.key_pressed(&ctx, *key) - }, - winit::event::ElementState::Released => { - st.key_released(&ctx, *key) - }, - } _ => {}, - }, - - winit::event::Event::AboutToWait => { - if ctx.resize_necessary() { - #[cfg(target_arch = "wasm32")] - ctx.maximize_canvas(); - st.handle_resize(&ctx); - } - if let Some(f) = &mut st.request { - match std::future::Future::poll(f.as_mut(), &mut st.waker_ctx) { - std::task::Poll::Pending => {}, - std::task::Poll::Ready(res) => { - st.request = None; - match res { - Ok(r) => st.request_returned(&ctx, game, r), - Err(e) => log::warn!("error during HTTP request: {}", e), - } - }, + } + } + if ctx.resize_necessary() { + st.handle_resize(&ctx); + } + if let Some(f) = &mut st.request { + match std::future::Future::poll(f.as_mut(), &mut st.waker_ctx) { + std::task::Poll::Pending => {}, + std::task::Poll::Ready(res) => { + st.request = None; + match res { + Ok(r) => st.request_returned(&ctx, game, r), + Err(e) => log::warn!("error during HTTP request: {}", e), } - // f.poll(); - } - st.run_update(&ctx, game); - st.run_render(&ctx, game); - ctx.window.request_redraw(); - }, - - _ => {}, + }, + } } - }); + st.run_update(&ctx, game); + st.run_render(&ctx, game); + ctx.window.gl_swap_window(); + } + + // event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll); + // event_loop.run(|event, elwt| { + // event_loop_body::(event, elwt); + // }).expect("window closed"); } +#[cfg(target_arch = "wasm32")] pub async fn run<'a, F, G, Fut>(gnew: F) where Fut: std::future::Future, G: state::Game + 'static, F: (Fn(&'a context::Context) -> Fut), { - #[cfg(target_arch = "wasm32")] - { - console_log::init_with_level(log::Level::Debug).unwrap(); - console_error_panic_hook::set_once(); - tracing_wasm::set_as_global_default(); - } - #[cfg(not(target_arch = "wasm32"))] - { - env_logger::Builder::new() - .filter(None, log::LevelFilter::Info) - .init(); - } + console_log::init_with_level(log::Level::Debug).unwrap(); + console_error_panic_hook::set_once(); + tracing_wasm::set_as_global_default(); + log::info!("hello computer, starting up..."); let event_loop = winit::event_loop::EventLoop::new() .expect("failed to initialize event loop"); - #[cfg(target_arch = "wasm32")] let (window, gl) = { let window = winit::window::WindowBuilder::new() .with_maximized(true) @@ -163,63 +173,10 @@ where (window, gl) }; - #[cfg(not(target_arch = "wasm32"))] - let (window, gl) = { - use glutin::config::GlConfig; - use glutin::context::NotCurrentGlContext; - use glutin::display::{GlDisplay, GetGlDisplay}; - use glutin::surface::GlSurface; - use raw_window_handle::HasRawWindowHandle; - use glutin_winit::GlWindow; - let window_builder = winit::window::WindowBuilder::new() - .with_title("teleia") - .with_maximized(true) - .with_decorations(false); - let template = glutin::config::ConfigTemplateBuilder::new(); - let display_builder = glutin_winit::DisplayBuilder::new().with_window_builder(Some(window_builder)); - let (window, gl_config) = display_builder - .build(&event_loop, template, |configs| { - configs.reduce(|a, c| { - if c.num_samples() > a.num_samples() { c } else { a } - }).expect("failed to obtain select configuration") - }).expect("failed to obtain opengl display"); - let window = window.expect("failed to create window"); - let raw_window_handle = window.raw_window_handle(); - let gl_display = gl_config.display(); - let context_attributes = glutin::context::ContextAttributesBuilder::new() - // .with_context_api(glutin::context::ContextApi::OpenGl(Some(glutin::context::Version { - // major: 3, - // minor: 3, - // }))) - .build(Some(raw_window_handle)); - unsafe { - let not_current_gl_context = gl_display.create_context(&gl_config, &context_attributes) - .expect("failed to obtain opengl context"); - let attrs = window.build_surface_attributes(Default::default()); - let gl_surface = gl_display.create_window_surface(&gl_config, &attrs) - .expect("failed to create opengl surface"); - let gl_context = not_current_gl_context.make_current(&gl_surface) - .expect("failed to set openglt context"); - let gl = glow::Context::from_loader_function_cstr(|s| gl_display.get_proc_address(s)); - gl_surface - .set_swap_interval(&gl_context, glutin::surface::SwapInterval::Wait(std::num::NonZeroU32::new(1).unwrap())) - .expect("failed to set swap interval"); - (window, gl) - } - }; - let ctx = Box::leak(Box::new(context::Context::new(window, gl))); - - #[cfg(target_arch = "wasm32")] - { - ctx.maximize_canvas(); - } - + ctx.maximize_canvas(); let game = Box::leak(Box::new(gnew(ctx).await)); let st = Box::leak(Box::new(state::State::new(&ctx))); - // request = Some(Box::new(async { - // "foo".to_owned() - // })); unsafe { CTX = Some(ctx as _); @@ -227,20 +184,84 @@ where G = Some(game as *mut G as *mut std::ffi::c_void); } + event_loop.set_control_flow(winit::event_loop::ControlFlow::Wait); + event_loop.spawn(|event, elwt| { + contextualize(|ctx, st, game: &mut G| { + match &event { + winit::event::Event::WindowEvent { + event: wev, + window_id, + .. + } => match wev { + winit::event::WindowEvent::CloseRequested + if *window_id == ctx.window.id() => elwt.exit(), + winit::event::WindowEvent::Resized{..} => { + #[cfg(target_arch = "wasm32")] + ctx.maximize_canvas(); + st.handle_resize(&ctx); + }, + winit::event::WindowEvent::Focused(false) => { + st.keys = state::Keys::new(); + }, + winit::event::WindowEvent::CursorMoved { position, ..} => { + st.mouse_moved(&ctx, position.x as f32, position.y as f32, game); + }, + winit::event::WindowEvent::MouseInput { + state, + .. + } => match state { + winit::event::ElementState::Pressed => { + st.mouse_pressed(&ctx, game) + }, + winit::event::ElementState::Released => { + st.mouse_released(&ctx) + }, + } + winit::event::WindowEvent::KeyboardInput { + event: winit::event::KeyEvent { + physical_key: winit::keyboard::PhysicalKey::Code(key), + state, + repeat: false, + .. + }, + .. + } => match state { + winit::event::ElementState::Pressed => { + st.key_pressed(&ctx, *key) + }, + winit::event::ElementState::Released => { + st.key_released(&ctx, *key) + }, + } + _ => {}, + }, + + winit::event::Event::AboutToWait => { + if ctx.resize_necessary() { + #[cfg(target_arch = "wasm32")] + ctx.maximize_canvas(); + st.handle_resize(&ctx); + } + if let Some(f) = &mut st.request { + match std::future::Future::poll(f.as_mut(), &mut st.waker_ctx) { + std::task::Poll::Pending => {}, + std::task::Poll::Ready(res) => { + st.request = None; + match res { + Ok(r) => st.request_returned(&ctx, game, r), + Err(e) => log::warn!("error during HTTP request: {}", e), + } + }, + } + // f.poll(); + } + st.run_update(&ctx, game); + st.run_render(&ctx, game); + ctx.window.request_redraw(); + }, - #[cfg(target_arch = "wasm32")] - { - event_loop.set_control_flow(winit::event_loop::ControlFlow::Wait); - event_loop.spawn(|event, elwt| { - event_loop_body::(event, elwt); + _ => {}, + } }); - } - - #[cfg(not(target_arch = "wasm32"))] - { - event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll); - event_loop.run(|event, elwt| { - event_loop_body::(event, elwt); - }).expect("window closed"); - } + }); } diff --git a/src/state.rs b/src/state.rs index c5478a9..0be163b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -93,11 +93,13 @@ pub struct PointLight { pub attenuation: glam::Vec2, } -#[cfg(target_arch = "wasm32")] type Timestamp = f64; +#[cfg(target_arch = "wasm32")] +type Keycode = winit::keyboard::KeyCode; + #[cfg(not(target_arch = "wasm32"))] -type Timestamp = std::time::Instant; +type Keycode = sdl2::keyboard::Keycode; pub struct State { pub acc: f64, @@ -105,7 +107,7 @@ pub struct State { pub tick: u64, pub rebinding: Option, - pub keybindings: BiHashMap, + pub keybindings: BiHashMap, pub keys: Keys, pub screen: framebuffer::Framebuffer, @@ -131,11 +133,13 @@ pub fn now(ctx: &context::Context) -> Timestamp { } #[cfg(not(target_arch = "wasm32"))] -pub fn now(_ctx: &context::Context) -> Timestamp { - std::time::Instant::now() +pub fn now(ctx: &context::Context) -> Timestamp { + let ms = ctx.timer.ticks64(); + (ms as f64) / 1000.0 } -pub fn default_keybindings() -> BiHashMap { +#[cfg(target_arch = "wasm32")] +pub fn default_keybindings() -> BiHashMap { BiHashMap::from_iter(vec![ (winit::keyboard::KeyCode::KeyW, Key::Up), (winit::keyboard::KeyCode::KeyS, Key::Down), @@ -150,6 +154,22 @@ pub fn default_keybindings() -> BiHashMap { ]) } +#[cfg(not(target_arch = "wasm32"))] +pub fn default_keybindings() -> BiHashMap { + BiHashMap::from_iter(vec![ + (sdl2::keyboard::Keycode::W, Key::Up), + (sdl2::keyboard::Keycode::S, Key::Down), + (sdl2::keyboard::Keycode::A, Key::Left), + (sdl2::keyboard::Keycode::D, Key::Right), + (sdl2::keyboard::Keycode::NUM_1, Key::A), + (sdl2::keyboard::Keycode::NUM_2, Key::B), + (sdl2::keyboard::Keycode::Q, Key::L), + (sdl2::keyboard::Keycode::E, Key::R), + (sdl2::keyboard::Keycode::TAB, Key::Start), + (sdl2::keyboard::Keycode::SPACE, Key::Select), + ]) +} + impl State { pub fn new(ctx: &context::Context) -> Self { let screen = framebuffer::Framebuffer::screen(ctx); @@ -347,7 +367,6 @@ impl State { pub fn mouse_pressed( &mut self, ctx: &context::Context, - _button: winit::event::MouseButton, game: &mut G ) where G: Game { log::info!("click"); @@ -363,16 +382,19 @@ impl State { pub fn mouse_released( &mut self, _ctx: &context::Context, - _button: winit::event::MouseButton, ) { } pub fn key_pressed( &mut self, _ctx: &context::Context, - key: winit::keyboard::KeyCode, + key: Keycode, ) { - if key == winit::keyboard::KeyCode::F12 { + #[cfg(target_arch = "wasm32")] + let rebind = key == winit::keyboard::KeyCode::F12; + #[cfg(not(target_arch = "wasm32"))] + let rebind = key == sdl2::keyboard::Keycode::F12; + if rebind { self.keybindings = default_keybindings(); self.rebinding = None; self.write_log("Reset keybindings!"); @@ -388,7 +410,7 @@ impl State { pub fn key_released( &mut self, _ctx: &context::Context, - key: winit::keyboard::KeyCode, + key: Keycode, ) { if let Some(k) = self.keybindings.get_by_left(&key) { self.keys.pressed[*k] = false; @@ -437,10 +459,7 @@ impl State { pub fn run_update(&mut self, ctx: &context::Context, game: &mut G) where G: Game { let now = now(ctx); - #[cfg(target_arch = "wasm32")] let diff = now - self.last; - #[cfg(not(target_arch = "wasm32"))] - let diff = now.duration_since(self.last).as_secs_f64(); self.acc += diff; self.last = now; -- cgit v1.2.3