From c4f96d2b3f3b3878d6e0bbca7e0c4cd3f5d8bc85 Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Fri, 31 Jan 2025 13:50:14 -0500 Subject: Terminal (it doesn't do the colors right for some reason) --- src/common/overlay.rs | 26 ++++++++++++++++++++++++-- src/common/overlay/terminal.rs | 31 +++++++++++++++++++++++++++++++ src/main.rs | 11 +++++++++-- 3 files changed, 64 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/common/overlay.rs b/src/common/overlay.rs index 6e68974..492f1bd 100644 --- a/src/common/overlay.rs +++ b/src/common/overlay.rs @@ -4,12 +4,19 @@ mod terminal; mod fig; use teleia::*; +use termion::raw::IntoRawMode; use std::{collections::HashMap, f32::consts::PI}; use lexpr::sexp; use base64::prelude::*; +pub enum RenderMode { + Overlay, + Terminal(termion::raw::RawTerminal), +} + pub struct Overlay { + mode: RenderMode, assets: assets::Assets, model: scene::Scene, model_neck_base: glam::Mat4, @@ -22,13 +29,14 @@ pub struct Overlay { } impl Overlay { - pub async fn new(ctx: &context::Context) -> Self { + pub async fn new(ctx: &context::Context, mode: RenderMode) -> 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 { + mode, assets: assets::Assets::new(ctx), model, model_neck_base, @@ -50,6 +58,13 @@ impl Overlay { tracking_neck: glam::Quat::IDENTITY, } } + pub async fn overlay(ctx: &context::Context) -> Self { + Self::new(ctx, RenderMode::Overlay).await + } + pub async fn terminal(ctx: &context::Context) -> Self { + let raw_stdout = std::io::stdout().into_raw_mode().expect("failed to set raw mode"); + Self::new(ctx, RenderMode::Terminal(raw_stdout)).await + } 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::().ok()?; @@ -135,7 +150,14 @@ impl teleia::state::Game for Overlay { 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(12.0, 250.0)); + match &mut self.mode { + RenderMode::Overlay => { + self.terminal.render(ctx, &glam::Vec2::new(12.0, 250.0)); + }, + RenderMode::Terminal(stdout) => if st.tick % 10 == 0 { + self.terminal.write_tty(stdout); + }, + } // 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), diff --git a/src/common/overlay/terminal.rs b/src/common/overlay/terminal.rs index 1b8df4c..e631899 100644 --- a/src/common/overlay/terminal.rs +++ b/src/common/overlay/terminal.rs @@ -1,3 +1,6 @@ +use std::io::Write; +use colored::Colorize; + use teleia::*; pub const WIDTH: usize = 64; @@ -164,4 +167,32 @@ impl Terminal { } self.font.render_text_helper(ctx, pos, &s, &colors); } + pub fn write_tty(&self, out: &mut W) + where W: Write { + let mut output: Vec = Vec::new(); + write!(output, "\x1b[2J\x1b[1;1H").expect("failed to write output"); + for row in 0..64 { + for col in 0..64 { + let pos = Pos::new(col, row); + let c = self.get_color(pos); + let new = if let Some(p) = self.set_char.get(pos) { + if c == glam::Vec3::new(0.0, 0.0, 0.0) { + String::from(" ") + } else if let Some(pat) = self.outline_pattern(pos) { + pat + } else { + format!("{}{}", p.first, if let Some(snd) = p.second { snd } else { ' ' }) + } + } else { + String::from(" ") + }; + write!( + output, "{}", + new.truecolor((c.x * 255.0) as u8, (c.y * 255.0) as u8, (c.z * 255.0) as u8) + ).unwrap(); + } + write!(output, "\r\n").unwrap(); + } + out.write(&output).expect("failed to write to terminal"); + } } diff --git a/src/main.rs b/src/main.rs index 8306cae..af8e753 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,11 @@ pub async fn main() { .arg_required_else_help(true) .subcommand( Command::new("overlay") - .about("Run the LCOLONQ model renderer / overlay") + .about("Run the LCOLONQ model renderer in a full-screen transparent overlay") + ) + .subcommand( + Command::new("terminal") + .about("Run the LCOLONQ model renderer in a terminal") ) .subcommand( Command::new("server") @@ -24,7 +28,10 @@ pub async fn main() { .get_matches(); match matches.subcommand() { Some(("overlay", _cm)) => { - teleia::run("LCOLONQ", 1920, 1080, true, common::overlay::Overlay::new).await; + teleia::run("LCOLONQ", 1920, 1080, teleia::Options::OVERLAY, common::overlay::Overlay::overlay).await; + }, + Some(("terminal", _cm)) => { + teleia::run("LCOLONQ", 1920, 1080, teleia::Options::HIDDEN, common::overlay::Overlay::terminal).await; }, Some(("server", _cm)) => { env_logger::Builder::new().filter(None, log::LevelFilter::Info).init(); -- cgit v1.2.3