organicomplex 0.7.0

Interactive complex-valued cellular automaton on 2D and 3D grids in search of that stuff - emergence, open-endedness, organicity etc.
use crate::base::{
	ARGB,
	RGB
};

use super::System;

const ERR_OUTSIDE_SCREEN: &str = "outside screen";

impl System {
	/// Draw a single pixel with alpha channel
	pub fn draw_pixel(&mut self, x: i32, y: i32, color: ARGB) -> Result<(), String> {
		if (x >= 0) && (y >= 0) && (x < self.width) && (y < self.height) {
			let buf = &mut self.buffer;
		    let offs = ((y * self.width + x) << 2) as usize;
			let a = color.a as u32;
			let na = 0x100 - a;
		    buf[offs + 0] = (((color.b as u32) * a + (buf[offs + 0] as u32) * na) >> 8) as u8;
		    buf[offs + 1] = (((color.g as u32) * a + (buf[offs + 1] as u32) * na) >> 8) as u8;
		    buf[offs + 2] = (((color.r as u32) * a + (buf[offs + 2] as u32) * na) >> 8) as u8;
			Ok(())
		} else {
			Err(String::from(ERR_OUTSIDE_SCREEN))
		}
	}
	// "Now we can make DOOM". But DOOM has been made already, long ago...

	/// Draw a single pixel without alpha channel
	pub fn draw_pixel_opaque(&mut self, x: i32, y: i32, color: RGB) -> Result<(), String> {
		if (x >= 0) && (y >= 0) && (x < self.width) && (y < self.height) {
			let buf = &mut self.buffer;
		    let offs = ((y * self.width + x) << 2) as usize;
		    buf[offs + 0] = color.b;
		    buf[offs + 1] = color.g;
		    buf[offs + 2] = color.r;
			buf[offs + 3] = 0xFF;
			Ok(())
		} else {
			Err(String::from(ERR_OUTSIDE_SCREEN))
		}
	}

}