use serde_derive::{Deserialize, Serialize};
use byteorder::{LittleEndian, ReadBytesExt};
pub struct Color {
red: f32,
green: f32,
blue: f32,
alpha: f32,
}
impl Color {
pub fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Color {
Self {
red,
green,
blue,
alpha,
}
}
pub fn from_rgba(rgba: u32) -> Color {
let red = (rgba & 0xFF) as f32 / 255.0;
let green = ((rgba >> 8) & 0xFF) as f32 / 255.0;
let blue = ((rgba >> 16) & 0xFF) as f32 / 255.0;
let alpha = ((rgba >> 24) & 0xFF) as f32 / 255.0;
Self::new(red, green, blue, alpha)
}
pub fn as_rgba(&self) -> u32 {
let range = 255.0;
let red = (range * self.red) as u32;
let green = (range * self.green) as u32;
let blue = (range * self.blue) as u32;
let alpha = (range * self.alpha) as u32;
let mut rgba = alpha << 24;
rgba |= blue << 16;
rgba |= green << 8;
rgba |= red;
rgba
}
pub fn red(&self) -> f32 {
self.red
}
pub fn green(&self) -> f32 {
self.green
}
pub fn blue(&self) -> f32 {
self.blue
}
pub fn alpha(&self) -> f32 {
self.alpha
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Image {
width: i32,
height: i32,
data: Vec<u32>,
}
impl Image {
pub fn new(width: i32, height: i32, color: Color) -> Self {
let color = color.as_rgba();
let mut d = Vec::with_capacity((width * height) as usize);
for _ in 0..width * height {
d.push(color);
}
Self {
width,
height,
data: d,
}
}
pub fn from_data(width: i32, height: i32, data: &[u8]) -> Self {
let mut d = Vec::with_capacity((width * height) as usize);
for i in 0..width * height {
let pixel = (&data[i as usize * 4..i as usize * 4 + 4])
.read_u32::<LittleEndian>()
.unwrap();
d.push(pixel);
}
Self {
width,
height,
data: d,
}
}
pub fn get_pixel(&self, x: i32, y: i32) -> Color {
let width = self.width();
Color::from_rgba( self.pixels()[(y * width + x) as usize] )
}
pub fn set_pixel(&mut self, x: i32, y: i32, color: Color) {
let width = self.width();
self.pixels_mut()[(y * width + x) as usize] = color.as_rgba();
}
pub fn width(&self) -> i32 {
self.width
}
pub fn height(&self) -> i32 {
self.height
}
pub fn pixels(&self) -> &[u32] {
&self.data
}
pub fn pixels8(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(self.data.as_ptr() as *const u8, self.data.len() * 4)
}
}
pub fn pixels_mut(&mut self) -> &mut [u32] {
&mut self.data
}
pub fn pixels8_mut(&mut self) -> &mut [u8] {
unsafe {
std::slice::from_raw_parts_mut(self.data.as_mut_ptr() as *mut u8, self.data.len() * 4)
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Sound {
sample_rate: i32,
samples: Vec<f32>,
}
impl Sound {
pub fn from_data(sample_rate: i32, samples: &[f32]) -> Self {
Self {
sample_rate,
samples: samples.to_vec(),
}
}
pub fn with_buffer_size(sample_rate: i32, sample_count: i32) -> Self {
let mut samples = Vec::with_capacity(sample_count as usize);
samples.resize(sample_count as usize, 0.0);
Self::from_data(sample_rate, &samples)
}
pub fn with_buffer_sized_to_step(sample_rate: i32, steps_per_second: i32) -> Self {
let sample_count = sample_rate / steps_per_second;
Self::with_buffer_size(sample_rate, sample_count)
}
pub fn set_sample(&mut self, index: i32, sample: f32) {
self.samples_mut()[index as usize] = sample;
}
pub fn sample_rate(&self) -> i32 {
self.sample_rate
}
pub fn sample_count(&self) -> i32 {
self.samples.len() as i32
}
pub fn samples(&self) -> &[f32] {
&self.samples
}
pub fn samples_mut(&mut self) -> &mut [f32] {
&mut self.samples
}
pub fn sample(&self, start: i32, length: i32) -> Self {
Self {
sample_rate: self.sample_rate,
samples: self.samples[(start as usize)..((start + length) as usize)].to_vec(),
}
}
}