Something went wrong. Try again.
HEXWORK - A Lantern in the Deep: 3D ASCII terminal roguelike RPG in Rust.
Entirely designed and built by Muse Spark 1.3 to evaluate if I like the model.
Something went wrong. Try again.
2.5 kB · 51 lines
Rust
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152//! Encoding-only adapter and display cache for shared composed cells.use std::fmt::Write;use hexwork_game::composed_frame::{Cell, CellSink, ComposedFrame};use hexwork_render::ansi::{ColorMode, quantize_256};#[derive(Default)]pub struct TerminalCache { previous: Option<(ComposedFrame, ColorMode)> }impl TerminalCache { /// Every physical erase invalidates the display, even without a size change. pub fn physical_clear(&mut self) -> &'static str { self.previous = None; "\x1b[0m\x1b[2J\x1b[H" } pub fn encode(&mut self, frame: ComposedFrame, mode: ColorMode) -> String { let previous = self.previous.as_ref().filter(|(_, old_mode)| *old_mode == mode).map(|(frame, _)| frame); let output = encode(&frame, previous, mode); self.previous = Some((frame, mode)); output }}fn encode(frame: &ComposedFrame, previous: Option<&ComposedFrame>, mode: ColorMode) -> String { let previous = previous.filter(|p| p.width() == frame.width() && p.height() == frame.height()); struct Terminal<'a>(String, ColorMode, Option<&'a ComposedFrame>); impl CellSink for Terminal<'_> { fn begin(&mut self, _: usize, _: usize) { self.0.push_str("\x1b[0m"); } fn cell(&mut self, x: usize, y: usize, cell: &Cell) { if cell.continuation() { return; } if self.2.is_some_and(|p| p.cells()[y * p.width() + x] == *cell) { return; } let _ = write!(self.0, "\x1b[{};{}H\x1b[0m", y + 1, x + 1); let style = cell.style(); let no_color_bold = self.1 == ColorMode::NoColor && style.foreground.is_some_and(|rgb| rgb.into_iter().max().unwrap_or(0) >= 128); if style.bold || no_color_bold { self.0.push_str("\x1b[1m"); } for (prefix, color) in [(38, style.foreground), (48, style.background)] { if let Some([r,g,b]) = color { match self.1 { ColorMode::TrueColor => { let _ = write!(self.0, "\x1b[{prefix};2;{r};{g};{b}m"); } ColorMode::Ansi256 => { let _ = write!(self.0, "\x1b[{prefix};5;{}m", quantize_256([r,g,b])); } ColorMode::NoColor => {} } } } self.0.push_str(cell.text()); } fn end(&mut self) { self.0.push_str("\x1b[0m"); } } let mut sink = Terminal(String::new(), mode, previous); frame.present(&mut sink); sink.0}#[cfg(test)]#[path = "composed_terminal_tests.rs"]mod tests;