Correctly allocate screenblocks

This commit is contained in:
Gwilym Kuiper 2022-05-03 23:23:25 +01:00
parent ae65af4ca2
commit be650779e6
4 changed files with 61 additions and 9 deletions

View file

@ -164,7 +164,10 @@ impl RegularMap {
pub struct MapLoan<'a, T> {
map: T,
background_id: u8,
screenblock_id: u8,
screenblock_length: u8,
regular_map_list: &'a RefCell<Bitarray<1>>,
screenblock_list: &'a RefCell<Bitarray<1>>,
}
impl<'a, T> Deref for MapLoan<'a, T> {
@ -185,12 +188,18 @@ impl<'a, T> MapLoan<'a, T> {
pub(crate) fn new(
map: T,
background_id: u8,
screenblock_id: u8,
screenblock_length: u8,
regular_map_list: &'a RefCell<Bitarray<1>>,
screenblock_list: &'a RefCell<Bitarray<1>>,
) -> Self {
MapLoan {
map,
background_id,
screenblock_id,
screenblock_length,
regular_map_list,
screenblock_list,
}
}
}
@ -200,5 +209,11 @@ impl<'a, T> Drop for MapLoan<'a, T> {
self.regular_map_list
.borrow_mut()
.set(self.background_id as usize, false);
let mut screenblock_list = self.screenblock_list.borrow_mut();
for i in self.screenblock_id..self.screenblock_id + self.screenblock_length {
screenblock_list.set(i as usize, false);
}
}
}

View file

@ -48,6 +48,10 @@ impl RegularBackgroundSize {
(self.width() * self.height()) as usize
}
pub(crate) fn num_screen_blocks(&self) -> usize {
self.num_tiles() / (32 * 32)
}
pub(crate) fn rem_euclid_width(&self, x: i32) -> u16 {
((x as u32) & (self.width() - 1)) as u16
}

View file

@ -9,6 +9,7 @@ use super::{MapLoan, RegularBackgroundSize, RegularMap};
pub struct Tiled0 {
regular: RefCell<Bitarray<1>>,
screenblocks: RefCell<Bitarray<1>>,
}
impl Tiled0 {
@ -17,6 +18,7 @@ impl Tiled0 {
Self {
regular: Default::default(),
screenblocks: Default::default(),
}
}
@ -31,15 +33,46 @@ impl Tiled0 {
panic!("can only have 4 active backgrounds");
}
let bg = RegularMap::new(
new_background as u8,
(new_background + 16) as u8,
priority,
size,
);
let num_screenblocks = size.num_screen_blocks();
let mut screenblocks = self.screenblocks.borrow_mut();
let screenblock = find_screenblock_gap(&screenblocks, num_screenblocks);
for id in screenblock..(screenblock + num_screenblocks) {
screenblocks.set(id, true);
}
let bg = RegularMap::new(new_background as u8, screenblock as u8 + 16, priority, size);
regular.set(new_background, true);
MapLoan::new(bg, new_background as u8, &self.regular)
MapLoan::new(
bg,
new_background as u8,
screenblock as u8,
num_screenblocks as u8,
&self.regular,
&self.screenblocks,
)
}
}
fn find_screenblock_gap(screenblocks: &Bitarray<1>, gap: usize) -> usize {
let mut candidate = 0;
'outer: while candidate < 16 - gap {
let starting_point = candidate;
for attempt in starting_point..(starting_point + gap) {
if screenblocks.get(attempt) == Some(true) {
candidate = attempt + 1;
continue 'outer;
}
}
return candidate;
}
panic!(
"Failed to find screenblock gap of at least {} elements",
gap
);
}

View file

@ -846,7 +846,7 @@ fn main(mut agb: agb::Gba) -> ! {
let map_current_level = current_level;
let mut background = InfiniteScrolledMap::new(
tiled.background(Priority::P2, RegularBackgroundSize::Background32x32),
tiled.background(Priority::P2, RegularBackgroundSize::Background64x64),
Box::new(|pos: Vector2D<i32>| {
let level = &map_tiles::LEVELS[map_current_level as usize];
(
@ -861,7 +861,7 @@ fn main(mut agb: agb::Gba) -> ! {
}),
);
let mut foreground = InfiniteScrolledMap::new(
tiled.background(Priority::P0, RegularBackgroundSize::Background32x32),
tiled.background(Priority::P0, RegularBackgroundSize::Background64x64),
Box::new(|pos: Vector2D<i32>| {
let level = &map_tiles::LEVELS[map_current_level as usize];
(