Merge pull request #202 from gwilymk/animated-tiles

Add super simple animated tiles
This commit is contained in:
Gwilym Kuiper 2022-03-27 21:55:49 +01:00 committed by GitHub
commit c43581620f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 25 deletions

View file

@ -0,0 +1,48 @@
#![no_std]
#![no_main]
use agb::{
display::{
tiled::{TileFormat, TileSet, TileSetting},
Priority,
},
include_gfx,
};
include_gfx!("examples/water_tiles.toml");
#[agb::entry]
fn main(mut gba: agb::Gba) -> ! {
let (gfx, mut vram) = gba.display.video.tiled0();
let vblank = agb::interrupt::VBlank::get();
let tileset = TileSet::new(water_tiles::water_tiles.tiles, TileFormat::FourBpp);
let tileset_ref = vram.add_tileset(tileset);
vram.set_background_palettes(water_tiles::water_tiles.palettes);
let mut bg = gfx.background(Priority::P0);
for y in 0..20u16 {
for x in 0..30u16 {
bg.set_tile(
&mut vram,
(x, y).into(),
tileset_ref,
TileSetting::new(0, false, false, 0),
);
}
}
bg.commit();
bg.show();
let mut i = 0;
loop {
i = (i + 1) % 8;
vram.replace_tile(tileset_ref, 0, tileset_ref, i);
vblank.wait_for_vblank();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

View file

@ -0,0 +1,5 @@
version = "1.0"
[image.water_tiles]
filename = "water_tiles.png"
tile_size = "8x8"

View file

@ -188,33 +188,10 @@ impl<'a> VRamManager<'a> {
let new_reference: NonNull<u32> =
unsafe { TILE_ALLOCATOR.alloc(TILE_LAYOUT) }.unwrap().cast();
let tile_slice = if let ArenaStorageItem::Data(data, generation) =
&self.tilesets[tile_set_ref.id as usize]
{
debug_assert_eq!(
*generation, tile_set_ref.generation,
"Stale tile data requested"
);
let tile_offset = (tile as usize) * data.format.tile_size();
&data.tiles[tile_offset..(tile_offset + data.format.tile_size())]
} else {
panic!("Tile set ref must point to existing tile set");
};
let tile_size_in_half_words = tile_slice.len() / 2;
unsafe {
dma_copy16(
tile_slice.as_ptr() as *const u16,
new_reference.as_ptr() as *mut u16,
tile_size_in_half_words,
);
}
let tile_reference = TileReference(new_reference);
self.copy_tile_to_location(tile_set_ref, tile, tile_reference);
let index = Self::index_from_reference(tile_reference);
self.tile_set_to_vram
@ -252,6 +229,54 @@ impl<'a> VRamManager<'a> {
self.reference_counts[index].1 = None;
}
pub fn replace_tile(
&mut self,
source_tile_set_ref: TileSetReference,
source_tile: u16,
target_tile_set_ref: TileSetReference,
target_tile: u16,
) {
if let Some(&reference) = self
.tile_set_to_vram
.get(&(source_tile_set_ref.id, source_tile))
{
self.copy_tile_to_location(target_tile_set_ref, target_tile, reference);
}
}
fn copy_tile_to_location(
&self,
tile_set_ref: TileSetReference,
tile_id: u16,
tile_reference: TileReference,
) {
let tile_slice = if let ArenaStorageItem::Data(data, generation) =
&self.tilesets[tile_set_ref.id as usize]
{
debug_assert_eq!(
*generation, tile_set_ref.generation,
"Stale tile data requested"
);
let tile_offset = (tile_id as usize) * data.format.tile_size();
&data.tiles[tile_offset..(tile_offset + data.format.tile_size())]
} else {
panic!("Target tile set ref must point to an existing tile set reference")
};
let tile_size_in_half_words = tile_slice.len() / 2;
let target_location = tile_reference.0.as_ptr() as *mut _;
unsafe {
dma_copy16(
tile_slice.as_ptr() as *const u16,
target_location,
tile_size_in_half_words,
)
};
}
/// Copies raw palettes to the background palette without any checks.
pub fn set_background_palette_raw(&mut self, palette: &[u16]) {
unsafe {