mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-11 17:41:33 +11:00
possible iter for backgrounds
This commit is contained in:
parent
6f804d884b
commit
1541d514c9
|
@ -129,7 +129,7 @@ impl<'a> Map<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> BackgroundRegular<'a> {
|
||||
impl<'a, 'b> BackgroundRegular<'a> {
|
||||
unsafe fn new(background: u8, block: u8, size: BackgroundSize) -> BackgroundRegular<'a> {
|
||||
let mut b = BackgroundRegular {
|
||||
background,
|
||||
|
@ -211,29 +211,23 @@ impl<'a> BackgroundRegular<'a> {
|
|||
self.map = Some(map);
|
||||
}
|
||||
|
||||
pub fn commit(&mut self) {
|
||||
pub fn commit_partial(&'b mut self) -> impl Iterator<Item = ()> + 'b {
|
||||
// commit shadowed register
|
||||
unsafe { self.get_register().set(self.shadowed_register) };
|
||||
|
||||
let map = self.map.as_ref().unwrap();
|
||||
|
||||
let commited_screen = Rect::new(self.commited_position, self.copy_size.change_base());
|
||||
let shadowed_screen = Rect::new(self.shadowed_position, self.copy_size.change_base());
|
||||
|
||||
if self.poisoned || !shadowed_screen.touches(commited_screen) {
|
||||
let iter = if self.poisoned || !shadowed_screen.touches(commited_screen) {
|
||||
let positions_to_be_updated = Rect::new(
|
||||
self.shadowed_position / 8 - (1, 1).into(),
|
||||
self.copy_size.change_base() + (1, 1).into(),
|
||||
)
|
||||
.iter();
|
||||
|
||||
if let Some(map) = &self.map {
|
||||
for (x, y) in positions_to_be_updated {
|
||||
unsafe {
|
||||
(&mut (*MAP)[self.block as usize][y.rem_euclid(32) as usize]
|
||||
[x.rem_euclid(32) as usize] as *mut u16)
|
||||
.write_volatile(map.get_position(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
positions_to_be_updated.chain(Rect::new((0, 0).into(), (0, 0).into()).iter())
|
||||
} else {
|
||||
let commited_block = self.commited_position / 8;
|
||||
let shadowed_block = self.shadowed_position / 8;
|
||||
|
@ -264,15 +258,7 @@ impl<'a> BackgroundRegular<'a> {
|
|||
)
|
||||
};
|
||||
|
||||
if let Some(map) = &self.map {
|
||||
for (x, y) in top_bottom_rect.iter().chain(left_right_rect.iter()) {
|
||||
unsafe {
|
||||
(&mut (*MAP)[self.block as usize][y.rem_euclid(32) as usize]
|
||||
[x.rem_euclid(32) as usize] as *mut u16)
|
||||
.write_volatile(map.get_position(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
top_bottom_rect.iter().chain(left_right_rect.iter())
|
||||
};
|
||||
|
||||
// update commited position
|
||||
|
@ -287,6 +273,18 @@ impl<'a> BackgroundRegular<'a> {
|
|||
self.set_position_x_register((self.commited_position.x % (32 * 8)) as u16);
|
||||
self.set_position_y_register((self.commited_position.y % (32 * 8)) as u16);
|
||||
}
|
||||
|
||||
let block = self.block;
|
||||
|
||||
iter.map(move |(x, y)| unsafe {
|
||||
(&mut (*MAP)[block as usize][y.rem_euclid(32) as usize][x.rem_euclid(32) as usize]
|
||||
as *mut u16)
|
||||
.write_volatile(map.get_position(x, y));
|
||||
})
|
||||
}
|
||||
|
||||
pub fn commit(&mut self) {
|
||||
self.commit_partial().count();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#![feature(alloc_error_handler)]
|
||||
#![test_runner(crate::test_runner)]
|
||||
#![reexport_test_harness_main = "test_main"]
|
||||
#![feature(step_trait)]
|
||||
//! # agb
|
||||
//! `agb` is a library for making games on the Game Boy Advance using the Rust
|
||||
//! programming language. It attempts to be a high level abstraction over the
|
||||
|
|
|
@ -700,30 +700,16 @@ impl<T: Number> Rect<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: FixedWidthUnsignedInteger> Rect<T> {
|
||||
impl<T: FixedWidthUnsignedInteger + core::iter::Step> Rect<T> {
|
||||
pub fn iter(self) -> impl Iterator<Item = (T, T)> {
|
||||
let mut current_x = self.position.x;
|
||||
let mut current_y = self.position.y;
|
||||
let mut is_done = false;
|
||||
core::iter::from_fn(move || {
|
||||
if is_done {
|
||||
None
|
||||
} else {
|
||||
let (old_x, old_y) = (current_x, current_y);
|
||||
|
||||
current_x = current_x + T::one();
|
||||
if current_x > self.position.x + self.size.x {
|
||||
current_x = self.position.x;
|
||||
current_y = current_y + T::one();
|
||||
}
|
||||
|
||||
if current_y > self.position.y + self.size.y {
|
||||
is_done = true;
|
||||
}
|
||||
|
||||
Some((old_x, old_y))
|
||||
}
|
||||
(self.position.x..=(self.position.x + self.size.x))
|
||||
.into_iter()
|
||||
.map(move |x| {
|
||||
(self.position.y..=(self.position.y + self.size.y))
|
||||
.into_iter()
|
||||
.map(move |y| (x, y))
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue