diff options
| author | LLLL Colonq <llll@colonq> | 2025-01-28 12:03:11 -0500 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2025-01-28 12:03:11 -0500 |
| commit | 23d651bbad510f14484cf1c0a8081ffff890565e (patch) | |
| tree | 3645723cb9383bcf8ea3733d50d76ba1fe86e131 | |
| parent | f448de77d84b985047a332150c0382adc1836899 (diff) | |
Working overlay
| -rw-r--r-- | Cargo.lock | 93 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | flake.nix | 37 | ||||
| -rw-r--r-- | src/common.rs (renamed from src/newton.rs) | 0 | ||||
| -rw-r--r-- | src/common/client.rs (renamed from src/newton/client.rs) | 0 | ||||
| -rw-r--r-- | src/common/client/assets.rs (renamed from src/newton/client/assets.rs) | 0 | ||||
| -rw-r--r-- | src/common/client/assets/audio/test.wav (renamed from src/newton/client/assets/audio/test.wav) | bin | 924 -> 924 bytes | |||
| -rw-r--r-- | src/common/client/assets/meshes/square.obj (renamed from src/newton/client/assets/meshes/square.obj) | 0 | ||||
| -rw-r--r-- | src/common/client/assets/shaders/flat/frag.glsl (renamed from src/newton/client/assets/shaders/flat/frag.glsl) | 0 | ||||
| -rw-r--r-- | src/common/client/assets/shaders/flat/vert.glsl (renamed from src/newton/client/assets/shaders/flat/vert.glsl) | 0 | ||||
| -rw-r--r-- | src/common/client/assets/textures/test.png (renamed from src/newton/client/assets/textures/test.png) | bin | 714 -> 714 bytes | |||
| -rw-r--r-- | src/common/overlay.rs | 125 | ||||
| -rw-r--r-- | src/common/overlay/assets.rs (renamed from src/newton/overlay/assets.rs) | 0 | ||||
| -rw-r--r-- | src/common/overlay/assets/audio/test.wav (renamed from src/newton/overlay/assets/audio/test.wav) | bin | 924 -> 924 bytes | |||
| -rw-r--r-- | src/common/overlay/assets/fonts/iosevka-comfy-regular.ttf (renamed from src/newton/overlay/assets/fonts/iosevka-comfy-regular.ttf) | bin | 7811628 -> 7811628 bytes | |||
| -rw-r--r-- | src/common/overlay/assets/fonts/terminus.png (renamed from src/newton/overlay/assets/fonts/terminus.png) | bin | 1215 -> 1215 bytes | |||
| -rw-r--r-- | src/common/overlay/assets/fonts/terminus.ttf (renamed from src/newton/overlay/assets/fonts/terminus.ttf) | bin | 500668 -> 500668 bytes | |||
| -rw-r--r-- | src/common/overlay/assets/meshes/square.obj (renamed from src/newton/overlay/assets/meshes/square.obj) | 0 | ||||
| -rw-r--r-- | src/common/overlay/assets/scenes/lcolonq.vrm (renamed from src/newton/overlay/assets/scenes/lcolonq.vrm) | bin | 12451548 -> 12451548 bytes | |||
| -rw-r--r-- | src/common/overlay/assets/shaders/flat/frag.glsl (renamed from src/newton/overlay/assets/shaders/flat/frag.glsl) | 0 | ||||
| -rw-r--r-- | src/common/overlay/assets/shaders/flat/vert.glsl (renamed from src/newton/overlay/assets/shaders/flat/vert.glsl) | 0 | ||||
| -rw-r--r-- | src/common/overlay/assets/shaders/scene/frag.glsl (renamed from src/newton/overlay/assets/shaders/scene/frag.glsl) | 0 | ||||
| -rw-r--r-- | src/common/overlay/assets/shaders/scene/vert.glsl (renamed from src/newton/overlay/assets/shaders/scene/vert.glsl) | 0 | ||||
| -rw-r--r-- | src/common/overlay/assets/textures/test.png (renamed from src/newton/overlay/assets/textures/test.png) | bin | 714 -> 714 bytes | |||
| -rw-r--r-- | src/common/overlay/fig.rs | 40 | ||||
| -rw-r--r-- | src/common/overlay/terminal.rs (renamed from src/newton/overlay/terminal.rs) | 56 | ||||
| -rw-r--r-- | src/common/server.rs (renamed from src/newton/server.rs) | 0 | ||||
| -rw-r--r-- | src/lib.rs | 4 | ||||
| -rw-r--r-- | src/main.rs | 4 | ||||
| -rw-r--r-- | src/newton/overlay.rs | 76 |
30 files changed, 290 insertions, 147 deletions
@@ -274,7 +274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" dependencies = [ "block-sys", - "objc2", + "objc2 0.4.1", ] [[package]] @@ -915,6 +915,17 @@ dependencies = [ ] [[package]] +name = "glfw" +version = "0.59.0" +dependencies = [ + "bitflags 1.3.2", + "objc2 0.5.2", + "raw-window-handle", + "serde", + "winapi", +] + +[[package]] name = "glob" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1143,7 +1154,7 @@ checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" dependencies = [ "block2", "dispatch", - "objc2", + "objc2 0.4.1", ] [[package]] @@ -1438,6 +1449,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] +name = "lexpr" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a84de6a9df442363b08f5dbf0cd5b92edc70097b89c4ce4bfea4679fe48bc67" +dependencies = [ + "itoa", + "lexpr-macros", + "ryu", +] + +[[package]] +name = "lexpr-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36b5cb8bb985c81a8ac1a0f8b5c4865214f574ddd64397ef7a99c236e21f35bb" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] name = "libc" version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1613,7 +1645,9 @@ dependencies = [ "glam", "glow", "lazy_static", + "lexpr", "log", + "polling", "rand", "strum", "teleia", @@ -1675,9 +1709,9 @@ dependencies = [ [[package]] name = "objc-sys" -version = "0.3.2" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" [[package]] name = "objc2" @@ -1686,7 +1720,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" dependencies = [ "objc-sys", - "objc2-encode", + "objc2-encode 3.0.0", +] + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode 4.1.0", ] [[package]] @@ -1696,6 +1740,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" [[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] name = "object" version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2245,29 +2295,6 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2679,6 +2706,7 @@ dependencies = [ "fontdue", "getrandom", "glam", + "glfw", "glow", "gltf", "image 0.24.9", @@ -2687,7 +2715,6 @@ dependencies = [ "log", "rand", "reqwest", - "sdl2", "serde", "tobj", "tracing-wasm", @@ -3041,12 +3068,6 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3605,7 +3626,7 @@ dependencies = [ "memmap2", "ndk", "ndk-sys", - "objc2", + "objc2 0.4.1", "once_cell", "orbclient", "percent-encoding", @@ -27,6 +27,8 @@ rand = "*" # rng log = "*" # logging lazy_static = "*" # global constants strum = {version = "*", features = ["derive"]} # utility macros for enums +polling = "*" # polling sockets +lexpr = "*" # s-expression parsing [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = "*" # wasm bindings @@ -67,30 +67,37 @@ }); in { - checks = { - inherit game; - game-clippy = craneLib.cargoClippy (commonArgs // { - inherit cargoArtifacts; - cargoClippyExtraArgs = "--all-targets -- --deny warnings"; - }); - game-fmt = craneLib.cargoFmt { - inherit src; - }; - }; - packages.default = game; devShells.default = craneLib.devShell { - checks = self.checks.${system}; packages = [ pkgs.trunk pkgs.rust-analyzer - pkgs.pkg-config - pkgs.openssl.dev - pkgs.SDL2 pkgs.glxinfo pkgs.alsa-lib + pkgs.cmake + pkgs.pkg-config + pkgs.openssl.dev + pkgs.glfw + pkgs.xorg.libX11 + pkgs.xorg.libXcursor + pkgs.xorg.libXi + pkgs.xorg.libXrandr + pkgs.xorg.libXinerama + pkgs.libxkbcommon + pkgs.xorg.libxcb + pkgs.libglvnd ]; + LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${ + pkgs.lib.makeLibraryPath [ + pkgs.xorg.libX11 + pkgs.xorg.libXcursor + pkgs.xorg.libXi + pkgs.libxkbcommon + pkgs.xorg.libxcb + pkgs.libglvnd + ] + }"; }; }); } diff --git a/src/newton.rs b/src/common.rs index 3599211..3599211 100644 --- a/src/newton.rs +++ b/src/common.rs diff --git a/src/newton/client.rs b/src/common/client.rs index 69ac6b3..69ac6b3 100644 --- a/src/newton/client.rs +++ b/src/common/client.rs diff --git a/src/newton/client/assets.rs b/src/common/client/assets.rs index 742f9ea..742f9ea 100644 --- a/src/newton/client/assets.rs +++ b/src/common/client/assets.rs diff --git a/src/newton/client/assets/audio/test.wav b/src/common/client/assets/audio/test.wav Binary files differindex 0eabe85..0eabe85 100644 --- a/src/newton/client/assets/audio/test.wav +++ b/src/common/client/assets/audio/test.wav diff --git a/src/newton/client/assets/meshes/square.obj b/src/common/client/assets/meshes/square.obj index 7328a6c..7328a6c 100644 --- a/src/newton/client/assets/meshes/square.obj +++ b/src/common/client/assets/meshes/square.obj diff --git a/src/newton/client/assets/shaders/flat/frag.glsl b/src/common/client/assets/shaders/flat/frag.glsl index 7006a2b..7006a2b 100644 --- a/src/newton/client/assets/shaders/flat/frag.glsl +++ b/src/common/client/assets/shaders/flat/frag.glsl diff --git a/src/newton/client/assets/shaders/flat/vert.glsl b/src/common/client/assets/shaders/flat/vert.glsl index e324f7e..e324f7e 100644 --- a/src/newton/client/assets/shaders/flat/vert.glsl +++ b/src/common/client/assets/shaders/flat/vert.glsl diff --git a/src/newton/client/assets/textures/test.png b/src/common/client/assets/textures/test.png Binary files differindex 1f1edca..1f1edca 100644 --- a/src/newton/client/assets/textures/test.png +++ b/src/common/client/assets/textures/test.png diff --git a/src/common/overlay.rs b/src/common/overlay.rs new file mode 100644 index 0000000..d7a0d87 --- /dev/null +++ b/src/common/overlay.rs @@ -0,0 +1,125 @@ +#![allow(dead_code, unused_variables)] +mod assets; +mod terminal; +mod fig; + +use teleia::*; + +use std::{collections::HashMap, f32::consts::PI}; +use lexpr::sexp; + +pub struct Overlay { + assets: assets::Assets, + model: scene::Scene, + model_neck_base: glam::Mat4, + model_fb: framebuffer::Framebuffer, + terminal: terminal::Terminal, + fig: fig::Client, + tracking_eyes: (f32, f32), + tracking_neck: glam::Quat, +} + +impl Overlay { + pub async fn new(ctx: &context::Context) -> Self { + let model = scene::Scene::from_gltf(ctx, include_bytes!("overlay/assets/scenes/lcolonq.vrm")); + let model_neck_base = model.nodes_by_name.get("J_Bip_C_Neck") + .and_then(|i| model.nodes.get(*i)) + .expect("failed to find neck joint") + .transform; + Self { + assets: assets::Assets::new(ctx), + model, + model_neck_base, + model_fb: framebuffer::Framebuffer::new( + ctx, + &glam::Vec2::new(terminal::WIDTH as _, terminal::HEIGHT as _), + &glam::Vec2::ZERO + ), + terminal: terminal::Terminal::new(ctx), + fig: fig::Client::new("shiro:32050", &[ + sexp!((avatar toggle)), + sexp!((avatar text)), + sexp!((avatar frame)), + sexp!((avatar reset)), + sexp!((avatar tracking)), + ]), + tracking_eyes: (1.0, 1.0), + tracking_neck: glam::Quat::IDENTITY, + } + } + pub fn handle_tracking(&mut self, msg: fig::Message) -> Option<()> { + let eyes = msg.data.get(0)?; + let eye_left = eyes.get(0)?.as_str()?.parse::<f32>().ok()?; + let eye_right = eyes.get(1)?.as_str()?.parse::<f32>().ok()?; + let euler = msg.data.get(1)?; + let euler_x = euler.get(0)?.as_str()?.parse::<f32>().ok()?.to_radians(); + let euler_y = PI - euler.get(1)?.as_str()?.parse::<f32>().ok()?.to_radians(); + let euler_z = euler.get(2)?.as_str()?.parse::<f32>().ok()?.to_radians() + PI/2.0; + self.tracking_eyes = (eye_left, eye_right); + self.tracking_neck = glam::Quat::from_euler(glam::EulerRot::XYZ, euler_x, euler_y, euler_z); + Some(()) + } + pub fn handle_text(&mut self, msg: fig::Message) -> Option<()> { + let s = msg.data.get(0)?.as_str()?; + self.terminal.fill_string(s); + Some(()) + } +} + +impl teleia::state::Game for Overlay { + fn initialize_audio(&self, ctx: &context::Context, st: &state::State, actx: &audio::Context) -> HashMap<String, audio::Audio> { + HashMap::new() + } + fn finish_title(&mut self, _st: &mut state::State) {} + fn mouse_press(&mut self, _ctx: &context::Context, _st: &mut state::State) {} + fn mouse_move(&mut self, _ctx: &context::Context, _st: &mut state::State, _x: i32, _y: i32) {} + fn update(&mut self, ctx: &context::Context, st: &mut state::State) -> Option<()> { + st.projection = glam::Mat4::perspective_lh( + PI / 4.0, + terminal::WIDTH as f32 / terminal::HEIGHT as f32, + 0.1, 10.0 + ); + st.move_camera( + ctx, + &glam::Vec3::new(0.0, 0.0, 1.0), + &glam::Vec3::new(0.0, 0.0, -1.0), + &glam::Vec3::new(0.0, 1.0, 0.0), + ); + while let Some(msg) = self.fig.pump() { + let malformed = format!("malformed {} data: {}", msg.event, msg.data); + if msg.event == sexp!((avatar tracking)) { + if self.handle_tracking(msg).is_none() { log::warn!("{}", malformed) } + } else if msg.event == sexp!((avatar text)) { + if self.handle_text(msg).is_none() { log::warn!("{}", malformed) } + } else { + log::info!("received unhandled event {} with data: {}", msg.event, msg.data); + } + } + 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); + } + Some(()) + } + fn render(&mut self, ctx: &context::Context, st: &mut state::State) -> Option<()> { + self.model_fb.bind(ctx); + ctx.clear_color(glam::Vec4::new(0.0, 0.0, 0.0, 1.0)); + ctx.clear(); + st.bind_3d(ctx, &self.assets.shader_scene); + self.assets.shader_scene.set_position_3d( + ctx, + &glam::Mat4::from_translation( + glam::Vec3::new(0.0, -1.6, 0.5), + ), + ); + self.model.render(ctx, &self.assets.shader_scene); + st.render_framebuffer.bind(ctx); + self.terminal.update(ctx, &self.model_fb); + self.terminal.render(ctx, &glam::Vec2::new(400.0, 200.0)); + // self.model_fb.blit( + // ctx, &st.render_framebuffer, + // &glam::Vec2::new(ctx.render_width / 2.0 - 512.0, ctx.render_height / 2.0 - 512.0), + // &glam::Vec2::new(128.0, 128.0) + // ); + Some(()) + } +} diff --git a/src/newton/overlay/assets.rs b/src/common/overlay/assets.rs index 9a0cefc..9a0cefc 100644 --- a/src/newton/overlay/assets.rs +++ b/src/common/overlay/assets.rs diff --git a/src/newton/overlay/assets/audio/test.wav b/src/common/overlay/assets/audio/test.wav Binary files differindex 0eabe85..0eabe85 100644 --- a/src/newton/overlay/assets/audio/test.wav +++ b/src/common/overlay/assets/audio/test.wav diff --git a/src/newton/overlay/assets/fonts/iosevka-comfy-regular.ttf b/src/common/overlay/assets/fonts/iosevka-comfy-regular.ttf Binary files differindex b474adc..b474adc 100644 --- a/src/newton/overlay/assets/fonts/iosevka-comfy-regular.ttf +++ b/src/common/overlay/assets/fonts/iosevka-comfy-regular.ttf diff --git a/src/newton/overlay/assets/fonts/terminus.png b/src/common/overlay/assets/fonts/terminus.png Binary files differindex 287810b..287810b 100644 --- a/src/newton/overlay/assets/fonts/terminus.png +++ b/src/common/overlay/assets/fonts/terminus.png diff --git a/src/newton/overlay/assets/fonts/terminus.ttf b/src/common/overlay/assets/fonts/terminus.ttf Binary files differindex d125e63..d125e63 100644 --- a/src/newton/overlay/assets/fonts/terminus.ttf +++ b/src/common/overlay/assets/fonts/terminus.ttf diff --git a/src/newton/overlay/assets/meshes/square.obj b/src/common/overlay/assets/meshes/square.obj index 7328a6c..7328a6c 100644 --- a/src/newton/overlay/assets/meshes/square.obj +++ b/src/common/overlay/assets/meshes/square.obj diff --git a/src/newton/overlay/assets/scenes/lcolonq.vrm b/src/common/overlay/assets/scenes/lcolonq.vrm Binary files differindex 49fa4a4..49fa4a4 100644 --- a/src/newton/overlay/assets/scenes/lcolonq.vrm +++ b/src/common/overlay/assets/scenes/lcolonq.vrm diff --git a/src/newton/overlay/assets/shaders/flat/frag.glsl b/src/common/overlay/assets/shaders/flat/frag.glsl index 7006a2b..7006a2b 100644 --- a/src/newton/overlay/assets/shaders/flat/frag.glsl +++ b/src/common/overlay/assets/shaders/flat/frag.glsl diff --git a/src/newton/overlay/assets/shaders/flat/vert.glsl b/src/common/overlay/assets/shaders/flat/vert.glsl index e324f7e..e324f7e 100644 --- a/src/newton/overlay/assets/shaders/flat/vert.glsl +++ b/src/common/overlay/assets/shaders/flat/vert.glsl diff --git a/src/newton/overlay/assets/shaders/scene/frag.glsl b/src/common/overlay/assets/shaders/scene/frag.glsl index 81e08b9..81e08b9 100644 --- a/src/newton/overlay/assets/shaders/scene/frag.glsl +++ b/src/common/overlay/assets/shaders/scene/frag.glsl diff --git a/src/newton/overlay/assets/shaders/scene/vert.glsl b/src/common/overlay/assets/shaders/scene/vert.glsl index 64f400c..64f400c 100644 --- a/src/newton/overlay/assets/shaders/scene/vert.glsl +++ b/src/common/overlay/assets/shaders/scene/vert.glsl diff --git a/src/newton/overlay/assets/textures/test.png b/src/common/overlay/assets/textures/test.png Binary files differindex 1f1edca..1f1edca 100644 --- a/src/newton/overlay/assets/textures/test.png +++ b/src/common/overlay/assets/textures/test.png diff --git a/src/common/overlay/fig.rs b/src/common/overlay/fig.rs new file mode 100644 index 0000000..b60f8e9 --- /dev/null +++ b/src/common/overlay/fig.rs @@ -0,0 +1,40 @@ +use std::io::{BufRead, Write}; + +#[derive(Debug, Clone)] +pub struct Message { + pub event: lexpr::Value, + pub data: lexpr::Value, +} + +pub struct Client { + reader: std::io::BufReader<std::net::TcpStream>, +} +impl Client { + pub fn new(addr: &str, subs: &[lexpr::Value]) -> Self { + let mut socket = std::net::TcpStream::connect(addr).expect("failed to connect to message bus"); + socket.set_nonblocking(true).expect("failed to set message bus socket nonblocking"); + for s in subs { + write!(socket, "(sub {})\n", s).expect("failed to send subscribe message to bus"); + } + let reader = std::io::BufReader::new(socket); + Self { reader, } + } + pub fn pump(&mut self) -> Option<Message> { + let mut buf = String::new(); + match self.reader.read_line(&mut buf) { + Ok(l) => match lexpr::from_str(&buf) { + Ok(v) => { + match v.as_cons() { + Some(cs) => { + Some(Message { event: cs.car().clone(), data: cs.cdr().clone() }) + }, + _ => { log::error!("malformed message bus input s-expression: {}", v); None }, + } + }, + Err(e) => { log::error!("malformed message bus input line: {}", e); None }, + }, + Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => None, + Err(e) => panic!("IO error on message bus: {}", e), + } + } +} diff --git a/src/newton/overlay/terminal.rs b/src/common/overlay/terminal.rs index 3371789..a2382b1 100644 --- a/src/newton/overlay/terminal.rs +++ b/src/common/overlay/terminal.rs @@ -15,6 +15,20 @@ impl std::ops::Add for Pos { fn add(self, rhs: Self) -> Self { Self {x: self.x + rhs.x, y: self.y + rhs.y } } } +#[derive(Debug, Clone)] +pub struct CharPair { + pub first: char, + pub second: Option<char>, +} +impl Default for CharPair { + fn default() -> Self { + Self { + first: 'a', + second: Some('b'), + } + } +} + pub struct Layer<T> { pub data: [T; WIDTH * HEIGHT], } @@ -26,9 +40,28 @@ impl<T> Layer<T> { } pub fn get(&self, p: Pos) -> Option<&T> { if p.x < 0 || p.x >= WIDTH as _ || p.y < 0 || p.y >= HEIGHT as _ { return None } - let idx = p.x as usize + p.y as usize * WIDTH; + let idx = p.x as usize + p.y as usize * WIDTH; Some(&self.data[idx]) } + pub fn set(&mut self, p: Pos, x: T) { + if p.x < 0 || p.x >= WIDTH as _ || p.y < 0 || p.y >= HEIGHT as _ { return } + let idx = p.x as usize + p.y as usize * WIDTH; + self.data[idx] = x; + } +} +impl Layer<CharPair> { + pub fn from_str(&mut self, s: &str) { + let chars: Vec<char> = s.chars().collect(); + if chars.is_empty() { return } + let mut i: usize = 0; + for row in 0..64 { + for col in 0..64 { + let first = chars[i]; i += 1; i %= chars.len(); + let second = Some(chars[i]); i += 1; i %= chars.len(); + self.set(Pos::new(col, row), CharPair { first, second }); + } + } + } } impl Layer<glam::Vec3> { pub fn from_framebuffer(&mut self, ctx: &context::Context, fb: &framebuffer::Framebuffer) { @@ -36,20 +69,6 @@ impl Layer<glam::Vec3> { } } -#[derive(Debug, Clone)] -pub struct CharPair { - pub first: char, - pub second: Option<char>, -} -impl Default for CharPair { - fn default() -> Self { - Self { - first: 'a', - second: Some('b'), - } - } -} - pub struct Terminal { pub font: font::Bitmap, pub base_color: Layer<glam::Vec3>, @@ -58,11 +77,13 @@ pub struct Terminal { } impl Terminal { pub fn new(ctx: &context::Context) -> Self { + let mut set_char = Layer::new(); + set_char.from_str("lcolonq"); Self { font: font::Bitmap::from_image(ctx, 6, 12, 96, 72, include_bytes!("assets/fonts/terminus.png")), base_color: Layer::new(), set_color: Layer::new(), - set_char: Layer::new(), + set_char, } } pub fn get_color(&self, pos: Pos) -> glam::Vec3 { @@ -75,6 +96,9 @@ impl Terminal { pub fn update(&mut self, ctx: &context::Context, fb: &framebuffer::Framebuffer) { self.base_color.from_framebuffer(ctx, fb); } + pub fn fill_string(&mut self, s: &str) { + self.set_char.from_str(s); + } pub fn render(&self, ctx: &context::Context, pos: &glam::Vec2) { let mut s = String::new(); let mut colors = Vec::new(); diff --git a/src/newton/server.rs b/src/common/server.rs index e69de29..e69de29 100644 --- a/src/newton/server.rs +++ b/src/common/server.rs @@ -1,4 +1,4 @@ -mod newton; +mod common; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; @@ -6,5 +6,5 @@ use wasm_bindgen::prelude::*; #[cfg(target_arch = "wasm32")] #[wasm_bindgen] pub async fn main_js() { - teleia::run(240, 160, newton::client::Game::new).await; + teleia::run(240, 160, common::client::Game::new).await; } diff --git a/src/main.rs b/src/main.rs index 92a527b..8306cae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -mod newton; +mod common; #[cfg(not(target_arch = "wasm32"))] use clap::{command, Command}; @@ -24,7 +24,7 @@ pub async fn main() { .get_matches(); match matches.subcommand() { Some(("overlay", _cm)) => { - teleia::run("LCOLONQ", 1920, 1080, newton::overlay::Overlay::new).await; + teleia::run("LCOLONQ", 1920, 1080, true, common::overlay::Overlay::new).await; }, Some(("server", _cm)) => { env_logger::Builder::new().filter(None, log::LevelFilter::Info).init(); diff --git a/src/newton/overlay.rs b/src/newton/overlay.rs deleted file mode 100644 index 33b96cb..0000000 --- a/src/newton/overlay.rs +++ /dev/null @@ -1,76 +0,0 @@ -#![allow(dead_code, unused_variables)] -mod assets; -mod terminal; - -use std::collections::HashMap; -use teleia::*; - -pub struct Overlay { - assets: assets::Assets, - model: scene::Scene, - model_fb: framebuffer::Framebuffer, - terminal: terminal::Terminal, -} - -impl Overlay { - pub async fn new(ctx: &context::Context) -> Self { - Self { - assets: assets::Assets::new(ctx), - model: scene::Scene::from_gltf(ctx, include_bytes!("overlay/assets/scenes/lcolonq.vrm")), - model_fb: framebuffer::Framebuffer::new( - ctx, - &glam::Vec2::new(terminal::WIDTH as _, terminal::HEIGHT as _), - &glam::Vec2::ZERO - ), - terminal: terminal::Terminal::new(ctx), - } - } -} - -impl teleia::state::Game for Overlay { - fn initialize_audio(&self, ctx: &context::Context, st: &state::State, actx: &audio::Context) -> HashMap<String, audio::Audio> { - HashMap::new() - } - fn finish_title(&mut self, _st: &mut state::State) {} - fn mouse_press(&mut self, _ctx: &context::Context, _st: &mut state::State) {} - fn mouse_move(&mut self, _ctx: &context::Context, _st: &mut state::State, _x: i32, _y: i32) {} - fn update(&mut self, ctx: &context::Context, st: &mut state::State) -> Option<()> { - st.projection = glam::Mat4::perspective_lh( - std::f32::consts::PI / 4.0, - terminal::WIDTH as f32 / terminal::HEIGHT as f32, - 0.1, 10.0 - ); - st.move_camera( - ctx, - &glam::Vec3::new(0.0, 0.0, 1.0), - &glam::Vec3::new(0.0, 0.0, -1.0), - &glam::Vec3::new(0.0, 1.0, 0.0), - ); - // 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 *= glam::Mat4::from_rotation_y(0.05); - // } - Some(()) - } - fn render(&mut self, ctx: &context::Context, st: &mut state::State) -> Option<()> { - self.model_fb.bind(ctx); - ctx.clear_color(glam::Vec4::new(0.0, 0.0, 0.0, 1.0)); - ctx.clear(); - st.bind_3d(ctx, &self.assets.shader_scene); - self.assets.shader_scene.set_position_3d( - ctx, - &glam::Mat4::from_translation( - glam::Vec3::new(0.0, -1.6, 0.5), - ), - ); - self.model.render(ctx, &self.assets.shader_scene); - st.render_framebuffer.bind(ctx); - // self.model_fb.blit( - // ctx, &st.render_framebuffer, - // &glam::Vec2::new(ctx.render_width / 2.0 - 512.0, ctx.render_height / 2.0 - 512.0), - // &glam::Vec2::new(1024.0, 1024.0) - // ); - self.terminal.update(ctx, &self.model_fb); - self.terminal.render(ctx, &glam::Vec2::new(400.0, 200.0)); - Some(()) - } -} |
