mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
Correctly allocate screenblocks
This commit is contained in:
parent
ae65af4ca2
commit
be650779e6
|
@ -164,7 +164,10 @@ impl RegularMap {
|
||||||
pub struct MapLoan<'a, T> {
|
pub struct MapLoan<'a, T> {
|
||||||
map: T,
|
map: T,
|
||||||
background_id: u8,
|
background_id: u8,
|
||||||
|
screenblock_id: u8,
|
||||||
|
screenblock_length: u8,
|
||||||
regular_map_list: &'a RefCell<Bitarray<1>>,
|
regular_map_list: &'a RefCell<Bitarray<1>>,
|
||||||
|
screenblock_list: &'a RefCell<Bitarray<1>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for MapLoan<'a, T> {
|
impl<'a, T> Deref for MapLoan<'a, T> {
|
||||||
|
@ -185,12 +188,18 @@ impl<'a, T> MapLoan<'a, T> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
map: T,
|
map: T,
|
||||||
background_id: u8,
|
background_id: u8,
|
||||||
|
screenblock_id: u8,
|
||||||
|
screenblock_length: u8,
|
||||||
regular_map_list: &'a RefCell<Bitarray<1>>,
|
regular_map_list: &'a RefCell<Bitarray<1>>,
|
||||||
|
screenblock_list: &'a RefCell<Bitarray<1>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
MapLoan {
|
MapLoan {
|
||||||
map,
|
map,
|
||||||
background_id,
|
background_id,
|
||||||
|
screenblock_id,
|
||||||
|
screenblock_length,
|
||||||
regular_map_list,
|
regular_map_list,
|
||||||
|
screenblock_list,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,5 +209,11 @@ impl<'a, T> Drop for MapLoan<'a, T> {
|
||||||
self.regular_map_list
|
self.regular_map_list
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.set(self.background_id as usize, false);
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,10 @@ impl RegularBackgroundSize {
|
||||||
(self.width() * self.height()) as usize
|
(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 {
|
pub(crate) fn rem_euclid_width(&self, x: i32) -> u16 {
|
||||||
((x as u32) & (self.width() - 1)) as u16
|
((x as u32) & (self.width() - 1)) as u16
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use super::{MapLoan, RegularBackgroundSize, RegularMap};
|
||||||
|
|
||||||
pub struct Tiled0 {
|
pub struct Tiled0 {
|
||||||
regular: RefCell<Bitarray<1>>,
|
regular: RefCell<Bitarray<1>>,
|
||||||
|
screenblocks: RefCell<Bitarray<1>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tiled0 {
|
impl Tiled0 {
|
||||||
|
@ -17,6 +18,7 @@ impl Tiled0 {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
regular: Default::default(),
|
regular: Default::default(),
|
||||||
|
screenblocks: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,15 +33,46 @@ impl Tiled0 {
|
||||||
panic!("can only have 4 active backgrounds");
|
panic!("can only have 4 active backgrounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
let bg = RegularMap::new(
|
let num_screenblocks = size.num_screen_blocks();
|
||||||
new_background as u8,
|
let mut screenblocks = self.screenblocks.borrow_mut();
|
||||||
(new_background + 16) as u8,
|
|
||||||
priority,
|
let screenblock = find_screenblock_gap(&screenblocks, num_screenblocks);
|
||||||
size,
|
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);
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -846,7 +846,7 @@ fn main(mut agb: agb::Gba) -> ! {
|
||||||
|
|
||||||
let map_current_level = current_level;
|
let map_current_level = current_level;
|
||||||
let mut background = InfiniteScrolledMap::new(
|
let mut background = InfiniteScrolledMap::new(
|
||||||
tiled.background(Priority::P2, RegularBackgroundSize::Background32x32),
|
tiled.background(Priority::P2, RegularBackgroundSize::Background64x64),
|
||||||
Box::new(|pos: Vector2D<i32>| {
|
Box::new(|pos: Vector2D<i32>| {
|
||||||
let level = &map_tiles::LEVELS[map_current_level as usize];
|
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(
|
let mut foreground = InfiniteScrolledMap::new(
|
||||||
tiled.background(Priority::P0, RegularBackgroundSize::Background32x32),
|
tiled.background(Priority::P0, RegularBackgroundSize::Background64x64),
|
||||||
Box::new(|pos: Vector2D<i32>| {
|
Box::new(|pos: Vector2D<i32>| {
|
||||||
let level = &map_tiles::LEVELS[map_current_level as usize];
|
let level = &map_tiles::LEVELS[map_current_level as usize];
|
||||||
(
|
(
|
||||||
|
|
Loading…
Reference in a new issue