rioterm 0.3.11

Rio terminal is a hardware-accelerated GPU terminal emulator, focusing to run in desktops and browsers.
use rio_backend::sugarloaf::Sugarloaf;

const PX: f32 = 1.0;
const DEPTH: f32 = 0.0;
const ORDER: u8 = 25;

const BLACK: [f32; 4] = [0.05, 0.05, 0.07, 1.0];
const DARK: [f32; 4] = [0.22, 0.22, 0.25, 1.0];
const MID: [f32; 4] = [0.50, 0.50, 0.53, 1.0];
const GRAY: [f32; 4] = [0.72, 0.72, 0.74, 1.0];
const WHITE: [f32; 4] = [0.95, 0.95, 0.95, 1.0];

/// Note: pre-computed RLE spans from the 21x25 Finalhand sprite.
/// each entry is basically (row, col, length, color_index)
/// the colors definition: 1=black, 2=white, 3=gray, 4=mid, 5=dark
#[rustfmt::skip]
const SPANS: [(u8, u8, u8, u8); 176] = [
    (0,3,2,1),
    (1,1,6,1),
    (2,1,2,1),(2,3,3,3),(2,6,2,1),
    (3,0,1,1),(3,1,1,5),(3,2,1,4),(3,3,1,3),(3,4,2,2),(3,6,1,3),(3,7,1,5),(3,8,1,1),
    (4,0,1,1),(4,1,1,5),(4,2,1,4),(4,3,1,3),(4,4,3,2),(4,7,1,3),(4,8,1,5),(4,9,1,1),
    (5,0,2,1),(5,2,2,4),(5,4,1,3),(5,5,3,2),(5,8,1,3),(5,9,1,5),(5,10,1,1),(5,12,3,1),
    (6,1,1,1),(6,2,1,5),(6,3,2,4),(6,5,1,3),(6,6,3,2),(6,9,1,3),(6,10,1,5),(6,11,1,1),(6,12,3,5),(6,15,1,1),
    (7,2,1,1),(7,3,3,4),(7,6,1,3),(7,7,3,2),(7,10,1,3),(7,11,2,5),(7,13,2,3),(7,15,1,5),(7,16,1,1),
    (8,3,1,1),(8,4,1,5),(8,5,2,4),(8,7,1,3),(8,8,3,2),(8,11,1,3),(8,12,1,4),(8,13,1,3),(8,14,1,2),(8,15,1,3),(8,16,1,5),(8,17,1,1),
    (9,2,1,5),(9,3,2,1),(9,5,1,5),(9,6,1,4),(9,7,1,3),(9,8,4,2),(9,12,1,3),(9,13,1,4),(9,14,2,2),(9,16,1,3),(9,17,1,5),(9,18,1,1),
    (10,1,1,5),(10,2,1,1),(10,3,5,3),(10,8,5,2),(10,13,1,3),(10,14,2,2),(10,16,1,3),(10,17,1,5),(10,18,1,1),
    (11,1,2,1),(11,3,1,3),(11,4,12,2),(11,16,1,3),(11,17,1,5),(11,18,1,1),
    (12,1,2,1),(12,3,1,3),(12,4,12,2),(12,16,1,3),(12,17,1,5),(12,18,1,1),
    (13,1,1,1),(13,2,1,4),(13,3,1,3),(13,4,12,2),(13,16,1,3),(13,17,2,1),
    (14,0,2,1),(14,2,1,4),(14,3,2,3),(14,5,11,2),(14,16,1,3),(14,17,2,5),(14,19,1,1),
    (15,0,2,1),(15,2,1,4),(15,3,2,3),(15,5,10,2),(15,15,4,3),(15,19,1,1),(15,20,1,5),
    (16,0,1,1),(16,1,1,5),(16,2,3,3),(16,5,9,2),(16,14,1,3),(16,15,2,2),(16,17,2,3),(16,19,1,1),
    (17,0,1,1),(17,1,1,5),(17,2,2,4),(17,4,2,3),(17,6,7,2),(17,13,2,3),(17,15,2,2),(17,17,1,3),(17,18,1,1),(17,19,1,5),
    (18,0,2,1),(18,2,3,4),(18,5,2,3),(18,7,5,2),(18,12,2,3),(18,14,2,2),(18,16,1,3),(18,17,1,1),(18,18,1,5),
    (19,1,1,1),(19,2,1,5),(19,3,3,4),(19,6,7,3),(19,13,2,2),(19,15,1,3),(19,16,1,1),(19,17,1,5),
    (20,2,1,1),(20,3,1,5),(20,4,8,4),(20,12,3,3),(20,15,1,1),(20,16,1,5),
    (21,3,1,1),(21,4,1,5),(21,5,4,4),(21,9,1,5),(21,10,1,4),(21,11,3,3),(21,14,1,1),(21,15,1,5),
    (22,4,5,1),(22,9,1,5),(22,10,3,4),(22,13,1,1),(22,14,1,5),
    (23,5,4,1),(23,9,1,5),(23,10,2,4),(23,12,1,1),(23,13,1,5),
    (24,8,2,1),(24,10,1,5),(24,11,1,1),(24,12,1,5),
];

#[inline]
fn span_color(value: u8) -> [f32; 4] {
    match value {
        2 => WHITE,
        3 => GRAY,
        4 => MID,
        5 => DARK,
        _ => BLACK,
    }
}

pub fn draw(sugarloaf: &mut Sugarloaf, mouse_x: f32, mouse_y: f32, scale: f32) {
    let px = PX;
    let base_x = mouse_x / scale;
    let base_y = mouse_y / scale;

    for &(row, col, len, color) in &SPANS {
        let x = base_x + col as f32 * px;
        let y = base_y + row as f32 * px;
        sugarloaf.rect(
            None,
            x,
            y,
            len as f32 * px,
            px,
            span_color(color),
            DEPTH,
            ORDER,
        );
    }
}