blockish_caca/
lib.rs

1extern crate blockish;
2extern crate crossterm;
3extern crate redhook;
4use blockish::ThreadedEngine;
5use gag::Gag;
6use std::env;
7use std::slice;
8
9#[repr(C)]
10#[derive(Debug, Copy, Clone)]
11pub struct caca_display {
12    _unused: [u8; 0],
13}
14#[doc = " \\e libcaca display context"]
15pub type CacaDisplayT = caca_display;
16#[repr(C)]
17#[derive(Debug, Copy, Clone)]
18pub struct caca_canvas {
19    _unused: [u8; 0],
20}
21#[doc = " \\e libcaca canvas"]
22pub type CacaCanvasT = caca_canvas;
23#[repr(C)]
24#[derive(Debug, Copy, Clone)]
25pub struct caca_dither {
26    _unused: [u8; 0],
27}
28#[doc = " dither structure"]
29pub type CacaDitherT = caca_dither;
30
31static mut WIDTH: i32 = 0;
32static mut HEIGHT: i32 = 0;
33static mut BYTES_PER_PIXEL: u32 = 0;
34static mut TERMINAL_WIDTH: i32 = 0;
35static mut TERMINAL_HEIGHT: i32 = 0;
36static mut TERMINAL_SIZE_CHANGED: bool = false;
37
38static mut ENGINE: Option<blockish::ThreadedEngine> = None;
39
40redhook::hook! {
41    unsafe fn caca_dither_bitmap(
42        _arg1: *mut CacaCanvasT,
43        _arg2: ::std::os::raw::c_int,
44        _arg3: ::std::os::raw::c_int,
45        _width: ::std::os::raw::c_int,
46        _height: ::std::os::raw::c_int,
47        _arg6: *const CacaDitherT,
48        data: *const ::std::os::raw::c_uchar
49    ) -> ::std::os::raw::c_int => my_caca_dither_bitmap {
50        let mut bwidth = 80;
51        let mut bheight = 20;
52        if let Ok(columns_string) = env::var("COLUNMS") {
53            if let Ok(columns) = columns_string.parse() {
54                bwidth = columns;
55                if TERMINAL_WIDTH != columns {
56                    TERMINAL_WIDTH = columns;
57                    TERMINAL_SIZE_CHANGED = true;
58                }
59            }
60        }
61        if let Ok(lines_string) = env::var("LINES") {
62            if let Ok(lines) = lines_string.parse() {
63                bheight = lines;
64                if TERMINAL_HEIGHT != lines {
65                    TERMINAL_HEIGHT = lines;
66                    TERMINAL_SIZE_CHANGED = true;
67                }
68            }
69        }
70        match crossterm::terminal::size() {
71            Ok(res) => {
72                bwidth = res.0 as i32;
73                bheight = res.1 as i32;
74                if bwidth != TERMINAL_WIDTH || bheight != TERMINAL_HEIGHT {
75                    TERMINAL_SIZE_CHANGED = true;
76                }
77                TERMINAL_WIDTH = bwidth;
78                TERMINAL_HEIGHT = bheight;
79            }
80            Err(_) => {
81            }
82        }
83        let width = bwidth as u32 * 8;
84        let height = bheight as u32 * 16 - 1;
85        if TERMINAL_SIZE_CHANGED {
86            ENGINE = Some(ThreadedEngine::new(width as u32, height as u32, true));
87        }
88        let original_width : u32 = WIDTH as u32;
89        let original_height : u32 = HEIGHT as u32;
90        print!("\x1b[{};0f", 1);
91        let raw_slice = slice::from_raw_parts(data, (original_width * original_height * BYTES_PER_PIXEL) as usize);
92        match &mut ENGINE {
93            Some(engine) => {
94                engine.render(&|x, y| {
95                    let start = (( ((y * original_height / height) * original_width as u32 + (x * original_width / width) ) * BYTES_PER_PIXEL)) as usize;
96                    let b = (raw_slice[start]) as u8;
97                    let g = (raw_slice[start + 1]) as u8;
98                    let r = (raw_slice[start + 2]) as u8;
99                    (r, g, b, 0)
100                });
101            }
102            None => {}
103        };
104        0
105    }
106}
107
108redhook::hook! {
109unsafe fn caca_refresh_display(arg1: *mut CacaDisplayT) -> ::std::os::raw::c_int => my_caca_refresh_display {
110    {
111        let _print_gag = Gag::stdout().unwrap();
112        redhook::real!(caca_refresh_display)(arg1)
113    }
114    }
115}
116
117redhook::hook! {
118    unsafe fn caca_create_dither(
119        _arg1: ::std::os::raw::c_int,
120        _arg2: ::std::os::raw::c_int,
121        _arg3: ::std::os::raw::c_int,
122        _arg4: ::std::os::raw::c_int,
123        _arg5: u32,
124        _arg6: u32,
125        _arg7: u32,
126        _arg8: u32
127    ) -> *mut CacaDitherT => my_caca_create_dither {
128        let res = redhook::real!(caca_create_dither)(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8);
129        WIDTH=_arg2;
130        HEIGHT=_arg3;
131        BYTES_PER_PIXEL=_arg1 as u32 / 8;
132        res
133    }
134}