mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-26 09:06:33 +11:00
Merge pull request #202 from gwilymk/animated-tiles
Add super simple animated tiles
This commit is contained in:
commit
c43581620f
4 changed files with 103 additions and 25 deletions
48
agb/examples/animated_background.rs
Normal file
48
agb/examples/animated_background.rs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
BIN
agb/examples/water_tiles.png
Normal file
BIN
agb/examples/water_tiles.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 209 B |
5
agb/examples/water_tiles.toml
Normal file
5
agb/examples/water_tiles.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
version = "1.0"
|
||||||
|
|
||||||
|
[image.water_tiles]
|
||||||
|
filename = "water_tiles.png"
|
||||||
|
tile_size = "8x8"
|
|
@ -188,33 +188,10 @@ impl<'a> VRamManager<'a> {
|
||||||
|
|
||||||
let new_reference: NonNull<u32> =
|
let new_reference: NonNull<u32> =
|
||||||
unsafe { TILE_ALLOCATOR.alloc(TILE_LAYOUT) }.unwrap().cast();
|
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);
|
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);
|
let index = Self::index_from_reference(tile_reference);
|
||||||
|
|
||||||
self.tile_set_to_vram
|
self.tile_set_to_vram
|
||||||
|
@ -252,6 +229,54 @@ impl<'a> VRamManager<'a> {
|
||||||
self.reference_counts[index].1 = None;
|
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.
|
/// Copies raw palettes to the background palette without any checks.
|
||||||
pub fn set_background_palette_raw(&mut self, palette: &[u16]) {
|
pub fn set_background_palette_raw(&mut self, palette: &[u16]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
Loading…
Add table
Reference in a new issue