mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-12 01:51:34 +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> {
|
unsafe fn new(background: u8, block: u8, size: BackgroundSize) -> BackgroundRegular<'a> {
|
||||||
let mut b = BackgroundRegular {
|
let mut b = BackgroundRegular {
|
||||||
background,
|
background,
|
||||||
|
@ -211,29 +211,23 @@ impl<'a> BackgroundRegular<'a> {
|
||||||
self.map = Some(map);
|
self.map = Some(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit(&mut self) {
|
pub fn commit_partial(&'b mut self) -> impl Iterator<Item = ()> + 'b {
|
||||||
// commit shadowed register
|
// commit shadowed register
|
||||||
unsafe { self.get_register().set(self.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 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());
|
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(
|
let positions_to_be_updated = Rect::new(
|
||||||
self.shadowed_position / 8 - (1, 1).into(),
|
self.shadowed_position / 8 - (1, 1).into(),
|
||||||
self.copy_size.change_base() + (1, 1).into(),
|
self.copy_size.change_base() + (1, 1).into(),
|
||||||
)
|
)
|
||||||
.iter();
|
.iter();
|
||||||
|
|
||||||
if let Some(map) = &self.map {
|
positions_to_be_updated.chain(Rect::new((0, 0).into(), (0, 0).into()).iter())
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let commited_block = self.commited_position / 8;
|
let commited_block = self.commited_position / 8;
|
||||||
let shadowed_block = self.shadowed_position / 8;
|
let shadowed_block = self.shadowed_position / 8;
|
||||||
|
@ -264,15 +258,7 @@ impl<'a> BackgroundRegular<'a> {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(map) = &self.map {
|
top_bottom_rect.iter().chain(left_right_rect.iter())
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// update commited position
|
// 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_x_register((self.commited_position.x % (32 * 8)) as u16);
|
||||||
self.set_position_y_register((self.commited_position.y % (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)]
|
#![feature(alloc_error_handler)]
|
||||||
#![test_runner(crate::test_runner)]
|
#![test_runner(crate::test_runner)]
|
||||||
#![reexport_test_harness_main = "test_main"]
|
#![reexport_test_harness_main = "test_main"]
|
||||||
|
#![feature(step_trait)]
|
||||||
//! # agb
|
//! # agb
|
||||||
//! `agb` is a library for making games on the Game Boy Advance using the Rust
|
//! `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
|
//! 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)> {
|
pub fn iter(self) -> impl Iterator<Item = (T, T)> {
|
||||||
let mut current_x = self.position.x;
|
(self.position.x..=(self.position.x + self.size.x))
|
||||||
let mut current_y = self.position.y;
|
.into_iter()
|
||||||
let mut is_done = false;
|
.map(move |x| {
|
||||||
core::iter::from_fn(move || {
|
(self.position.y..=(self.position.y + self.size.y))
|
||||||
if is_done {
|
.into_iter()
|
||||||
None
|
.map(move |y| (x, y))
|
||||||
} 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))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue