finished phase 2a
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
use crate::palette::index_to_rgb;
|
||||
|
||||
pub trait Renderer {
|
||||
fn present(&mut self, framebuffer: &[u8], width: u16, height: u16);
|
||||
}
|
||||
|
||||
pub struct PpmRenderer {
|
||||
dir: String,
|
||||
frame: u32,
|
||||
}
|
||||
|
||||
|
||||
impl PpmRenderer {
|
||||
pub fn new(dir: &str) -> Self {
|
||||
Self { dir: dir.to_string(), frame: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Renderer for PpmRenderer {
|
||||
fn present(&mut self, framebuffer: &[u8], width: u16, height: u16) {
|
||||
std::fs::create_dir_all(&self.dir).expect("failed to create render dir");
|
||||
let path = format!("{}/frame_{:04}.ppm", self.dir, self.frame);
|
||||
std::fs::write(&path, ppm_bytes(framebuffer, width, height))
|
||||
.expect("failed to write PPM file");
|
||||
self.frame += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ppm_bytes(framebuffer: &[u8], width: u16, height: u16) -> Vec<u8> {
|
||||
let mut out = format!("P6\n{width} {height}\n255\n").into_bytes();
|
||||
for &idx in framebuffer {
|
||||
let (r, g, b) = index_to_rgb(idx);
|
||||
out.extend_from_slice(&[r, g, b]);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
// Tests
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn ppm_bytes_has_correct_header() {
|
||||
let fb = [0u8; 4];
|
||||
let bytes = ppm_bytes(&fb, 2, 2);
|
||||
let expected_header = "P6\n2 2\n255\n";
|
||||
let got = String::from_utf8_lossy(&bytes[..expected_header.len()]);
|
||||
assert_eq!(got, expected_header);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ppm_bytes_emits_rgb_per_pixel() {
|
||||
let fb = [0x21u8, 0x21, 0x00, 0x3F]; // 4 pixels: 2x2
|
||||
let bytes = ppm_bytes(&fb, 2, 2);
|
||||
let header = format!("P6\n2 2\n255\n");
|
||||
let pixels = &bytes[header.len()..];
|
||||
assert_eq!(pixels.len(), 2 * 2 * 3); // 12 RGB bytes
|
||||
|
||||
assert_eq!(&pixels[0..3], &[0x64, 0x8D, 0xFF]); // pixel 0 = 0x21, unchanged
|
||||
assert_eq!(&pixels[9..12], &[0x66, 0x87, 0x96]); // pixel 3 = 0x3F (was 6..9)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user