mindustry logic execution, map- and schematic- parsing and rendering
fix incorrect canvas drawing
bendn 2023-08-14
parent 190450d · commit 20bcdff
-rw-r--r--Cargo.toml2
-rw-r--r--src/block/logic.rs3
-rw-r--r--src/utils/image.rs37
3 files changed, 29 insertions, 13 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 9c42197..3f30c92 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "mindus"
-version = "4.0.1"
+version = "4.0.2"
edition = "2021"
description = "A library for working with mindustry data formats (eg schematics and maps) (fork of plandustry)"
authors = [
diff --git a/src/block/logic.rs b/src/block/logic.rs
index 769e639..a099765 100644
--- a/src/block/logic.rs
+++ b/src/block/logic.rs
@@ -152,8 +152,9 @@ impl BlockLogic for CanvasBlock {
Scale::Eigth => 1,
};
let mut img = Image::alloc(p.width(), p.height());
- for ([r, g, b], &y) in img.buffer.array_chunks_mut::<3>().zip(p.buffer.iter()) {
+ for ([r, g, b, a], &y) in img.chunked_mut().zip(p.buffer.iter()) {
(*r, *g, *b) = PALETTE[y as usize];
+ *a = 255;
}
let img = img.as_mut().scale((s * self.size as u32) - offset * 2);
let mut borders = load!("canvas", s);
diff --git a/src/utils/image.rs b/src/utils/image.rs
index f5debcb..8254bb7 100644
--- a/src/utils/image.rs
+++ b/src/utils/image.rs
@@ -262,10 +262,7 @@ impl ImageUtils for Image<&mut [u8], 4> {
unsafe fn overlay(&mut self, with: &Image<&[u8], 4>) -> &mut Self {
unsafe_assert!(self.width() == with.width());
unsafe_assert!(self.height() == with.height());
- unsafe_assert!(with.buffer.len() > 4);
- unsafe_assert!(self.buffer.len() % 4 == 0);
- unsafe_assert!(with.buffer.len() % 4 == 0);
- for (i, other_pixels) in with.buffer.array_chunks::<4>().enumerate() {
+ for (i, other_pixels) in with.chunked().enumerate() {
if other_pixels[3] > 128 {
unsafe {
let own_pixels = self
@@ -287,15 +284,12 @@ impl ImageUtils for Image<&mut [u8], 4> {
let from =
fr::Image::from_slice_u8(self.width, self.height, self.buffer, fr::PixelType::U8x4)
.unwrap();
- let mut dst = fr::Image::new(
- to.try_into().unwrap(),
- to.try_into().unwrap(),
- fr::PixelType::U8x4,
- );
+ let to = to.try_into().unwrap();
+ let mut dst = fr::Image::new(to, to, fr::PixelType::U8x4);
fr::Resizer::new(fr::ResizeAlg::Nearest)
.resize(&from.view(), &mut dst.view_mut())
.unwrap();
- Image::new(self.width, self.height, dst.into_vec())
+ Image::new(to, to, dst.into_vec())
}
fn shadow(&mut self) -> &mut Self {
@@ -412,24 +406,37 @@ impl<T: std::ops::Deref<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS
}
#[inline]
+ pub fn chunked(&self) -> impl Iterator<Item = &[u8; CHANNELS]> {
+ unsafe_assert!(self.buffer.len() > CHANNELS);
+ unsafe_assert!(self.buffer.len() % CHANNELS == 0);
+ self.buffer.array_chunks::<CHANNELS>()
+ }
+
/// Return a pixel at (x, y).
/// # Safety
///
/// Refer to [`slice`]
+ #[inline]
pub unsafe fn pixel(&self, x: u32, y: u32) -> [u8; CHANNELS] {
*(self.buffer.get_unchecked(self.slice(x, y)).as_ptr().cast())
}
}
impl<T: std::ops::DerefMut<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
- #[inline]
/// Return a mutable reference to a pixel at (x, y).
/// # Safety
///
/// Refer to [`slice`]
+ #[inline]
pub unsafe fn pixel_mut(&mut self, x: u32, y: u32) -> &mut [u8] {
let idx = self.slice(x, y);
self.buffer.get_unchecked_mut(idx)
}
+
+ #[inline]
+ pub fn chunked_mut(&mut self) -> impl Iterator<Item = &mut [u8; CHANNELS]> {
+ self.buffer.array_chunks_mut::<CHANNELS>()
+ }
+
#[inline]
pub unsafe fn set_pixel(&mut self, x: u32, y: u32, px: [u8; CHANNELS]) {
std::ptr::copy_nonoverlapping(px.as_ptr(), self.pixel_mut(x, y).as_mut_ptr(), CHANNELS);
@@ -682,6 +689,14 @@ mod tests {
]
)
}
+
+ #[test]
+ fn scale() {
+ let mut from = Image::alloc(6, 6);
+ unsafe { from.set_pixel(3, 3, [255, 255, 255, 255]) };
+ let from = from.as_mut().scale(12);
+ assert_eq!(unsafe { from.pixel(6, 6) }, [255, 255, 255, 255]);
+ }
}
pub fn blend(bg: &mut [u8; 4], fg: [u8; 4]) {