mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
Introduce the MapLoan to infinite scrolled map
This commit is contained in:
parent
2c8fce40d3
commit
10c97f48d8
|
@ -46,20 +46,20 @@ fn main(mut gba: agb::Gba) -> ! {
|
|||
.unwrap()
|
||||
};
|
||||
|
||||
let mut gfx = gba.display.video.tiled0();
|
||||
let (gfx, mut vram) = gba.display.video.tiled0();
|
||||
let vblank = agb::interrupt::VBlank::get();
|
||||
let mut input = agb::input::ButtonController::new();
|
||||
|
||||
gfx.vram.set_background_palette_raw(&MAP_PALETTE);
|
||||
vram.set_background_palette_raw(&MAP_PALETTE);
|
||||
let tileset = TileSet::new(&MAP_TILES, TileFormat::FourBpp);
|
||||
let tileset_ref = gfx.vram.add_tileset(tileset);
|
||||
let tileset_ref = vram.add_tileset(tileset);
|
||||
|
||||
let mut background = gfx.background();
|
||||
let mut background = gfx.background(agb::display::Priority::P0);
|
||||
|
||||
for (i, &tile) in MAP_MAP.iter().enumerate() {
|
||||
let i = i as u16;
|
||||
background.set_tile(
|
||||
&mut gfx.vram,
|
||||
&mut vram,
|
||||
(i % 32, i / 32).into(),
|
||||
tileset_ref,
|
||||
TileSetting::from_raw(tile),
|
||||
|
|
|
@ -5,10 +5,9 @@ use agb::display::example_logo;
|
|||
|
||||
#[agb::entry]
|
||||
fn main(mut gba: agb::Gba) -> ! {
|
||||
let mut gfx = gba.display.video.tiled0();
|
||||
let (gfx, mut vram) = gba.display.video.tiled0();
|
||||
|
||||
let mut map = gfx.background(agb::display::Priority::P0);
|
||||
let mut vram = gfx.vram;
|
||||
|
||||
example_logo::display_logo(&mut map, &mut vram);
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ struct BackCosines {
|
|||
|
||||
#[agb::entry]
|
||||
fn main(mut gba: agb::Gba) -> ! {
|
||||
let mut gfx = gba.display.video.tiled0();
|
||||
let (gfx, mut vram) = gba.display.video.tiled0();
|
||||
|
||||
let mut background = gfx.background(agb::display::Priority::P0);
|
||||
|
||||
example_logo::display_logo(&mut background, &mut gfx.vram);
|
||||
example_logo::display_logo(&mut background, &mut vram);
|
||||
|
||||
let mut time = 0;
|
||||
let cosines = [0_u16; 32];
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use core::cell::RefCell;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{boxed::Box, vec};
|
||||
|
@ -424,17 +425,17 @@ impl RegularMap {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct InfiniteScrolledMap {
|
||||
map: RegularMap,
|
||||
pub struct InfiniteScrolledMap<'a> {
|
||||
map: MapLoan<'a, RegularMap>,
|
||||
get_tile: Box<dyn Fn(Vector2D<i32>) -> (TileSetReference, TileSetting)>,
|
||||
|
||||
current_pos: Vector2D<i32>,
|
||||
offset: Vector2D<i32>,
|
||||
}
|
||||
|
||||
impl InfiniteScrolledMap {
|
||||
impl<'a> InfiniteScrolledMap<'a> {
|
||||
pub fn new(
|
||||
map: RegularMap,
|
||||
map: MapLoan<'a, RegularMap>,
|
||||
get_tile: Box<dyn Fn(Vector2D<i32>) -> (TileSetReference, TileSetting)>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -613,25 +614,21 @@ fn div_ceil(x: i32, y: i32) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Tiled0<'a> {
|
||||
pub struct Tiled0 {
|
||||
regular: RefCell<Bitarray<1>>,
|
||||
|
||||
pub vram: VRamManager<'a>,
|
||||
}
|
||||
|
||||
impl Tiled0<'_> {
|
||||
impl Tiled0 {
|
||||
pub(crate) unsafe fn new() -> Self {
|
||||
set_graphics_settings(GraphicsSettings::empty() | GraphicsSettings::SPRITE1_D);
|
||||
set_graphics_mode(DisplayMode::Tiled0);
|
||||
|
||||
Self {
|
||||
regular: Default::default(),
|
||||
|
||||
vram: VRamManager::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn background(&mut self, priority: Priority) -> RegularMap {
|
||||
pub fn background(&self, priority: Priority) -> MapLoan<'_, RegularMap> {
|
||||
let mut regular = self.regular.borrow_mut();
|
||||
let new_background = regular.first_zero().unwrap();
|
||||
if new_background >= 4 {
|
||||
|
@ -642,7 +639,7 @@ impl Tiled0<'_> {
|
|||
|
||||
regular.set(new_background, true);
|
||||
|
||||
bg
|
||||
MapLoan::new(bg, new_background as u8, &self.regular)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,3 +648,41 @@ impl TileSetReference {
|
|||
Self { id, generation }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapLoan<'a, T> {
|
||||
map: T,
|
||||
background_id: u8,
|
||||
regular_map_list: &'a RefCell<Bitarray<1>>,
|
||||
}
|
||||
|
||||
impl<'a, T> Deref for MapLoan<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.map
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> DerefMut for MapLoan<'a, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.map
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> MapLoan<'a, T> {
|
||||
fn new(map: T, background_id: u8, regular_map_list: &'a RefCell<Bitarray<1>>) -> Self {
|
||||
MapLoan {
|
||||
map,
|
||||
background_id,
|
||||
regular_map_list,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Drop for MapLoan<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
self.regular_map_list
|
||||
.borrow_mut()
|
||||
.set(self.background_id as usize, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,11 +33,11 @@ mod tests {
|
|||
|
||||
#[test_case]
|
||||
fn logo_display(gba: &mut crate::Gba) {
|
||||
let mut gfx = gba.display.video.tiled0();
|
||||
let (gfx, mut vram) = gba.display.video.tiled0();
|
||||
|
||||
let mut map = gfx.background(crate::display::Priority::P0);
|
||||
|
||||
display_logo(&mut map, &mut gfx.vram);
|
||||
display_logo(&mut map, &mut vram);
|
||||
|
||||
crate::test_runner::assert_image_output("gfx/test_logo.png");
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use super::{background::Tiled0, bitmap3::Bitmap3, bitmap4::Bitmap4};
|
||||
use super::{
|
||||
background::{Tiled0, VRamManager},
|
||||
bitmap3::Bitmap3,
|
||||
bitmap4::Bitmap4,
|
||||
};
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct Video {}
|
||||
|
@ -14,7 +18,7 @@ impl Video {
|
|||
unsafe { Bitmap4::new() }
|
||||
}
|
||||
|
||||
pub fn tiled0(&mut self) -> Tiled0 {
|
||||
unsafe { Tiled0::new() }
|
||||
pub fn tiled0(&mut self) -> (Tiled0, VRamManager<'_>) {
|
||||
(unsafe { Tiled0::new() }, VRamManager::new())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,21 +28,21 @@ agb::include_gfx!("gfx/background.toml");
|
|||
|
||||
type Number = FixedNum<8>;
|
||||
|
||||
struct Level {
|
||||
background: InfiniteScrolledMap,
|
||||
foreground: InfiniteScrolledMap,
|
||||
clouds: InfiniteScrolledMap,
|
||||
struct Level<'a> {
|
||||
background: InfiniteScrolledMap<'a>,
|
||||
foreground: InfiniteScrolledMap<'a>,
|
||||
clouds: InfiniteScrolledMap<'a>,
|
||||
|
||||
slime_spawns: Vec<(u16, u16)>,
|
||||
bat_spawns: Vec<(u16, u16)>,
|
||||
emu_spawns: Vec<(u16, u16)>,
|
||||
}
|
||||
|
||||
impl Level {
|
||||
impl<'a> Level<'a> {
|
||||
fn load_level(
|
||||
mut backdrop: InfiniteScrolledMap,
|
||||
mut foreground: InfiniteScrolledMap,
|
||||
mut clouds: InfiniteScrolledMap,
|
||||
mut backdrop: InfiniteScrolledMap<'a>,
|
||||
mut foreground: InfiniteScrolledMap<'a>,
|
||||
mut clouds: InfiniteScrolledMap<'a>,
|
||||
vram: &mut VRamManager,
|
||||
) -> Self {
|
||||
backdrop.init(vram, (8, 8).into());
|
||||
|
@ -1772,7 +1772,7 @@ struct Game<'a> {
|
|||
player: Player<'a>,
|
||||
input: ButtonController,
|
||||
frame_count: u32,
|
||||
level: Level,
|
||||
level: Level<'a>,
|
||||
offset: Vector2D<Number>,
|
||||
shake_time: u16,
|
||||
sunrise_timer: u16,
|
||||
|
@ -2086,7 +2086,7 @@ impl<'a> Game<'a> {
|
|||
vram.set_background_palettes(&modified_palettes);
|
||||
}
|
||||
|
||||
fn new(object: &'a ObjectControl, level: Level, start_at_boss: bool) -> Self {
|
||||
fn new(object: &'a ObjectControl, level: Level<'a>, start_at_boss: bool) -> Self {
|
||||
let mut player = Player::new(object);
|
||||
let mut offset = (8, 8).into();
|
||||
if start_at_boss {
|
||||
|
@ -2138,12 +2138,11 @@ fn game_with_level(gba: &mut agb::Gba) {
|
|||
let mut start_at_boss = false;
|
||||
|
||||
loop {
|
||||
let mut background = gba.display.video.tiled0();
|
||||
background
|
||||
.vram
|
||||
.set_background_palettes(background::background.palettes);
|
||||
let (background, mut vram) = gba.display.video.tiled0();
|
||||
|
||||
let tileset_ref = background.vram.add_tileset(TileSet::new(
|
||||
vram.set_background_palettes(background::background.palettes);
|
||||
|
||||
let tileset_ref = vram.add_tileset(TileSet::new(
|
||||
background::background.tiles,
|
||||
TileFormat::FourBpp,
|
||||
));
|
||||
|
@ -2189,7 +2188,7 @@ fn game_with_level(gba: &mut agb::Gba) {
|
|||
|
||||
let mut game = Game::new(
|
||||
&object,
|
||||
Level::load_level(backdrop, foreground, clouds, &mut background.vram),
|
||||
Level::load_level(backdrop, foreground, clouds, &mut vram),
|
||||
start_at_boss,
|
||||
);
|
||||
|
||||
|
@ -2197,7 +2196,7 @@ fn game_with_level(gba: &mut agb::Gba) {
|
|||
sfx.frame();
|
||||
vblank.wait_for_vblank();
|
||||
sfx.after_vblank();
|
||||
match game.advance_frame(&object, &mut background.vram, &mut sfx) {
|
||||
match game.advance_frame(&object, &mut vram, &mut sfx) {
|
||||
GameStatus::Continue => {}
|
||||
GameStatus::Lost => {
|
||||
break false;
|
||||
|
|
Loading…
Reference in a new issue