rust_console_game_engine/
sprite.rs1use 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}