mindustry logic execution, map- and schematic- parsing and rendering
split traits
bendn 2023-08-27
parent f6cc494 · commit 98cad63
-rw-r--r--src/data/map.rs1
-rw-r--r--src/data/renderer.rs4
-rw-r--r--src/utils/image.rs98
-rw-r--r--src/utils/mod.rs2
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};