mindustry logic execution, map- and schematic- parsing and rendering
split traits
| -rw-r--r-- | src/data/map.rs | 1 | ||||
| -rw-r--r-- | src/data/renderer.rs | 4 | ||||
| -rw-r--r-- | src/utils/image.rs | 98 | ||||
| -rw-r--r-- | src/utils/mod.rs | 2 |
4 files changed, 65 insertions, 40 deletions
diff --git a/src/data/map.rs b/src/data/map.rs index b25ce94..98d8fac 100644 --- a/src/data/map.rs +++ b/src/data/map.rs @@ -86,7 +86,6 @@ use crate::{block::content, data::*, fluid, item, modifier, unit}; use super::{entity_mapping, Serializable}; use crate::content::Content; -use crate::utils::image::ImageUtils; /// a tile in a map #[derive(Clone)] diff --git a/src/data/renderer.rs b/src/data/renderer.rs index 5625212..4ceef76 100644 --- a/src/data/renderer.rs +++ b/src/data/renderer.rs @@ -3,7 +3,7 @@ pub(crate) use super::autotile::*; use super::schematic::Schematic; use super::GridPos; use crate::block::Rotation; -pub(crate) use crate::utils::{Image, ImageHolder, ImageUtils, Overlay, Repeat}; +pub(crate) use crate::utils::{Image, ImageHolder, ImageUtils, Overlay, OverlayAt, Repeat}; use crate::Map; include!(concat!(env!("OUT_DIR"), "/full.rs")); include!(concat!(env!("OUT_DIR"), "/quar.rs")); @@ -237,7 +237,7 @@ impl Renderable for Map<'_> { } } } - unsafe { floor.as_mut().overlay_at(&top.as_ref(), 0, 0) }; + unsafe { floor.as_mut().overlay(&top.as_ref()) }; floor } } diff --git a/src/utils/image.rs b/src/utils/image.rs index ee1ddea..972b10e 100644 --- a/src/utils/image.rs +++ b/src/utils/image.rs @@ -4,7 +4,7 @@ use std::simd::SimdPartialOrd; use std::simd::{simd_swizzle, Simd}; use std::{num::NonZeroU32, slice::SliceIndex}; -pub trait Overlay<W> { +pub trait OverlayAt<W> { /// Overlay with => self at coordinates x, y, without blending /// # Safety /// @@ -12,6 +12,14 @@ pub trait Overlay<W> { unsafe fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self; } +pub trait Overlay<W> { + /// Overlay with => self (does not blend) + /// # Safety + /// + /// UB if a.width != b.width || a.height != b.height + unsafe fn overlay(&mut self, with: &W) -> &mut Self; +} + pub trait RepeatNew { type Output; /// Repeat self till it fills a new image of size x, y @@ -22,14 +30,8 @@ pub trait RepeatNew { } pub trait ImageUtils { - type With<'a>; /// Tint this image with the color fn tint(&mut self, color: (u8, u8, u8)) -> &mut Self; - /// Overlay with => self (does not blend) - /// # Safety - /// - /// UB if a.width != b.width || a.height != b.height - unsafe fn overlay(&mut self, with: Self::With<'_>) -> &mut Self; /// rotate (squares only) /// # Safety /// @@ -58,7 +60,7 @@ macro_rules! unsafe_assert { }}; } -impl Overlay<Image<&[u8], 3>> for Image<&mut [u8], 3> { +impl OverlayAt<Image<&[u8], 3>> for Image<&mut [u8], 3> { unsafe fn overlay_at(&mut self, with: &Image<&[u8], 3>, x: u32, y: u32) -> &mut Self { for j in 0..with.height() { for i in 0..with.width() { @@ -121,7 +123,7 @@ pub unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) { } } -impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 3> { +impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 3> { unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self { unsafe_assert!(x + with.width() <= self.width()); unsafe_assert!(y + with.height() <= self.height()); @@ -142,7 +144,27 @@ impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 3> { } } -impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 4> { +impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 3> { + unsafe fn overlay(&mut self, with: &Image<&[u8], 4>) -> &mut Self { + unsafe_assert!(self.width() == with.width()); + unsafe_assert!(self.height() == with.height()); + for (i, chunk) in with + .buffer + .chunks_exact(with.width() as usize * 4) + .enumerate() + { + blit( + self.buffer.get_unchecked_mut( + i * with.width() as usize * 3..(i + 1) * with.width() as usize * 3, + ), + chunk, + ); + } + self + } +} + +impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 4> { unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self { for j in 0..with.height() { for i in 0..with.width() { @@ -282,6 +304,28 @@ pub unsafe fn rot_270<const CHANNELS: usize>(img: &mut Image<&mut [u8], CHANNELS } } +impl Overlay<Image<&[u8], 4>> 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()); + for (i, other_pixels) in with.chunked().enumerate() { + if other_pixels[3] >= 128 { + unsafe { + let own_pixels = self + .buffer + .get_unchecked_mut(i.unchecked_mul(4)..i.unchecked_mul(4).unchecked_add(4)); + std::ptr::copy_nonoverlapping( + other_pixels.as_ptr(), + own_pixels.as_mut_ptr(), + 4, + ); + } + } + } + self + } +} + impl ImageUtils for Image<&mut [u8], 4> { unsafe fn rotate(&mut self, times: u8) -> &mut Self { match times { @@ -302,26 +346,6 @@ impl ImageUtils for Image<&mut [u8], 4> { } self } - type With<'a> = &'a Image<&'a [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()); - for (i, other_pixels) in with.chunked().enumerate() { - if other_pixels[3] >= 128 { - unsafe { - let own_pixels = self - .buffer - .get_unchecked_mut(i.unchecked_mul(4)..i.unchecked_mul(4).unchecked_add(4)); - std::ptr::copy_nonoverlapping( - other_pixels.as_ptr(), - own_pixels.as_mut_ptr(), - 4, - ); - } - } - } - self - } // this function is very cold but im removing image so might as well use fir fn scale(self, to: u32) -> Image<Vec<u8>, 4> { @@ -578,23 +602,25 @@ impl<const CHANNELS: usize> ImageHolder<CHANNELS> { } } -impl Overlay<ImageHolder<4>> for ImageHolder<4> { +impl OverlayAt<ImageHolder<4>> for ImageHolder<4> { unsafe fn overlay_at(&mut self, with: &ImageHolder<4>, x: u32, y: u32) -> &mut Self { self.borrow_mut().overlay_at(&with.borrow(), x, y); self } } +impl Overlay<ImageHolder<4>> for ImageHolder<4> { + unsafe fn overlay(&mut self, with: &Self) -> &mut Self { + self.borrow_mut().overlay(&with.borrow()); + self + } +} + impl ImageUtils for ImageHolder<4> { fn tint(&mut self, color: (u8, u8, u8)) -> &mut Self { self.borrow_mut().tint(color); self } - type With<'a> = &'a Self; - unsafe fn overlay(&mut self, with: &Self) -> &mut Self { - self.borrow_mut().overlay(&with.borrow()); - self - } unsafe fn rotate(&mut self, times: u8) -> &mut Self { if times == 0 { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 6e781fe..4518839 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,3 +1,3 @@ pub mod array; pub mod image; -pub use self::image::{Image, ImageHolder, ImageUtils, Overlay, RepeatNew as Repeat}; +pub use self::image::{Image, ImageHolder, ImageUtils, Overlay, OverlayAt, RepeatNew as Repeat}; |