rust_console_game_engine/
sprite.rs

1use super::RustConsole;
2
3use std::{convert::TryInto, io::Error, mem::size_of};
4use std::io::Read;
5use std::fs::File;
6
7pub struct RustConsoleSprite {
8    width: usize,
9    height: usize,
10    glyphs: Vec<char>,
11    colors: Vec<u16>
12}
13
14impl RustConsoleSprite {
15    pub fn new(w: usize, h: usize) -> Result<RustConsoleSprite, Error> {
16        Ok(RustConsoleSprite {
17            width: w,
18            height: h,
19            glyphs: vec![' '; w * h],
20            colors: vec![RustConsole::FG_BLACK; w * h]
21        })
22    }
23
24    pub fn from_path(path: &str) -> Result<RustConsoleSprite, Error> {
25        let mut f = File::open(path)?;
26        let mut buffer = [0; size_of::<u32>()];
27        f.read_exact(&mut buffer)?;
28        let w = u32::from_le_bytes(buffer) as usize;
29        f.read_exact(&mut buffer)?;
30        let h = u32::from_le_bytes(buffer) as usize;
31        let mut colors = vec![0; size_of::<u16>() * w * h];
32        f.read_exact(&mut colors)?;
33        let mut glyphs = vec![0; size_of::<u16>() * w * h];
34        f.read_exact(&mut glyphs)?;
35        Ok(RustConsoleSprite {
36            width: w,
37            height: h,
38            glyphs: glyphs.chunks_exact(2).map(|c| char::from_u32(u16::from_le_bytes(c[..2].try_into().unwrap()) as u32).unwrap()).collect(),
39            colors: colors.chunks_exact(2).map(|c| u16::from_le_bytes(c[..2].try_into().unwrap())).collect()
40        })
41    }
42
43    pub fn width(&self) -> usize { self.width }
44    
45    pub fn height(&self) -> usize { self.height }
46
47    pub fn set_glyph(&mut self, x: usize, y: usize, c: char) {
48        if !(x >= self.width || y >= self.height) {
49            self.glyphs[y * self.width + x] = c;
50        }
51    }
52
53    pub fn set_color(&mut self, x: usize, y: usize, col: u16) {
54        if !(x >= self.width || y >= self.height) {
55            self.colors[y * self.width + x] = col;
56        }
57    }
58
59    pub fn get_glyph(&self, x: usize, y: usize) -> char {
60        if !(x >= self.width || y >= self.height) {
61            return self.glyphs[y * self.width + x];
62        } else {
63            return ' ';
64        }
65    }
66
67    pub fn get_color(&self, x: usize, y: usize) -> u16 {
68        if !(x >= self.width || y >= self.height) {
69            return self.colors[y * self.width + x];
70        } else {
71            return RustConsole::FG_BLACK;
72        }
73    }
74
75    pub fn sample_glyph(&self, x: f32, y: f32) -> char {
76        let sx = (x * self.width as f32) as isize;
77        let sy = (y * self.height as f32 - 1f32) as isize;
78        if !(sx < 0  || sx >= self.width as isize || sy < 0 || sy >= self.height as isize) {
79            return self.glyphs[sy as usize * self.width + sx as usize];
80        } else {
81            return ' ';
82        }
83    }
84
85    pub fn sample_color(&self, x: f32, y: f32) -> u16 {
86        let sx = (x * self.width as f32) as isize;
87        let sy = (y * self.height as f32 - 1f32) as isize;
88        if !(sx < 0  || sx >= self.width as isize || sy < 0 || sy >= self.height as isize) {
89            return self.colors[sy as usize * self.width + sx as usize];
90        } else {
91            return RustConsole::FG_BLACK;
92        }
93    }
94}