mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 16:51:33 +11:00
Merge pull request #203 from gwilymk/remove-tile-set-ref
Remove tile set ref
This commit is contained in:
commit
dc8a73b276
|
@ -17,7 +17,6 @@ fn main(mut gba: agb::Gba) -> ! {
|
||||||
let vblank = agb::interrupt::VBlank::get();
|
let vblank = agb::interrupt::VBlank::get();
|
||||||
|
|
||||||
let tileset = TileSet::new(water_tiles::water_tiles.tiles, TileFormat::FourBpp);
|
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);
|
vram.set_background_palettes(water_tiles::water_tiles.palettes);
|
||||||
|
|
||||||
|
@ -28,7 +27,7 @@ fn main(mut gba: agb::Gba) -> ! {
|
||||||
bg.set_tile(
|
bg.set_tile(
|
||||||
&mut vram,
|
&mut vram,
|
||||||
(x, y).into(),
|
(x, y).into(),
|
||||||
tileset_ref,
|
&tileset,
|
||||||
TileSetting::new(0, false, false, 0),
|
TileSetting::new(0, false, false, 0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +40,7 @@ fn main(mut gba: agb::Gba) -> ! {
|
||||||
loop {
|
loop {
|
||||||
i = (i + 1) % 8;
|
i = (i + 1) % 8;
|
||||||
|
|
||||||
vram.replace_tile(tileset_ref, 0, tileset_ref, i);
|
vram.replace_tile(&tileset, 0, &tileset, i);
|
||||||
|
|
||||||
vblank.wait_for_vblank();
|
vblank.wait_for_vblank();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ fn main(mut gba: agb::Gba) -> ! {
|
||||||
|
|
||||||
vram.set_background_palette_raw(&MAP_PALETTE);
|
vram.set_background_palette_raw(&MAP_PALETTE);
|
||||||
let tileset = TileSet::new(&MAP_TILES, TileFormat::FourBpp);
|
let tileset = TileSet::new(&MAP_TILES, TileFormat::FourBpp);
|
||||||
let tileset_ref = vram.add_tileset(tileset);
|
|
||||||
|
|
||||||
let mut background = gfx.background(agb::display::Priority::P0);
|
let mut background = gfx.background(agb::display::Priority::P0);
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ fn main(mut gba: agb::Gba) -> ! {
|
||||||
background.set_tile(
|
background.set_tile(
|
||||||
&mut vram,
|
&mut vram,
|
||||||
(i % 32, i / 32).into(),
|
(i % 32, i / 32).into(),
|
||||||
tileset_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(tile),
|
TileSetting::from_raw(tile),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ pub fn display_logo(map: &mut RegularMap, vram: &mut VRamManager) {
|
||||||
vram.set_background_palettes(agb_logo::test_logo.palettes);
|
vram.set_background_palettes(agb_logo::test_logo.palettes);
|
||||||
|
|
||||||
let background_tilemap = TileSet::new(agb_logo::test_logo.tiles, TileFormat::FourBpp);
|
let background_tilemap = TileSet::new(agb_logo::test_logo.tiles, TileFormat::FourBpp);
|
||||||
let background_tilemap_reference = vram.add_tileset(background_tilemap);
|
|
||||||
|
|
||||||
for y in 0..20 {
|
for y in 0..20 {
|
||||||
for x in 0..30 {
|
for x in 0..30 {
|
||||||
|
@ -15,12 +14,7 @@ pub fn display_logo(map: &mut RegularMap, vram: &mut VRamManager) {
|
||||||
let palette_entry = agb_logo::test_logo.palette_assignments[tile_id as usize];
|
let palette_entry = agb_logo::test_logo.palette_assignments[tile_id as usize];
|
||||||
let tile_setting = TileSetting::new(tile_id, false, false, palette_entry);
|
let tile_setting = TileSetting::new(tile_id, false, false, palette_entry);
|
||||||
|
|
||||||
map.set_tile(
|
map.set_tile(vram, (x, y).into(), &background_tilemap, tile_setting);
|
||||||
vram,
|
|
||||||
(x, y).into(),
|
|
||||||
background_tilemap_reference,
|
|
||||||
tile_setting,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
use super::{MapLoan, RegularMap, TileSetReference, TileSetting, VRamManager};
|
use super::{MapLoan, RegularMap, TileSet, TileSetting, VRamManager};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
display,
|
display,
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
|
|
||||||
pub struct InfiniteScrolledMap<'a> {
|
pub struct InfiniteScrolledMap<'a> {
|
||||||
map: MapLoan<'a, RegularMap>,
|
map: MapLoan<'a, RegularMap>,
|
||||||
tile: Box<dyn Fn(Vector2D<i32>) -> (TileSetReference, TileSetting)>,
|
tile: Box<dyn Fn(Vector2D<i32>) -> (&'a TileSet<'a>, TileSetting) + 'a>,
|
||||||
|
|
||||||
current_pos: Vector2D<i32>,
|
current_pos: Vector2D<i32>,
|
||||||
offset: Vector2D<i32>,
|
offset: Vector2D<i32>,
|
||||||
|
@ -26,7 +26,7 @@ pub enum PartialUpdateStatus {
|
||||||
impl<'a> InfiniteScrolledMap<'a> {
|
impl<'a> InfiniteScrolledMap<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
map: MapLoan<'a, RegularMap>,
|
map: MapLoan<'a, RegularMap>,
|
||||||
tile: Box<dyn Fn(Vector2D<i32>) -> (TileSetReference, TileSetting)>,
|
tile: Box<dyn Fn(Vector2D<i32>) -> (&'a TileSet<'a>, TileSetting) + 'a>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map,
|
map,
|
||||||
|
@ -79,12 +79,12 @@ impl<'a> InfiniteScrolledMap<'a> {
|
||||||
{
|
{
|
||||||
for (x_idx, x) in (x_start..x_end).enumerate() {
|
for (x_idx, x) in (x_start..x_end).enumerate() {
|
||||||
let pos = (x, y).into();
|
let pos = (x, y).into();
|
||||||
let (tile_set_ref, tile_setting) = (self.tile)(pos);
|
let (tileset, tile_setting) = (self.tile)(pos);
|
||||||
|
|
||||||
self.map.set_tile(
|
self.map.set_tile(
|
||||||
vram,
|
vram,
|
||||||
(x_idx as u16, (y_idx + copy_from as usize) as u16).into(),
|
(x_idx as u16, (y_idx + copy_from as usize) as u16).into(),
|
||||||
tile_set_ref,
|
tileset,
|
||||||
tile_setting,
|
tile_setting,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ impl<'a> InfiniteScrolledMap<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.chain(horizontal_rect_to_update.iter())
|
.chain(horizontal_rect_to_update.iter())
|
||||||
{
|
{
|
||||||
let (tile_set_ref, tile_setting) = (self.tile)((tile_x, tile_y).into());
|
let (tileset, tile_setting) = (self.tile)((tile_x, tile_y).into());
|
||||||
|
|
||||||
self.map.set_tile(
|
self.map.set_tile(
|
||||||
vram,
|
vram,
|
||||||
|
@ -181,7 +181,7 @@ impl<'a> InfiniteScrolledMap<'a> {
|
||||||
(tile_y - self.offset.y).rem_euclid(32) as u16,
|
(tile_y - self.offset.y).rem_euclid(32) as u16,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
tile_set_ref,
|
tileset,
|
||||||
tile_setting,
|
tile_setting,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::dma::dma_copy16;
|
||||||
use crate::fixnum::Vector2D;
|
use crate::fixnum::Vector2D;
|
||||||
use crate::memory_mapped::MemoryMapped;
|
use crate::memory_mapped::MemoryMapped;
|
||||||
|
|
||||||
use super::{Tile, TileSetReference, TileSetting, VRamManager};
|
use super::{Tile, TileSet, TileSetting, VRamManager};
|
||||||
|
|
||||||
pub struct RegularMap {
|
pub struct RegularMap {
|
||||||
background_id: u8,
|
background_id: u8,
|
||||||
|
@ -42,7 +42,7 @@ impl RegularMap {
|
||||||
&mut self,
|
&mut self,
|
||||||
vram: &mut VRamManager,
|
vram: &mut VRamManager,
|
||||||
pos: Vector2D<u16>,
|
pos: Vector2D<u16>,
|
||||||
tileset_ref: TileSetReference,
|
tileset: &TileSet<'_>,
|
||||||
tile_setting: TileSetting,
|
tile_setting: TileSetting,
|
||||||
) {
|
) {
|
||||||
let pos = (pos.x + pos.y * 32) as usize;
|
let pos = (pos.x + pos.y * 32) as usize;
|
||||||
|
@ -55,7 +55,7 @@ impl RegularMap {
|
||||||
let tile_index = tile_setting.index();
|
let tile_index = tile_setting.index();
|
||||||
|
|
||||||
let new_tile = if tile_index != TRANSPARENT_TILE_INDEX {
|
let new_tile = if tile_index != TRANSPARENT_TILE_INDEX {
|
||||||
let new_tile_idx = vram.add_tile(tileset_ref, tile_index);
|
let new_tile_idx = vram.add_tile(tileset, tile_index);
|
||||||
Tile::new(new_tile_idx, tile_setting)
|
Tile::new(new_tile_idx, tile_setting)
|
||||||
} else {
|
} else {
|
||||||
Tile::default()
|
Tile::default()
|
||||||
|
|
|
@ -6,7 +6,7 @@ mod vram_manager;
|
||||||
pub use infinite_scrolled_map::{InfiniteScrolledMap, PartialUpdateStatus};
|
pub use infinite_scrolled_map::{InfiniteScrolledMap, PartialUpdateStatus};
|
||||||
pub use map::{MapLoan, RegularMap};
|
pub use map::{MapLoan, RegularMap};
|
||||||
pub use tiled0::Tiled0;
|
pub use tiled0::Tiled0;
|
||||||
pub use vram_manager::{TileFormat, TileIndex, TileSet, TileSetReference, VRamManager};
|
pub use vram_manager::{TileFormat, TileIndex, TileSet, VRamManager};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
|
|
@ -24,18 +24,6 @@ static TILE_ALLOCATOR: BlockAllocator = unsafe {
|
||||||
|
|
||||||
const TILE_LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(8 * 8 / 2, 8 * 8 / 2) };
|
const TILE_LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(8 * 8 / 2, 8 * 8 / 2) };
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
unsafe fn debug_unreachable_unchecked(message: &'static str) -> ! {
|
|
||||||
unreachable!("{}", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
const unsafe fn debug_unreachable_unchecked(_message: &'static str) -> ! {
|
|
||||||
use core::hint::unreachable_unchecked;
|
|
||||||
|
|
||||||
unreachable_unchecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum TileFormat {
|
pub enum TileFormat {
|
||||||
FourBpp,
|
FourBpp,
|
||||||
|
@ -59,17 +47,9 @@ impl<'a> TileSet<'a> {
|
||||||
pub fn new(tiles: &'a [u8], format: TileFormat) -> Self {
|
pub fn new(tiles: &'a [u8], format: TileFormat) -> Self {
|
||||||
Self { tiles, format }
|
Self { tiles, format }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
fn reference(&self) -> NonNull<[u8]> {
|
||||||
pub struct TileSetReference {
|
self.tiles.into()
|
||||||
id: u16,
|
|
||||||
generation: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TileSetReference {
|
|
||||||
fn new(id: u16, generation: u16) -> Self {
|
|
||||||
Self { id, generation }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,81 +69,68 @@ impl TileIndex {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
struct TileReference(NonNull<u32>);
|
struct TileReference(NonNull<u32>);
|
||||||
|
|
||||||
enum ArenaStorageItem<T> {
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
EndOfFreeList,
|
struct TileInTileSetReference {
|
||||||
NextFree(usize),
|
tileset: NonNull<[u8]>,
|
||||||
Data(T, u16),
|
tile: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VRamManager<'a> {
|
impl TileInTileSetReference {
|
||||||
tilesets: Vec<ArenaStorageItem<TileSet<'a>>>,
|
fn new(tileset: &'_ TileSet<'_>, tile: u16) -> Self {
|
||||||
generation: u16,
|
|
||||||
free_pointer: Option<usize>,
|
|
||||||
|
|
||||||
tile_set_to_vram: HashMap<(u16, u16), TileReference>,
|
|
||||||
reference_counts: Vec<(u16, Option<(TileSetReference, u16)>)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> VRamManager<'a> {
|
|
||||||
pub(crate) fn new() -> Self {
|
|
||||||
let tile_set_to_vram: HashMap<(u16, u16), TileReference> = HashMap::with_capacity(256);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
tilesets: Vec::new(),
|
tileset: tileset.reference(),
|
||||||
generation: 0,
|
tile,
|
||||||
free_pointer: None,
|
}
|
||||||
|
|
||||||
tile_set_to_vram,
|
|
||||||
reference_counts: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_tileset(&mut self, tileset: TileSet<'a>) -> TileSetReference {
|
#[derive(Clone, Default)]
|
||||||
let generation = self.generation;
|
struct TileReferenceCount {
|
||||||
self.generation = self.generation.wrapping_add(1);
|
reference_count: u16,
|
||||||
|
tile_in_tile_set: Option<TileInTileSetReference>,
|
||||||
let tileset = ArenaStorageItem::Data(tileset, generation);
|
|
||||||
|
|
||||||
let index = if let Some(ptr) = self.free_pointer.take() {
|
|
||||||
match self.tilesets[ptr] {
|
|
||||||
ArenaStorageItem::EndOfFreeList => {
|
|
||||||
self.tilesets[ptr] = tileset;
|
|
||||||
ptr
|
|
||||||
}
|
|
||||||
ArenaStorageItem::NextFree(next_free) => {
|
|
||||||
self.free_pointer = Some(next_free);
|
|
||||||
self.tilesets[ptr] = tileset;
|
|
||||||
ptr
|
|
||||||
}
|
|
||||||
_ => unsafe { debug_unreachable_unchecked("Free pointer cannot point to data") },
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.tilesets.push(tileset);
|
|
||||||
self.tilesets.len() - 1
|
|
||||||
};
|
|
||||||
|
|
||||||
TileSetReference::new(index as u16, generation)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_tileset(&mut self, tile_set_ref: TileSetReference) {
|
impl TileReferenceCount {
|
||||||
let tileset = &self.tilesets[tile_set_ref.id as usize];
|
fn new(tile_in_tile_set: TileInTileSetReference) -> Self {
|
||||||
|
Self {
|
||||||
|
reference_count: 1,
|
||||||
|
tile_in_tile_set: Some(tile_in_tile_set),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match tileset {
|
fn increment_reference_count(&mut self) {
|
||||||
ArenaStorageItem::Data(_, generation) => {
|
self.reference_count += 1;
|
||||||
debug_assert_eq!(
|
}
|
||||||
*generation, tile_set_ref.generation,
|
|
||||||
"Tileset generation must be the same when removing"
|
fn decrement_reference_count(&mut self) -> u16 {
|
||||||
|
assert!(
|
||||||
|
self.reference_count > 0,
|
||||||
|
"Trying to decrease the reference count below 0",
|
||||||
);
|
);
|
||||||
|
|
||||||
self.tilesets[tile_set_ref.id as usize] = if let Some(ptr) = self.free_pointer {
|
self.reference_count -= 1;
|
||||||
ArenaStorageItem::NextFree(ptr)
|
self.reference_count
|
||||||
} else {
|
|
||||||
ArenaStorageItem::EndOfFreeList
|
|
||||||
};
|
|
||||||
|
|
||||||
self.free_pointer = Some(tile_set_ref.id as usize);
|
|
||||||
}
|
}
|
||||||
_ => panic!("Must remove valid tileset"),
|
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.reference_count = 0;
|
||||||
|
self.tile_in_tile_set = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct VRamManager {
|
||||||
|
tile_set_to_vram: HashMap<TileInTileSetReference, TileReference>,
|
||||||
|
reference_counts: Vec<TileReferenceCount>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VRamManager {
|
||||||
|
pub(crate) fn new() -> Self {
|
||||||
|
let tile_set_to_vram: HashMap<TileInTileSetReference, TileReference> =
|
||||||
|
HashMap::with_capacity(256);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
tile_set_to_vram,
|
||||||
|
reference_counts: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,12 +144,14 @@ impl<'a> VRamManager<'a> {
|
||||||
TileReference(NonNull::new(ptr as *mut _).unwrap())
|
TileReference(NonNull::new(ptr as *mut _).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_tile(&mut self, tile_set_ref: TileSetReference, tile: u16) -> TileIndex {
|
pub(crate) fn add_tile(&mut self, tile_set: &TileSet<'_>, tile: u16) -> TileIndex {
|
||||||
let reference = self.tile_set_to_vram.get(&(tile_set_ref.id, tile));
|
let reference = self
|
||||||
|
.tile_set_to_vram
|
||||||
|
.get(&TileInTileSetReference::new(tile_set, tile));
|
||||||
|
|
||||||
if let Some(reference) = reference {
|
if let Some(reference) = reference {
|
||||||
let index = Self::index_from_reference(*reference);
|
let index = Self::index_from_reference(*reference);
|
||||||
self.reference_counts[index].0 += 1;
|
self.reference_counts[index].increment_reference_count();
|
||||||
return TileIndex::new(index);
|
return TileIndex::new(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,32 +159,30 @@ impl<'a> VRamManager<'a> {
|
||||||
unsafe { TILE_ALLOCATOR.alloc(TILE_LAYOUT) }.unwrap().cast();
|
unsafe { TILE_ALLOCATOR.alloc(TILE_LAYOUT) }.unwrap().cast();
|
||||||
let tile_reference = TileReference(new_reference);
|
let tile_reference = TileReference(new_reference);
|
||||||
|
|
||||||
self.copy_tile_to_location(tile_set_ref, tile, tile_reference);
|
self.copy_tile_to_location(tile_set, 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
|
||||||
.insert((tile_set_ref.id, tile), tile_reference);
|
.insert(TileInTileSetReference::new(tile_set, tile), tile_reference);
|
||||||
|
|
||||||
self.reference_counts
|
self.reference_counts.resize(
|
||||||
.resize(self.reference_counts.len().max(index + 1), (0, None));
|
self.reference_counts.len().max(index + 1),
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
|
|
||||||
self.reference_counts[index] = (1, Some((tile_set_ref, tile)));
|
self.reference_counts[index] =
|
||||||
|
TileReferenceCount::new(TileInTileSetReference::new(tile_set, tile));
|
||||||
|
|
||||||
TileIndex::new(index)
|
TileIndex::new(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn remove_tile(&mut self, tile_index: TileIndex) {
|
pub(crate) fn remove_tile(&mut self, tile_index: TileIndex) {
|
||||||
let index = tile_index.index() as usize;
|
let index = tile_index.index() as usize;
|
||||||
assert!(
|
|
||||||
self.reference_counts[index].0 > 0,
|
|
||||||
"Trying to decrease the reference count of {} below 0",
|
|
||||||
index
|
|
||||||
);
|
|
||||||
|
|
||||||
self.reference_counts[index].0 -= 1;
|
let new_reference_count = self.reference_counts[index].decrement_reference_count();
|
||||||
|
|
||||||
if self.reference_counts[index].0 != 0 {
|
if new_reference_count != 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,45 +191,39 @@ impl<'a> VRamManager<'a> {
|
||||||
TILE_ALLOCATOR.dealloc_no_normalise(tile_reference.0.cast().as_ptr(), TILE_LAYOUT);
|
TILE_ALLOCATOR.dealloc_no_normalise(tile_reference.0.cast().as_ptr(), TILE_LAYOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tile_ref = self.reference_counts[index].1.unwrap();
|
let tile_ref = self.reference_counts[index]
|
||||||
self.tile_set_to_vram.remove(&(tile_ref.0.id, tile_ref.1));
|
.tile_in_tile_set
|
||||||
self.reference_counts[index].1 = None;
|
.as_ref()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
self.tile_set_to_vram.remove(tile_ref);
|
||||||
|
self.reference_counts[index].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace_tile(
|
pub fn replace_tile(
|
||||||
&mut self,
|
&mut self,
|
||||||
source_tile_set_ref: TileSetReference,
|
source_tile_set: &TileSet<'_>,
|
||||||
source_tile: u16,
|
source_tile: u16,
|
||||||
target_tile_set_ref: TileSetReference,
|
target_tile_set: &TileSet<'_>,
|
||||||
target_tile: u16,
|
target_tile: u16,
|
||||||
) {
|
) {
|
||||||
if let Some(&reference) = self
|
if let Some(&reference) = self
|
||||||
.tile_set_to_vram
|
.tile_set_to_vram
|
||||||
.get(&(source_tile_set_ref.id, source_tile))
|
.get(&TileInTileSetReference::new(source_tile_set, source_tile))
|
||||||
{
|
{
|
||||||
self.copy_tile_to_location(target_tile_set_ref, target_tile, reference);
|
self.copy_tile_to_location(target_tile_set, target_tile, reference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_tile_to_location(
|
fn copy_tile_to_location(
|
||||||
&self,
|
&self,
|
||||||
tile_set_ref: TileSetReference,
|
tile_set: &TileSet<'_>,
|
||||||
tile_id: u16,
|
tile_id: u16,
|
||||||
tile_reference: TileReference,
|
tile_reference: TileReference,
|
||||||
) {
|
) {
|
||||||
let tile_slice = if let ArenaStorageItem::Data(data, generation) =
|
let tile_size = tile_set.format.tile_size();
|
||||||
&self.tilesets[tile_set_ref.id as usize]
|
let tile_offset = (tile_id as usize) * tile_size;
|
||||||
{
|
let tile_slice = &tile_set.tiles[tile_offset..(tile_offset + tile_size)];
|
||||||
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 tile_size_in_half_words = tile_slice.len() / 2;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ impl Video {
|
||||||
unsafe { Bitmap4::new() }
|
unsafe { Bitmap4::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tiled0(&mut self) -> (Tiled0, VRamManager<'_>) {
|
pub fn tiled0(&mut self) -> (Tiled0, VRamManager) {
|
||||||
(unsafe { Tiled0::new() }, VRamManager::new())
|
(unsafe { Tiled0::new() }, VRamManager::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use agb::display::{
|
use agb::display::{
|
||||||
tiled::{RegularMap, TileSetReference, TileSetting, VRamManager},
|
tiled::{RegularMap, TileSet, TileSetting, VRamManager},
|
||||||
HEIGHT, WIDTH,
|
HEIGHT, WIDTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ pub fn write_level(
|
||||||
map: &mut RegularMap,
|
map: &mut RegularMap,
|
||||||
world: u32,
|
world: u32,
|
||||||
level: u32,
|
level: u32,
|
||||||
tile_set_ref: TileSetReference,
|
tileset: &'_ TileSet<'_>,
|
||||||
vram: &mut VRamManager,
|
vram: &mut VRamManager,
|
||||||
) {
|
) {
|
||||||
for (i, &tile) in [
|
for (i, &tile) in [
|
||||||
|
@ -30,7 +30,7 @@ pub fn write_level(
|
||||||
map.set_tile(
|
map.set_tile(
|
||||||
vram,
|
vram,
|
||||||
(i as u16, 0).into(),
|
(i as u16, 0).into(),
|
||||||
tile_set_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(tile),
|
TileSetting::from_raw(tile),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -783,17 +783,14 @@ fn main(mut agb: agb::Gba) -> ! {
|
||||||
let mut splash_screen = tiled.background(Priority::P0);
|
let mut splash_screen = tiled.background(Priority::P0);
|
||||||
let mut world_display = tiled.background(Priority::P0);
|
let mut world_display = tiled.background(Priority::P0);
|
||||||
|
|
||||||
let tile_set_ref = vram.add_tileset(TileSet::new(
|
let tileset = TileSet::new(tile_sheet::background.tiles, TileFormat::FourBpp);
|
||||||
tile_sheet::background.tiles,
|
|
||||||
TileFormat::FourBpp,
|
|
||||||
));
|
|
||||||
|
|
||||||
for y in 0..32u16 {
|
for y in 0..32u16 {
|
||||||
for x in 0..32u16 {
|
for x in 0..32u16 {
|
||||||
world_display.set_tile(
|
world_display.set_tile(
|
||||||
&mut vram,
|
&mut vram,
|
||||||
(x, y).into(),
|
(x, y).into(),
|
||||||
tile_set_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(level_display::BLANK),
|
TileSetting::from_raw(level_display::BLANK),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -837,7 +834,7 @@ fn main(mut agb: agb::Gba) -> ! {
|
||||||
&mut world_display,
|
&mut world_display,
|
||||||
current_level / 8 + 1,
|
current_level / 8 + 1,
|
||||||
current_level % 8 + 1,
|
current_level % 8 + 1,
|
||||||
tile_set_ref,
|
&tileset,
|
||||||
&mut vram,
|
&mut vram,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -849,12 +846,13 @@ fn main(mut agb: agb::Gba) -> ! {
|
||||||
vblank.wait_for_vblank();
|
vblank.wait_for_vblank();
|
||||||
mixer.after_vblank();
|
mixer.after_vblank();
|
||||||
|
|
||||||
|
let map_current_level = current_level;
|
||||||
let mut background = InfiniteScrolledMap::new(
|
let mut background = InfiniteScrolledMap::new(
|
||||||
tiled.background(Priority::P2),
|
tiled.background(Priority::P2),
|
||||||
Box::new(move |pos: Vector2D<i32>| {
|
Box::new(|pos: Vector2D<i32>| {
|
||||||
let level = &map_tiles::LEVELS[current_level as usize];
|
let level = &map_tiles::LEVELS[map_current_level as usize];
|
||||||
(
|
(
|
||||||
tile_set_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(
|
TileSetting::from_raw(
|
||||||
*level
|
*level
|
||||||
.background
|
.background
|
||||||
|
@ -866,10 +864,10 @@ fn main(mut agb: agb::Gba) -> ! {
|
||||||
);
|
);
|
||||||
let mut foreground = InfiniteScrolledMap::new(
|
let mut foreground = InfiniteScrolledMap::new(
|
||||||
tiled.background(Priority::P0),
|
tiled.background(Priority::P0),
|
||||||
Box::new(move |pos: Vector2D<i32>| {
|
Box::new(|pos: Vector2D<i32>| {
|
||||||
let level = &map_tiles::LEVELS[current_level as usize];
|
let level = &map_tiles::LEVELS[map_current_level as usize];
|
||||||
(
|
(
|
||||||
tile_set_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(
|
TileSetting::from_raw(
|
||||||
*level
|
*level
|
||||||
.foreground
|
.foreground
|
||||||
|
|
|
@ -19,22 +19,19 @@ pub fn show_splash_screen(
|
||||||
vram: &mut VRamManager,
|
vram: &mut VRamManager,
|
||||||
) {
|
) {
|
||||||
map.set_scroll_pos((0u16, 0u16).into());
|
map.set_scroll_pos((0u16, 0u16).into());
|
||||||
let (tile_set_ref, palette) = match which {
|
let (tileset, palette) = match which {
|
||||||
SplashScreen::Start => {
|
SplashScreen::Start => {
|
||||||
let tile_set_ref = vram.add_tileset(TileSet::new(
|
let tileset = TileSet::new(splash_screens::splash.tiles, TileFormat::FourBpp);
|
||||||
splash_screens::splash.tiles,
|
|
||||||
TileFormat::FourBpp,
|
|
||||||
));
|
|
||||||
|
|
||||||
(tile_set_ref, splash_screens::splash.palettes)
|
(tileset, splash_screens::splash.palettes)
|
||||||
}
|
}
|
||||||
SplashScreen::End => {
|
SplashScreen::End => {
|
||||||
let tile_set_ref = vram.add_tileset(TileSet::new(
|
let tileset = TileSet::new(
|
||||||
splash_screens::thanks_for_playing.tiles,
|
splash_screens::thanks_for_playing.tiles,
|
||||||
TileFormat::FourBpp,
|
TileFormat::FourBpp,
|
||||||
));
|
);
|
||||||
|
|
||||||
(tile_set_ref, splash_screens::thanks_for_playing.palettes)
|
(tileset, splash_screens::thanks_for_playing.palettes)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +57,7 @@ pub fn show_splash_screen(
|
||||||
map.set_tile(
|
map.set_tile(
|
||||||
vram,
|
vram,
|
||||||
(x, y).into(),
|
(x, y).into(),
|
||||||
tile_set_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(y * 30 + x),
|
TileSetting::from_raw(y * 30 + x),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -108,6 +105,4 @@ pub fn show_splash_screen(
|
||||||
|
|
||||||
map.hide();
|
map.hide();
|
||||||
map.clear(vram);
|
map.clear(vram);
|
||||||
|
|
||||||
vram.remove_tileset(tile_set_ref);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2223,18 +2223,15 @@ fn game_with_level(gba: &mut agb::Gba) {
|
||||||
|
|
||||||
vram.set_background_palettes(background::background.palettes);
|
vram.set_background_palettes(background::background.palettes);
|
||||||
|
|
||||||
let tileset_ref = vram.add_tileset(TileSet::new(
|
let tileset = TileSet::new(background::background.tiles, TileFormat::FourBpp);
|
||||||
background::background.tiles,
|
|
||||||
TileFormat::FourBpp,
|
|
||||||
));
|
|
||||||
|
|
||||||
let object = gba.display.object.get();
|
let object = gba.display.object.get();
|
||||||
|
|
||||||
let backdrop = InfiniteScrolledMap::new(
|
let backdrop = InfiniteScrolledMap::new(
|
||||||
background.background(Priority::P2),
|
background.background(Priority::P2),
|
||||||
Box::new(move |pos| {
|
Box::new(|pos| {
|
||||||
(
|
(
|
||||||
tileset_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(
|
TileSetting::from_raw(
|
||||||
*tilemap::BACKGROUND_MAP
|
*tilemap::BACKGROUND_MAP
|
||||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||||
|
@ -2246,9 +2243,9 @@ fn game_with_level(gba: &mut agb::Gba) {
|
||||||
|
|
||||||
let foreground = InfiniteScrolledMap::new(
|
let foreground = InfiniteScrolledMap::new(
|
||||||
background.background(Priority::P0),
|
background.background(Priority::P0),
|
||||||
Box::new(move |pos| {
|
Box::new(|pos| {
|
||||||
(
|
(
|
||||||
tileset_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(
|
TileSetting::from_raw(
|
||||||
*tilemap::FOREGROUND_MAP
|
*tilemap::FOREGROUND_MAP
|
||||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||||
|
@ -2260,9 +2257,9 @@ fn game_with_level(gba: &mut agb::Gba) {
|
||||||
|
|
||||||
let clouds = InfiniteScrolledMap::new(
|
let clouds = InfiniteScrolledMap::new(
|
||||||
background.background(Priority::P3),
|
background.background(Priority::P3),
|
||||||
Box::new(move |pos| {
|
Box::new(|pos| {
|
||||||
(
|
(
|
||||||
tileset_ref,
|
&tileset,
|
||||||
TileSetting::from_raw(
|
TileSetting::from_raw(
|
||||||
*tilemap::CLOUD_MAP
|
*tilemap::CLOUD_MAP
|
||||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||||
|
|
Loading…
Reference in a new issue