romy_core/
output.rs

1use serde_derive::{Deserialize, Serialize};
2use byteorder::{LittleEndian, ReadBytesExt};
3
4pub struct Color {
5    red: f32,
6    green: f32,
7    blue: f32,
8    alpha: f32,
9}
10
11impl Color {
12    pub fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Color {
13        Self {
14            red,
15            green,
16            blue,
17            alpha,
18        }
19    }
20
21    pub fn from_rgba(rgba: u32) -> Color {
22        let red = (rgba & 0xFF) as f32 / 255.0;
23        let green = ((rgba >> 8) & 0xFF) as f32 / 255.0;
24        let blue = ((rgba >> 16) & 0xFF) as f32 / 255.0;
25        let alpha = ((rgba >> 24) & 0xFF) as f32 / 255.0;
26
27        Self::new(red, green, blue, alpha)
28    }
29
30    pub fn as_rgba(&self) -> u32 {
31        let range = 255.0;
32        let red = (range * self.red) as u32;
33        let green = (range * self.green) as u32;
34        let blue = (range * self.blue) as u32;
35        let alpha = (range * self.alpha) as u32;
36        let mut rgba = alpha << 24;
37        rgba |= blue << 16;
38        rgba |= green << 8;
39        rgba |= red;
40        rgba
41    }
42
43    pub fn red(&self) -> f32 {
44        self.red
45    }
46    
47    pub fn green(&self) -> f32 {
48        self.green
49    }
50
51    pub fn blue(&self) -> f32 {
52        self.blue
53    }
54    
55    pub fn alpha(&self) -> f32 {
56        self.alpha
57    }
58}
59
60/// An image that can be displayed by the runtime.
61///
62/// Internally stores data as an array of 32 bit RGBA values.
63#[derive(Serialize, Deserialize, Debug, Clone)]
64pub struct Image {
65    width: i32,
66    height: i32,
67    data: Vec<u32>,
68}
69
70impl Image {
71    /// Create a blank image
72    /// # Arguments
73    /// * `width` - the number of horizontal pixels
74    /// * `height` - the number of vertical pixels.
75    /// * `color` - the initial color of all pixels in the image.
76    pub fn new(width: i32, height: i32, color: Color) -> Self {
77        let color = color.as_rgba();
78        let mut d = Vec::with_capacity((width * height) as usize);
79        for _ in 0..width * height {
80            d.push(color);
81        }
82
83        Self {
84            width,
85            height,
86            data: d,
87        }
88    }
89
90    /// Create an image from a slice of existing data
91    /// # Arguments
92    /// * `width` - the number of horizontal pixels
93    /// * `height` - the number of vertical pixels
94    /// * `data` - slice of existing data.
95    pub fn from_data(width: i32, height: i32, data: &[u8]) -> Self {
96        let mut d = Vec::with_capacity((width * height) as usize);
97        for i in 0..width * height {
98            let pixel = (&data[i as usize * 4..i as usize * 4 + 4])
99                .read_u32::<LittleEndian>()
100                .unwrap();
101
102            d.push(pixel);
103        }
104
105        Self {
106            width,
107            height,
108            data: d,
109        }
110    }
111
112    /// Gets a pixel in the image
113    /// # Arguments
114    /// * `x` - horizontal coordinate
115    /// * `y` - vertical coordinate
116    pub fn get_pixel(&self, x: i32, y: i32) -> Color {
117        let width = self.width();
118        Color::from_rgba( self.pixels()[(y * width + x) as usize] )
119    }
120
121    /// Sets a pixel in the image to a specified color
122    /// # Arguments
123    /// * `x` - horizontal coordinate
124    /// * `y` - vertical coordinate
125    /// * `color` - color to set the pixel to
126    pub fn set_pixel(&mut self, x: i32, y: i32, color: Color) {
127        let width = self.width();
128        self.pixels_mut()[(y * width + x) as usize] = color.as_rgba();
129    }
130
131    /// Gets the number of horizontal pixels
132    pub fn width(&self) -> i32 {
133        self.width
134    }
135
136    /// Gets the number of vertical pixels
137    pub fn height(&self) -> i32 {
138        self.height
139    }
140
141    /// Gets a reference to the raw pixel buffer
142    pub fn pixels(&self) -> &[u32] {
143        &self.data
144    }
145
146    /// Gets a reference to the raw pixel as u8s
147    pub fn pixels8(&self) -> &[u8] {
148        unsafe {
149            std::slice::from_raw_parts(self.data.as_ptr() as *const u8, self.data.len() * 4)
150        }
151    }
152
153    /// Gets a mutable reference to the raw pixel buffer
154    pub fn pixels_mut(&mut self) -> &mut [u32] {
155        &mut self.data
156    }
157
158    /// Gets a mutable reference to the raw pixel buffer as u8s
159    pub fn pixels8_mut(&mut self) -> &mut [u8] {
160        unsafe {
161            std::slice::from_raw_parts_mut(self.data.as_mut_ptr() as *mut u8, self.data.len() * 4)
162        }
163    }
164}
165
166/// A sound that can be played by the runtime.
167///
168/// Internally stores data as an array of 32 bit floating point values that range from -1.0 to 1.0
169#[derive(Serialize, Deserialize, Debug, Clone)]
170pub struct Sound {
171    sample_rate: i32,
172    samples: Vec<f32>,
173}
174
175impl Sound {
176    /// Create a sound from a slice of existing data
177    /// # Arguments
178    /// * `sample_rate` - the number of samples per second
179    /// * `data` - slice of existing data
180    pub fn from_data(sample_rate: i32, samples: &[f32]) -> Self {
181        Self {
182            sample_rate,
183            samples: samples.to_vec(),
184        }
185    }
186    
187    /// Create a blank/silent sound
188    /// # Arguments
189    /// * `sample_rate` - the number of samples per second
190    /// * `sample_count` - the number of samples
191    pub fn with_buffer_size(sample_rate: i32, sample_count: i32) -> Self {
192        let mut samples = Vec::with_capacity(sample_count as usize);
193        samples.resize(sample_count as usize, 0.0);
194        Self::from_data(sample_rate, &samples)
195    }
196    
197    /// Create a sound with the number of samples needed to cover a specific step time 
198    /// # Arguments
199    /// * `sample_rate` - the number of samples per second
200    /// * `steps_per_second` - the number of steps per second
201    pub fn with_buffer_sized_to_step(sample_rate: i32, steps_per_second: i32) -> Self {
202        let sample_count = sample_rate / steps_per_second;
203        Self::with_buffer_size(sample_rate, sample_count)
204    }
205
206    /// Sets a value of the sample
207    /// # Arguments
208    /// * `index' sample index
209    /// * `sample` - sample value 
210    pub fn set_sample(&mut self, index: i32, sample: f32) {
211        self.samples_mut()[index as usize] = sample;
212    }
213
214    /// Gets the sample rate of the sound
215    pub fn sample_rate(&self) -> i32 {
216        self.sample_rate
217    }
218
219    /// Gets the number of samples stored in this sound
220    pub fn sample_count(&self) -> i32 {
221        self.samples.len() as i32
222    }
223
224    /// Gets a reference to the raw sample data
225    pub fn samples(&self) -> &[f32] {
226        &self.samples
227    }
228
229    /// Gets a mutable reference to the raw sample data
230    pub fn samples_mut(&mut self) -> &mut [f32] {
231        &mut self.samples
232    }
233
234    /// Creates a new sound by sampling a section of this one
235    /// # Arguments
236    /// * `start' sample start index
237    /// * `length` - length of the sample
238    pub fn sample(&self, start: i32, length: i32) -> Self {
239        Self {
240            sample_rate: self.sample_rate,
241            samples: self.samples[(start as usize)..((start + length) as usize)].to_vec(),
242        }
243    }
244}