mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 00:01:34 +11:00
Deduplicate background tiles (#477)
This started as an attempt to get dungeon puzzler in the combo rom, ended up fixing a _load_ of 256 colour bugs and the ability to deduplicate tiles you import. Fixes #448 - [x] Changelog updated / no changelog update needed
This commit is contained in:
commit
dc5bf9de98
|
@ -12,14 +12,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- New tracker for playing XM files (see the `agb-tracker` crate).
|
||||
- You can now declare where looping sound channels should restart.
|
||||
- Fixnums now have constructors from_f32 and from_f64. This is mainly useful if using agb-fixnum outside of the Game Boy Advance e.g. in build scripts or macros.
|
||||
- New option when loading a background to automatically deduplicate tiles.
|
||||
- Methods on tile_setting to toggle its hflip and vflip status.
|
||||
|
||||
### Changed
|
||||
|
||||
- Sound channel panning and volume options are now `Num<i16, 8>` rather than `Num<i16, 4>` for improved precision and sound quality.
|
||||
- Due to dependency changes, agb-gbafix is now released under MPL rather than GPL.
|
||||
- `include_background_gfx!` now produces tile settings directly rather than palette assigments.
|
||||
|
||||
### Fixed
|
||||
|
||||
- 256-colour backgrounds are better supported.
|
||||
- Mono looping samples will now correctly play to the end if it doesn't perfectly align with a buffer boundry and short samples now also loop correctly.
|
||||
|
||||
## [0.16.0] - 2023/07/18
|
||||
|
|
|
@ -11,4 +11,5 @@ pub(crate) trait Config {
|
|||
pub(crate) trait Image {
|
||||
fn filename(&self) -> String;
|
||||
fn colours(&self) -> Colours;
|
||||
fn deduplicate(&self) -> bool;
|
||||
}
|
||||
|
|
152
agb-image-converter/src/deduplicator.rs
Normal file
152
agb-image-converter/src/deduplicator.rs
Normal file
|
@ -0,0 +1,152 @@
|
|||
use std::{collections::HashMap, hash::BuildHasher};
|
||||
|
||||
use crate::{colour::Colour, image_loader::Image};
|
||||
|
||||
pub struct Transformation {
|
||||
pub vflip: bool,
|
||||
pub hflip: bool,
|
||||
}
|
||||
|
||||
impl Transformation {
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
vflip: false,
|
||||
hflip: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vflipped() -> Self {
|
||||
Self {
|
||||
vflip: true,
|
||||
hflip: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hflipped() -> Self {
|
||||
Self {
|
||||
vflip: false,
|
||||
hflip: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vhflipped() -> Self {
|
||||
Self {
|
||||
vflip: true,
|
||||
hflip: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DeduplicatedData {
|
||||
pub new_index: usize,
|
||||
pub transformation: Transformation,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
struct Tile {
|
||||
data: [Colour; 64],
|
||||
}
|
||||
|
||||
impl Tile {
|
||||
fn split_image(input: &Image) -> Vec<Self> {
|
||||
let mut ret = vec![];
|
||||
|
||||
for y in 0..(input.height / 8) {
|
||||
for x in 0..(input.width / 8) {
|
||||
let mut tile_data = Vec::with_capacity(64);
|
||||
|
||||
for j in 0..8 {
|
||||
for i in 0..8 {
|
||||
tile_data.push(input.colour(x * 8 + i, y * 8 + j));
|
||||
}
|
||||
}
|
||||
|
||||
ret.push(Tile {
|
||||
data: tile_data.try_into().unwrap(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
fn vflipped(&self) -> Self {
|
||||
let mut new_data = self.data;
|
||||
for y in 0..4 {
|
||||
for x in 0..8 {
|
||||
new_data.swap(y * 8 + x, (7 - y) * 8 + x);
|
||||
}
|
||||
}
|
||||
|
||||
Self { data: new_data }
|
||||
}
|
||||
|
||||
fn hflipped(&self) -> Self {
|
||||
let mut new_data = self.data;
|
||||
|
||||
for y in 0..8 {
|
||||
for x in 0..4 {
|
||||
new_data.swap(y * 8 + x, y * 8 + (7 - x));
|
||||
}
|
||||
}
|
||||
|
||||
Self { data: new_data }
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn deduplicate_image(input: &Image, can_flip: bool) -> (Image, Vec<DeduplicatedData>) {
|
||||
let mut resulting_tiles = vec![];
|
||||
let mut deduplication_data = vec![];
|
||||
|
||||
let all_tiles = Tile::split_image(input);
|
||||
let mut existing_tiles = HashMap::new();
|
||||
|
||||
let hasher = std::collections::hash_map::RandomState::new();
|
||||
|
||||
for tile in all_tiles {
|
||||
let (tile, transformation) = if can_flip {
|
||||
let vflipped = tile.vflipped();
|
||||
let hflipped = tile.hflipped();
|
||||
let vhflipped = vflipped.hflipped();
|
||||
|
||||
// find the one with the smallest hash
|
||||
let tile_hash = hasher.hash_one(&tile);
|
||||
let vflipped_hash = hasher.hash_one(&vflipped);
|
||||
let hflipped_hash = hasher.hash_one(&hflipped);
|
||||
let vhflipped_hash = hasher.hash_one(&vhflipped);
|
||||
|
||||
let minimum = tile_hash
|
||||
.min(vflipped_hash)
|
||||
.min(hflipped_hash)
|
||||
.min(vhflipped_hash);
|
||||
|
||||
if minimum == tile_hash {
|
||||
(tile, Transformation::none())
|
||||
} else if minimum == vflipped_hash {
|
||||
(vflipped, Transformation::vflipped())
|
||||
} else if minimum == hflipped_hash {
|
||||
(hflipped, Transformation::hflipped())
|
||||
} else {
|
||||
(vhflipped, Transformation::vhflipped())
|
||||
}
|
||||
} else {
|
||||
(tile, Transformation::none())
|
||||
};
|
||||
|
||||
let index = *existing_tiles.entry(tile.clone()).or_insert_with(|| {
|
||||
resulting_tiles.push(tile);
|
||||
resulting_tiles.len() - 1
|
||||
});
|
||||
|
||||
deduplication_data.push(DeduplicatedData {
|
||||
new_index: index,
|
||||
transformation,
|
||||
});
|
||||
}
|
||||
|
||||
let image_data = resulting_tiles
|
||||
.iter()
|
||||
.flat_map(|tile| tile.data)
|
||||
.collect::<Vec<_>>();
|
||||
(Image::from_colour_data(image_data), deduplication_data)
|
||||
}
|
|
@ -4,6 +4,7 @@ use image::{DynamicImage, GenericImageView};
|
|||
|
||||
use crate::colour::Colour;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Image {
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
|
@ -42,6 +43,14 @@ impl Image {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_colour_data(colour_data: Vec<Colour>) -> Self {
|
||||
Self {
|
||||
height: colour_data.len() / 8,
|
||||
colour_data,
|
||||
width: 8,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn colour(&self, x: usize, y: usize) -> Colour {
|
||||
self.colour_data[x + y * self.width]
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use quote::{format_ident, quote, ToTokens};
|
|||
mod aseprite;
|
||||
mod colour;
|
||||
mod config;
|
||||
mod deduplicator;
|
||||
mod font_loader;
|
||||
mod image_loader;
|
||||
mod palette16;
|
||||
|
@ -36,6 +37,7 @@ struct BackgroundGfxOption {
|
|||
module_name: String,
|
||||
file_name: String,
|
||||
colours: Colours,
|
||||
deduplicate: bool,
|
||||
}
|
||||
|
||||
impl config::Image for BackgroundGfxOption {
|
||||
|
@ -46,6 +48,10 @@ impl config::Image for BackgroundGfxOption {
|
|||
fn colours(&self) -> Colours {
|
||||
self.colours
|
||||
}
|
||||
|
||||
fn deduplicate(&self) -> bool {
|
||||
self.deduplicate
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for BackgroundGfxOption {
|
||||
|
@ -72,12 +78,30 @@ impl Parse for BackgroundGfxOption {
|
|||
Colours::Colours16
|
||||
};
|
||||
|
||||
let lookahead = input.lookahead1();
|
||||
|
||||
let deduplicate = if lookahead.peek(syn::Ident) {
|
||||
let deduplicate: syn::Ident = input.parse()?;
|
||||
|
||||
if deduplicate == "deduplicate" {
|
||||
true
|
||||
} else {
|
||||
return Err(syn::Error::new_spanned(
|
||||
deduplicate,
|
||||
"Must either be the literal deduplicate or missing",
|
||||
));
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let file_name: syn::LitStr = input.parse()?;
|
||||
|
||||
Ok(Self {
|
||||
module_name: module_name.to_string(),
|
||||
file_name: file_name.value(),
|
||||
colours,
|
||||
deduplicate,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -406,6 +430,7 @@ fn convert_image(
|
|||
) -> proc_macro2::TokenStream {
|
||||
let image_filename = &parent.join(settings.filename());
|
||||
let image = Image::load_from_file(image_filename);
|
||||
let deduplicate = settings.deduplicate();
|
||||
|
||||
rust_generator::generate_code(
|
||||
variable_name,
|
||||
|
@ -414,6 +439,7 @@ fn convert_image(
|
|||
&image_filename.to_string_lossy(),
|
||||
crate_prefix.to_owned(),
|
||||
assignment_offset,
|
||||
deduplicate,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -468,7 +494,14 @@ fn palette_tile_data(
|
|||
let mut tile_data = Vec::new();
|
||||
|
||||
for (image_idx, image) in images.iter().enumerate() {
|
||||
add_image_to_tile_data(&mut tile_data, image, optimiser, image_idx, true)
|
||||
add_image_to_tile_data(
|
||||
&mut tile_data,
|
||||
image,
|
||||
optimiser,
|
||||
image_idx,
|
||||
true,
|
||||
&(0..images.len()).collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
let tile_data = collapse_to_4bpp(&tile_data);
|
||||
|
@ -491,6 +524,7 @@ fn add_image_to_tile_data(
|
|||
optimiser: &Palette16OptimisationResults,
|
||||
assignment_offset: usize,
|
||||
is_sprite: bool,
|
||||
remap_index: &[usize],
|
||||
) {
|
||||
let tile_size = 8;
|
||||
let tiles_x = image.width / tile_size;
|
||||
|
@ -501,7 +535,7 @@ fn add_image_to_tile_data(
|
|||
let assignment = if is_sprite {
|
||||
assignment_offset
|
||||
} else {
|
||||
y * tiles_x + x + assignment_offset
|
||||
remap_index[y * tiles_x + x] + assignment_offset
|
||||
};
|
||||
|
||||
let palette_index = optimiser.assignments[assignment];
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::deduplicator::{DeduplicatedData, Transformation};
|
||||
use crate::palette16::Palette16OptimisationResults;
|
||||
use crate::{add_image_256_to_tile_data, add_image_to_tile_data, collapse_to_4bpp};
|
||||
use crate::{image_loader::Image, ByteString};
|
||||
|
@ -5,6 +6,7 @@ use crate::{image_loader::Image, ByteString};
|
|||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::iter;
|
||||
|
||||
pub(crate) fn generate_palette_code(
|
||||
|
@ -40,36 +42,77 @@ pub(crate) fn generate_code(
|
|||
image_filename: &str,
|
||||
crate_prefix: String,
|
||||
assignment_offset: Option<usize>,
|
||||
deduplicate: bool,
|
||||
) -> TokenStream {
|
||||
let crate_prefix = format_ident!("{}", crate_prefix);
|
||||
let output_variable_name = format_ident!("{}", output_variable_name);
|
||||
|
||||
let (image, dedup_data) = if deduplicate {
|
||||
let (new_image, dedup_data) =
|
||||
crate::deduplicator::deduplicate_image(image, assignment_offset.is_some());
|
||||
|
||||
(new_image, dedup_data)
|
||||
} else {
|
||||
(
|
||||
image.clone(),
|
||||
(0..(image.width * image.height / 8 / 8))
|
||||
.map(|i| DeduplicatedData {
|
||||
new_index: i,
|
||||
transformation: Transformation::none(),
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
};
|
||||
|
||||
let remap_index = dedup_data
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, data)| (data.new_index, i))
|
||||
.collect::<BTreeMap<_, _>>(); // BTreeMap so that values below is in order
|
||||
|
||||
let remap_index = remap_index.values().cloned().collect::<Vec<_>>();
|
||||
|
||||
let (tile_data, assignments) = if let Some(assignment_offset) = assignment_offset {
|
||||
let mut tile_data = Vec::new();
|
||||
|
||||
add_image_to_tile_data(&mut tile_data, image, results, assignment_offset, false);
|
||||
add_image_to_tile_data(
|
||||
&mut tile_data,
|
||||
&image,
|
||||
results,
|
||||
assignment_offset,
|
||||
false,
|
||||
&remap_index,
|
||||
);
|
||||
|
||||
let tile_data = collapse_to_4bpp(&tile_data);
|
||||
|
||||
let num_tiles = image.width * image.height / 8usize.pow(2);
|
||||
|
||||
let assignments = results
|
||||
.assignments
|
||||
.iter()
|
||||
.skip(assignment_offset)
|
||||
.take(num_tiles)
|
||||
.map(|&x| x as u8)
|
||||
let all_assignments = &results.assignments[assignment_offset..];
|
||||
let assignments = (0..num_tiles)
|
||||
.map(|tile_id| all_assignments[remap_index[tile_id]] as u8)
|
||||
.collect();
|
||||
|
||||
(tile_data, assignments)
|
||||
} else {
|
||||
let mut tile_data = Vec::new();
|
||||
|
||||
add_image_256_to_tile_data(&mut tile_data, image, results);
|
||||
add_image_256_to_tile_data(&mut tile_data, &image, results);
|
||||
|
||||
(tile_data, vec![])
|
||||
};
|
||||
|
||||
let tile_settings = dedup_data.iter().map(|data| {
|
||||
let palette_assignment = assignments.get(data.new_index).unwrap_or(&0);
|
||||
let vflipped = data.transformation.vflip;
|
||||
let hflipped = data.transformation.hflip;
|
||||
let index = data.new_index as u16;
|
||||
|
||||
quote! {
|
||||
#crate_prefix::display::tiled::TileSetting::new(#index, #hflipped, #vflipped, #palette_assignment)
|
||||
}
|
||||
});
|
||||
|
||||
let data = ByteString(&tile_data);
|
||||
|
||||
quote! {
|
||||
|
@ -91,11 +134,11 @@ pub(crate) fn generate_code(
|
|||
&ALIGNED.bytes
|
||||
};
|
||||
|
||||
const PALETTE_ASSIGNMENT: &[u8] = &[
|
||||
#(#assignments),*
|
||||
const TILE_SETTINGS: &[#crate_prefix::display::tiled::TileSetting] = &[
|
||||
#(#tile_settings),*
|
||||
];
|
||||
|
||||
#crate_prefix::display::tile_data::TileData::new(TILE_DATA, PALETTE_ASSIGNMENT)
|
||||
#crate_prefix::display::tile_data::TileData::new(TILE_DATA, TILE_SETTINGS)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use agb::{
|
||||
display::{
|
||||
tiled::{RegularBackgroundSize, TileFormat, TileSet, TileSetting, TiledMap},
|
||||
tiled::{RegularBackgroundSize, TileFormat, TileSet, TiledMap},
|
||||
Priority,
|
||||
},
|
||||
include_background_gfx,
|
||||
|
@ -32,7 +32,7 @@ fn main(mut gba: agb::Gba) -> ! {
|
|||
&mut vram,
|
||||
(x, y).into(),
|
||||
&tileset,
|
||||
TileSetting::new(0, false, false, 0),
|
||||
water_tiles::water_tiles.tile_settings[0],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::tiled::{RegularMap, TileFormat, TileSet, TileSetting, TiledMap, VRamManager};
|
||||
use super::tiled::{RegularMap, TileFormat, TileSet, TiledMap, VRamManager};
|
||||
|
||||
crate::include_background_gfx!(crate, agb_logo, test_logo => "gfx/test_logo.png");
|
||||
crate::include_background_gfx!(crate, agb_logo, test_logo => deduplicate "gfx/test_logo.png");
|
||||
|
||||
pub fn display_logo(map: &mut RegularMap, vram: &mut VRamManager) {
|
||||
vram.set_background_palettes(agb_logo::PALETTES);
|
||||
|
@ -11,10 +11,12 @@ pub fn display_logo(map: &mut RegularMap, vram: &mut VRamManager) {
|
|||
for x in 0..30 {
|
||||
let tile_id = y * 30 + x;
|
||||
|
||||
let palette_entry = agb_logo::test_logo.palette_assignments[tile_id as usize];
|
||||
let tile_setting = TileSetting::new(tile_id, false, false, palette_entry);
|
||||
|
||||
map.set_tile(vram, (x, y).into(), &background_tilemap, tile_setting);
|
||||
map.set_tile(
|
||||
vram,
|
||||
(x as u16, y as u16).into(),
|
||||
&background_tilemap,
|
||||
agb_logo::test_logo.tile_settings[tile_id],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
use super::tiled::TileSetting;
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct TileData {
|
||||
pub tiles: &'static [u8],
|
||||
pub palette_assignments: &'static [u8],
|
||||
pub tile_settings: &'static [TileSetting],
|
||||
}
|
||||
|
||||
impl TileData {
|
||||
#[must_use]
|
||||
pub const fn new(tiles: &'static [u8], palette_assignments: &'static [u8]) -> Self {
|
||||
pub const fn new(tiles: &'static [u8], tile_settings: &'static [TileSetting]) -> Self {
|
||||
TileData {
|
||||
tiles,
|
||||
palette_assignments,
|
||||
tile_settings,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::memory_mapped::MemoryMapped;
|
|||
|
||||
use super::{
|
||||
AffineBackgroundSize, BackgroundID, BackgroundSize, BackgroundSizePrivate,
|
||||
RegularBackgroundSize, Tile, TileFormat, TileIndex, TileSet, TileSetting, VRamManager,
|
||||
RegularBackgroundSize, Tile, TileFormat, TileSet, TileSetting, VRamManager,
|
||||
};
|
||||
|
||||
use alloc::{vec, vec::Vec};
|
||||
|
@ -20,10 +20,9 @@ pub trait TiledMapTypes: private::Sealed {
|
|||
}
|
||||
|
||||
trait TiledMapPrivate: TiledMapTypes {
|
||||
type TileType: Into<TileIndex> + Copy + Default + Eq + PartialEq;
|
||||
type AffineMatrix;
|
||||
|
||||
fn tiles_mut(&mut self) -> &mut [Self::TileType];
|
||||
fn tiles_mut(&mut self) -> &mut [Tile];
|
||||
fn tiles_dirty(&mut self) -> &mut bool;
|
||||
|
||||
fn colours(&self) -> TileFormat;
|
||||
|
@ -59,9 +58,11 @@ where
|
|||
T::Size: BackgroundSizePrivate,
|
||||
{
|
||||
fn clear(&mut self, vram: &mut VRamManager) {
|
||||
let colours = self.colours();
|
||||
|
||||
for tile in self.tiles_mut() {
|
||||
if *tile != Default::default() {
|
||||
vram.remove_tile((*tile).into());
|
||||
vram.remove_tile(tile.tile_index(colours));
|
||||
}
|
||||
|
||||
*tile = Default::default();
|
||||
|
@ -82,18 +83,18 @@ where
|
|||
|
||||
fn commit(&mut self, vram: &mut VRamManager) {
|
||||
let screenblock_memory = self.screenblock_memory();
|
||||
let tile_count_divisor = self.colours().tile_size() / TileFormat::FourBpp.tile_size();
|
||||
|
||||
if *self.tiles_dirty() {
|
||||
unsafe {
|
||||
dma_copy16(
|
||||
self.tiles_mut().as_ptr() as *const u16,
|
||||
screenblock_memory,
|
||||
self.map_size().num_tiles() / tile_count_divisor,
|
||||
self.map_size().num_tiles(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let tile_colour_flag: u16 = (tile_count_divisor == 2).into();
|
||||
let tile_colour_flag: u16 = (self.colours() == TileFormat::EightBpp).into();
|
||||
|
||||
let new_bg_control_value = (self.priority() as u16)
|
||||
| ((self.screenblock() as u16) << 8)
|
||||
|
@ -134,10 +135,9 @@ impl TiledMapTypes for RegularMap {
|
|||
}
|
||||
|
||||
impl TiledMapPrivate for RegularMap {
|
||||
type TileType = Tile;
|
||||
type AffineMatrix = ();
|
||||
|
||||
fn tiles_mut(&mut self) -> &mut [Self::TileType] {
|
||||
fn tiles_mut(&mut self) -> &mut [Tile] {
|
||||
&mut self.tiles
|
||||
}
|
||||
fn tiles_dirty(&mut self) -> &mut bool {
|
||||
|
@ -195,11 +195,12 @@ impl RegularMap {
|
|||
tileset: &TileSet<'_>,
|
||||
tile_setting: TileSetting,
|
||||
) {
|
||||
if tileset.format() != self.colours() {
|
||||
let colours = self.colours();
|
||||
if tileset.format() != colours {
|
||||
panic!(
|
||||
"Cannot set a {:?} colour tile on a {:?} colour background",
|
||||
tileset.format(),
|
||||
self.colours()
|
||||
colours
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -207,7 +208,7 @@ impl RegularMap {
|
|||
|
||||
let old_tile = self.tiles_mut()[pos];
|
||||
if old_tile != Tile::default() {
|
||||
vram.remove_tile(old_tile.into());
|
||||
vram.remove_tile(old_tile.tile_index(colours));
|
||||
}
|
||||
|
||||
let tile_index = tile_setting.index();
|
||||
|
@ -254,7 +255,7 @@ pub struct AffineMap {
|
|||
|
||||
transform: AffineMatrixBackground,
|
||||
|
||||
tiles: Vec<u8>,
|
||||
tiles: Vec<Tile>,
|
||||
tiles_dirty: bool,
|
||||
}
|
||||
|
||||
|
@ -263,10 +264,9 @@ impl TiledMapTypes for AffineMap {
|
|||
}
|
||||
|
||||
impl TiledMapPrivate for AffineMap {
|
||||
type TileType = u8;
|
||||
type AffineMatrix = AffineMatrixBackground;
|
||||
|
||||
fn tiles_mut(&mut self) -> &mut [Self::TileType] {
|
||||
fn tiles_mut(&mut self) -> &mut [Tile] {
|
||||
&mut self.tiles
|
||||
}
|
||||
fn tiles_dirty(&mut self) -> &mut bool {
|
||||
|
@ -320,19 +320,20 @@ impl AffineMap {
|
|||
tile_id: u8,
|
||||
) {
|
||||
let pos = self.map_size().gba_offset(pos);
|
||||
let colours = self.colours();
|
||||
|
||||
let old_tile = self.tiles_mut()[pos];
|
||||
if old_tile != 0 {
|
||||
vram.remove_tile(old_tile.into());
|
||||
if old_tile != Tile::default() {
|
||||
vram.remove_tile(old_tile.tile_index(colours));
|
||||
}
|
||||
|
||||
let tile_index = tile_id as u16;
|
||||
|
||||
let new_tile = if tile_index != TRANSPARENT_TILE_INDEX {
|
||||
let new_tile_idx = vram.add_tile(tileset, tile_index);
|
||||
new_tile_idx.raw_index() as u8
|
||||
Tile::new(new_tile_idx, TileSetting(0))
|
||||
} else {
|
||||
0
|
||||
Tile::default()
|
||||
};
|
||||
|
||||
if old_tile == new_tile {
|
||||
|
|
|
@ -156,8 +156,8 @@ impl Tile {
|
|||
Self(idx.raw_index() | setting.setting())
|
||||
}
|
||||
|
||||
fn tile_index(self) -> TileIndex {
|
||||
TileIndex::new(self.0 as usize & ((1 << 10) - 1), TileFormat::FourBpp)
|
||||
fn tile_index(self, format: TileFormat) -> TileIndex {
|
||||
TileIndex::new(self.0 as usize & ((1 << 10) - 1), format)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,6 +165,8 @@ impl Tile {
|
|||
pub struct TileSetting(u16);
|
||||
|
||||
impl TileSetting {
|
||||
pub const BLANK: Self = TileSetting::new(1023, false, false, 0);
|
||||
|
||||
#[must_use]
|
||||
pub const fn new(tile_id: u16, hflip: bool, vflip: bool, palette_id: u8) -> Self {
|
||||
Self(
|
||||
|
@ -180,6 +182,16 @@ impl TileSetting {
|
|||
Self(raw)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn hflip(self, should_flip: bool) -> Self {
|
||||
Self(self.0 ^ ((should_flip as u16) << 10))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn vflip(self, should_flip: bool) -> Self {
|
||||
Self(self.0 ^ ((should_flip as u16) << 11))
|
||||
}
|
||||
|
||||
fn index(self) -> u16 {
|
||||
self.0 & ((1 << 10) - 1)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ use core::{alloc::Layout, ptr::NonNull};
|
|||
|
||||
use alloc::{slice, vec::Vec};
|
||||
|
||||
use crate::display::tiled::Tile;
|
||||
use crate::{
|
||||
agb_alloc::{block_allocator::BlockAllocator, bump_allocator::StartEnd},
|
||||
display::palette16,
|
||||
|
@ -66,21 +65,21 @@ impl<'a> TileSet<'a> {
|
|||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum TileIndex {
|
||||
FourBpp(u16),
|
||||
EightBpp(u8),
|
||||
EightBpp(u16),
|
||||
}
|
||||
|
||||
impl TileIndex {
|
||||
pub(crate) const fn new(index: usize, format: TileFormat) -> Self {
|
||||
match format {
|
||||
TileFormat::FourBpp => Self::FourBpp(index as u16),
|
||||
TileFormat::EightBpp => Self::EightBpp(index as u8),
|
||||
TileFormat::EightBpp => Self::EightBpp(index as u16),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn raw_index(self) -> u16 {
|
||||
match self {
|
||||
TileIndex::FourBpp(x) => x,
|
||||
TileIndex::EightBpp(x) => x as u16,
|
||||
TileIndex::EightBpp(x) => x,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,18 +98,6 @@ impl TileIndex {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Tile> for TileIndex {
|
||||
fn from(tile: Tile) -> Self {
|
||||
tile.tile_index()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for TileIndex {
|
||||
fn from(index: u8) -> TileIndex {
|
||||
TileIndex::new(usize::from(index), TileFormat::EightBpp)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
struct TileReference(NonNull<u32>);
|
||||
|
||||
|
@ -302,7 +289,7 @@ impl VRamManager {
|
|||
|
||||
let new_reference: NonNull<u32> =
|
||||
unsafe { TILE_ALLOCATOR.alloc(layout_of(tile_set.format)) }
|
||||
.unwrap()
|
||||
.expect("Ran out of video RAM for tiles")
|
||||
.cast();
|
||||
let tile_reference = TileReference(new_reference);
|
||||
reference.or_insert(tile_reference);
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
//!
|
||||
//! To get started with agb, you should clone the [template repo](https://github.com/agbrs/template) and work from there.
|
||||
|
||||
/// This macro is used to convert a png or bmp into a format usable by the Game Boy Advance.
|
||||
/// This macro is used to convert a png, bmp or aseprite file into a format usable by the Game Boy Advance.
|
||||
///
|
||||
/// Suppose you have a file in `examples/water_tiles.png` which contains some tiles you'd like to use.
|
||||
///
|
||||
|
@ -89,7 +89,7 @@
|
|||
/// &mut vram,
|
||||
/// (x, y).into(),
|
||||
/// &tileset,
|
||||
/// TileSetting::new(0, false, false, 0),
|
||||
/// water_tiles::tiles.tile_settings[0],
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
|
|
304
examples/combo/Cargo.lock
generated
304
examples/combo/Cargo.lock
generated
|
@ -52,7 +52,7 @@ dependencies = [
|
|||
"image",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -61,7 +61,7 @@ version = "0.16.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -71,7 +71,47 @@ dependencies = [
|
|||
"hound",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "agb_tracker"
|
||||
version = "0.16.0"
|
||||
dependencies = [
|
||||
"agb",
|
||||
"agb_tracker_interop",
|
||||
"agb_xm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "agb_tracker_interop"
|
||||
version = "0.16.0"
|
||||
dependencies = [
|
||||
"agb_fixnum",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "agb_xm"
|
||||
version = "0.16.0"
|
||||
dependencies = [
|
||||
"agb_xm_core",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "agb_xm_core"
|
||||
version = "0.16.0"
|
||||
dependencies = [
|
||||
"agb_fixnum",
|
||||
"agb_tracker_interop",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
"xmrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -133,6 +173,12 @@ dependencies = [
|
|||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
|
||||
|
||||
[[package]]
|
||||
name = "bilge"
|
||||
version = "0.2.0"
|
||||
|
@ -153,7 +199,16 @@ dependencies = [
|
|||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -199,6 +254,7 @@ dependencies = [
|
|||
"agb",
|
||||
"amplitude",
|
||||
"hyperspace-roll",
|
||||
"the-dungeon-puzzlers-lament",
|
||||
"the-hat-chooses-the-wizard",
|
||||
"the-purple-night",
|
||||
]
|
||||
|
@ -228,6 +284,12 @@ version = "1.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.26"
|
||||
|
@ -244,7 +306,7 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0793f5137567643cf65ea42043a538804ff0fbf288649e2141442b602d81f9bc"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"hashbrown 0.13.2",
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
|
@ -257,6 +319,17 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.13.2"
|
||||
|
@ -266,6 +339,12 @@ dependencies = [
|
|||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
|
||||
|
||||
[[package]]
|
||||
name = "hound"
|
||||
version = "3.5.0"
|
||||
|
@ -294,6 +373,16 @@ dependencies = [
|
|||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
|
@ -309,6 +398,12 @@ version = "1.0.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "libflate"
|
||||
version = "0.1.27"
|
||||
|
@ -321,12 +416,38 @@ dependencies = [
|
|||
"take_mut",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libflate"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ff4ae71b685bbad2f2f391fe74f6b7659a34871c08b210fdc039e43bee07d18"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"crc32fast",
|
||||
"libflate_lz77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libflate_lz77"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a52d3a8bfc85f250440e4424db7d857e241a3aebbbe301f3eb606ab15c39acbf"
|
||||
dependencies = [
|
||||
"rle-decode-fast",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f478948fd84d9f8e86967bf432640e46adfb5a4bd4f14ef7e864ab38220534ae"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.7"
|
||||
|
@ -392,6 +513,27 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
|
@ -410,6 +552,22 @@ dependencies = [
|
|||
"miniz_oxide 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
|
@ -419,6 +577,7 @@ dependencies = [
|
|||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
@ -451,6 +610,36 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rle-decode-fast"
|
||||
version = "1.0.3"
|
||||
|
@ -478,6 +667,15 @@ dependencies = [
|
|||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-big-array"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.183"
|
||||
|
@ -486,7 +684,7 @@ checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -500,6 +698,25 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slotmap"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.28"
|
||||
|
@ -517,6 +734,18 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
|
||||
|
||||
[[package]]
|
||||
name = "the-dungeon-puzzlers-lament"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"agb",
|
||||
"agb_tracker",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"slotmap",
|
||||
"tiled 0.11.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "the-hat-chooses-the-wizard"
|
||||
version = "0.1.0"
|
||||
|
@ -533,7 +762,7 @@ dependencies = [
|
|||
"agb",
|
||||
"generational-arena",
|
||||
"quote",
|
||||
"tiled",
|
||||
"tiled 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -542,11 +771,39 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d2c30aeea9d8159cb461a17dba23ad28980a2a9c217a6784a14e931e4979d6f"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"libflate",
|
||||
"base64 0.10.1",
|
||||
"libflate 0.1.27",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiled"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "181e2402be287d74e951a8e81c8798d0737cc94b1a089237bb3b838be76c6b5b"
|
||||
dependencies = [
|
||||
"base64 0.21.3",
|
||||
"libflate 1.4.0",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.15.2"
|
||||
|
@ -565,8 +822,37 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47430998a7b5d499ccee752b41567bc3afc57e1327dc855b1a2aa44ce29b5fa1"
|
||||
|
||||
[[package]]
|
||||
name = "xmrs"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fa1ec7c01e6bb4c716f84a418f4ced5f4a735b2ae6364f4bb5850da61321d16"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"libflate 1.4.0",
|
||||
"num_enum",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde-big-array",
|
||||
]
|
||||
|
|
|
@ -11,6 +11,7 @@ the-purple-night = { path = "../the-purple-night" }
|
|||
the-hat-chooses-the-wizard = { path = "../the-hat-chooses-the-wizard" }
|
||||
hyperspace-roll = { path = "../hyperspace-roll" }
|
||||
amplitude = { path = "../amplitude" }
|
||||
the-dungeon-puzzlers-lament = { path = "../the-dungeon-puzzlers-lament" }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 3
|
||||
|
|
BIN
examples/combo/gfx/dungeon_puzzler.png
Normal file
BIN
examples/combo/gfx/dungeon_puzzler.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
|
@ -8,7 +8,7 @@ use alloc::boxed::Box;
|
|||
|
||||
use agb::{
|
||||
display::{
|
||||
tiled::{InfiniteScrolledMap, RegularBackgroundSize, TileFormat, TileSet, TileSetting},
|
||||
tiled::{InfiniteScrolledMap, RegularBackgroundSize, TileFormat, TileSet},
|
||||
Priority,
|
||||
},
|
||||
fixnum::{Num, Vector2D},
|
||||
|
@ -21,6 +21,7 @@ pub enum Game {
|
|||
TheHatChoosesTheWizard,
|
||||
ThePurpleNight,
|
||||
HyperspaceRoll,
|
||||
TheDungeonPuzzlersLament,
|
||||
Amplitude,
|
||||
}
|
||||
|
||||
|
@ -30,6 +31,7 @@ impl Game {
|
|||
Game::TheHatChoosesTheWizard => the_hat_chooses_the_wizard::main(gba),
|
||||
Game::ThePurpleNight => the_purple_night::main(gba),
|
||||
Game::HyperspaceRoll => hyperspace_roll::main(gba),
|
||||
Game::TheDungeonPuzzlersLament => the_dungeon_puzzlers_lament::entry(gba),
|
||||
Game::Amplitude => amplitude::main(gba),
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +41,8 @@ impl Game {
|
|||
0 => Game::TheHatChoosesTheWizard,
|
||||
1 => Game::ThePurpleNight,
|
||||
2 => Game::HyperspaceRoll,
|
||||
3 => Game::Amplitude,
|
||||
3 => Game::TheDungeonPuzzlersLament,
|
||||
4 => Game::Amplitude,
|
||||
_ => unreachable!("game out of index in an unreachable manner"),
|
||||
}
|
||||
}
|
||||
|
@ -47,10 +50,11 @@ impl Game {
|
|||
|
||||
include_background_gfx!(
|
||||
games, "121105",
|
||||
hat => "gfx/hat.png",
|
||||
purple => "gfx/purple.png",
|
||||
hyperspace => "gfx/hyperspace.png",
|
||||
amplitude => "gfx/amplitude.png"
|
||||
hat => 256 deduplicate "gfx/hat.png",
|
||||
purple => 256 deduplicate "gfx/purple.png",
|
||||
hyperspace => 256 deduplicate "gfx/hyperspace.png",
|
||||
dungeon_puzzler => 256 deduplicate "gfx/dungeon_puzzler.png",
|
||||
amplitude => 256 deduplicate "gfx/amplitude.png",
|
||||
);
|
||||
|
||||
fn get_game(gba: &mut agb::Gba) -> Game {
|
||||
|
@ -59,18 +63,20 @@ fn get_game(gba: &mut agb::Gba) -> Game {
|
|||
|
||||
let (tile, mut vram) = gba.display.video.tiled0();
|
||||
|
||||
let hat = TileSet::new(games::hat.tiles, TileFormat::FourBpp);
|
||||
let purple = TileSet::new(games::purple.tiles, TileFormat::FourBpp);
|
||||
let hyperspace = TileSet::new(games::hyperspace.tiles, TileFormat::FourBpp);
|
||||
let amplitude = TileSet::new(games::amplitude.tiles, TileFormat::FourBpp);
|
||||
let hat = TileSet::new(games::hat.tiles, TileFormat::EightBpp);
|
||||
let purple = TileSet::new(games::purple.tiles, TileFormat::EightBpp);
|
||||
let hyperspace = TileSet::new(games::hyperspace.tiles, TileFormat::EightBpp);
|
||||
let dungeon_puzzler = TileSet::new(games::dungeon_puzzler.tiles, TileFormat::EightBpp);
|
||||
let amplitude = TileSet::new(games::amplitude.tiles, TileFormat::EightBpp);
|
||||
|
||||
let tiles = [hat, purple, hyperspace, amplitude];
|
||||
let tiles = [hat, purple, hyperspace, dungeon_puzzler, amplitude];
|
||||
|
||||
let palette_assignments = &[
|
||||
games::hat.palette_assignments,
|
||||
games::purple.palette_assignments,
|
||||
games::hyperspace.palette_assignments,
|
||||
games::amplitude.palette_assignments,
|
||||
let tile_settings = &[
|
||||
games::hat.tile_settings,
|
||||
games::purple.tile_settings,
|
||||
games::hyperspace.tile_settings,
|
||||
games::dungeon_puzzler.tile_settings,
|
||||
games::amplitude.tile_settings,
|
||||
];
|
||||
|
||||
vram.set_background_palettes(games::PALETTES);
|
||||
|
@ -79,7 +85,7 @@ fn get_game(gba: &mut agb::Gba) -> Game {
|
|||
tile.background(
|
||||
Priority::P0,
|
||||
RegularBackgroundSize::Background32x32,
|
||||
TileFormat::FourBpp,
|
||||
TileFormat::EightBpp,
|
||||
),
|
||||
Box::new(|pos| {
|
||||
let y = pos.y.rem_euclid(20);
|
||||
|
@ -87,15 +93,7 @@ fn get_game(gba: &mut agb::Gba) -> Game {
|
|||
|
||||
let game = (pos.x).rem_euclid(tiles.len() as i32 * 30) as usize / 30;
|
||||
let tile_id = (y * 30 + x) as usize;
|
||||
(
|
||||
&tiles[game],
|
||||
TileSetting::new(
|
||||
tile_id as u16,
|
||||
false,
|
||||
false,
|
||||
palette_assignments[game][tile_id],
|
||||
),
|
||||
)
|
||||
(&tiles[game], tile_settings[game][tile_id])
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@ use agb::{
|
|||
use crate::sfx::Sfx;
|
||||
|
||||
include_background_gfx!(backgrounds, "121105",
|
||||
stars => "gfx/stars.aseprite",
|
||||
title => "gfx/title-screen.aseprite",
|
||||
help => "gfx/help-text.aseprite",
|
||||
descriptions1 => "gfx/descriptions1.png",
|
||||
descriptions2 => "gfx/descriptions2.png",
|
||||
stars => deduplicate "gfx/stars.aseprite",
|
||||
title => deduplicate "gfx/title-screen.aseprite",
|
||||
help => deduplicate "gfx/help-text.aseprite",
|
||||
descriptions1 => deduplicate "gfx/descriptions1.png",
|
||||
descriptions2 => deduplicate "gfx/descriptions2.png",
|
||||
);
|
||||
|
||||
pub fn load_palettes(vram: &mut VRamManager) {
|
||||
|
@ -35,12 +35,7 @@ pub(crate) fn load_help_text(
|
|||
vram,
|
||||
(x + at_tile.0, at_tile.1).into(),
|
||||
&help_tileset,
|
||||
TileSetting::new(
|
||||
tile_id,
|
||||
false,
|
||||
false,
|
||||
backgrounds::help.palette_assignments[tile_id as usize],
|
||||
),
|
||||
backgrounds::help.tile_settings[tile_id as usize],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -50,13 +45,13 @@ pub(crate) fn load_description(
|
|||
descriptions_map: &mut RegularMap,
|
||||
vram: &mut VRamManager,
|
||||
) {
|
||||
let (tileset, palette_assignments) = if face_id < 10 {
|
||||
let (tileset, tile_settings) = if face_id < 10 {
|
||||
(
|
||||
TileSet::new(
|
||||
backgrounds::descriptions1.tiles,
|
||||
agb::display::tiled::TileFormat::FourBpp,
|
||||
),
|
||||
backgrounds::descriptions1.palette_assignments,
|
||||
backgrounds::descriptions1.tile_settings,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
|
@ -64,7 +59,7 @@ pub(crate) fn load_description(
|
|||
backgrounds::descriptions2.tiles,
|
||||
agb::display::tiled::TileFormat::FourBpp,
|
||||
),
|
||||
backgrounds::descriptions2.palette_assignments,
|
||||
backgrounds::descriptions2.tile_settings,
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -75,7 +70,7 @@ pub(crate) fn load_description(
|
|||
vram,
|
||||
(x, y).into(),
|
||||
&tileset,
|
||||
TileSetting::new(tile_id, false, false, palette_assignments[tile_id as usize]),
|
||||
tile_settings[tile_id as usize],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -87,16 +82,12 @@ fn create_background_map(map: &mut RegularMap, vram: &mut VRamManager, stars_til
|
|||
for y in 0..32u16 {
|
||||
let blank = rng::gen().rem_euclid(32) < 30;
|
||||
|
||||
let (tile_id, palette_id) = if blank {
|
||||
((1 << 10) - 1, 0)
|
||||
let tile_setting = if blank {
|
||||
TileSetting::new((1 << 10) - 1, false, false, 0)
|
||||
} else {
|
||||
let tile_id = rng::gen().rem_euclid(64) as u16;
|
||||
(
|
||||
tile_id,
|
||||
backgrounds::stars.palette_assignments[tile_id as usize],
|
||||
)
|
||||
backgrounds::stars.tile_settings[tile_id as usize]
|
||||
};
|
||||
let tile_setting = TileSetting::new(tile_id, false, false, palette_id);
|
||||
|
||||
map.set_tile(vram, (x, y).into(), stars_tileset, tile_setting);
|
||||
}
|
||||
|
@ -121,12 +112,7 @@ pub fn show_title_screen(background: &mut RegularMap, vram: &mut VRamManager, sf
|
|||
vram,
|
||||
(x, y).into(),
|
||||
&tile_set,
|
||||
TileSetting::new(
|
||||
tile_id,
|
||||
false,
|
||||
false,
|
||||
backgrounds::title.palette_assignments[tile_id as usize],
|
||||
),
|
||||
backgrounds::title.tile_settings[tile_id as usize],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -331,12 +331,10 @@ fn export_tiles(map: &tiled::Map, background: TokenStream) -> TokenStream {
|
|||
tile_tileset_x * 2 + x_offset + tile_tileset_y * 9 * 4 + y_offset * 9 * 2;
|
||||
let gba_tile_id = gba_tile_id as u16;
|
||||
|
||||
let palette_id =
|
||||
quote! { backgrounds::#background.palette_assignments[#gba_tile_id as usize] };
|
||||
quote! { TileSetting::new(#gba_tile_id, #hflip, #vflip, #palette_id) }
|
||||
quote! { backgrounds::#background.tile_settings[#gba_tile_id as usize].hflip(#hflip).vflip(#vflip) }
|
||||
}
|
||||
None => {
|
||||
quote! { TileSetting::new(1023, false, false, 0) }
|
||||
quote! { TileSetting::BLANK }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -361,12 +359,11 @@ fn export_ui_tiles(map: &tiled::Map, background: TokenStream) -> TokenStream {
|
|||
let tile_id = tile.id() as u16;
|
||||
let vflip = tile.flip_v;
|
||||
let hflip = tile.flip_h;
|
||||
let palette_id =
|
||||
quote! { backgrounds::#background.palette_assignments[#tile_id as usize] };
|
||||
quote! { TileSetting::new(#tile_id, #hflip, #vflip, #palette_id) }
|
||||
|
||||
quote! { backgrounds::#background.tile_settings[#tile_id as usize].hflip(#hflip).vflip(#vflip) }
|
||||
}
|
||||
None => {
|
||||
quote! { TileSetting::new(1023, false, false, 0) }
|
||||
quote! { TileSetting::BLANK }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use agb::{
|
||||
display::tiled::{RegularMap, TileFormat, TileSet, TileSetting, VRamManager},
|
||||
display::tiled::{RegularMap, TileFormat, TileSet, VRamManager},
|
||||
include_background_gfx,
|
||||
};
|
||||
|
||||
include_background_gfx!(backgrounds, "1e151b",
|
||||
ui => "maps/ui_tiles.png",
|
||||
level => "maps/level.png",
|
||||
ending => "gfx/ending_page.aseprite",
|
||||
ui => deduplicate "maps/ui_tiles.png",
|
||||
level => deduplicate "maps/level.png",
|
||||
ending => deduplicate "gfx/ending_page.aseprite",
|
||||
);
|
||||
|
||||
mod tilemaps {
|
||||
|
@ -56,13 +56,13 @@ pub fn load_ending_page(map: &mut RegularMap, vram_manager: &mut VRamManager) {
|
|||
for y in 0..20u16 {
|
||||
for x in 0..30u16 {
|
||||
let tile_pos = y * 30 + x;
|
||||
let tile_setting = TileSetting::new(
|
||||
tile_pos,
|
||||
false,
|
||||
false,
|
||||
backgrounds::ending.palette_assignments[tile_pos as usize],
|
||||
|
||||
map.set_tile(
|
||||
vram_manager,
|
||||
(x, y).into(),
|
||||
&ending_tileset,
|
||||
backgrounds::ending.tile_settings[tile_pos as usize],
|
||||
);
|
||||
map.set_tile(vram_manager, (x, y).into(), &ending_tileset, tile_setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ use agb::display::{
|
|||
HEIGHT, WIDTH,
|
||||
};
|
||||
|
||||
const LEVEL_START: u16 = 12 * 28;
|
||||
const NUMBERS_START: u16 = 12 * 28 + 3;
|
||||
const HYPHEN: u16 = 12 * 28 + 11;
|
||||
pub const BLANK: u16 = 11 * 28;
|
||||
const LEVEL_START: usize = 12 * 28;
|
||||
const NUMBERS_START: usize = 12 * 28 + 3;
|
||||
const HYPHEN: usize = 12 * 28 + 11;
|
||||
pub const BLANK: usize = 11 * 28;
|
||||
|
||||
pub fn write_level(
|
||||
map: &mut RegularMap,
|
||||
|
@ -14,25 +14,21 @@ pub fn write_level(
|
|||
level: u32,
|
||||
tileset: &'_ TileSet<'_>,
|
||||
vram: &mut VRamManager,
|
||||
tile_settings: &[TileSetting],
|
||||
) {
|
||||
for (i, &tile) in [
|
||||
LEVEL_START,
|
||||
LEVEL_START + 1,
|
||||
LEVEL_START + 2,
|
||||
BLANK,
|
||||
world as u16 + NUMBERS_START - 1,
|
||||
world as usize + NUMBERS_START - 1,
|
||||
HYPHEN,
|
||||
level as u16 + NUMBERS_START - 1,
|
||||
level as usize + NUMBERS_START - 1,
|
||||
]
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
map.set_tile(
|
||||
vram,
|
||||
(i as u16, 0).into(),
|
||||
tileset,
|
||||
TileSetting::from_raw(tile),
|
||||
);
|
||||
map.set_tile(vram, (i as u16, 0).into(), tileset, tile_settings[tile]);
|
||||
}
|
||||
|
||||
map.set_scroll_pos((-(WIDTH / 2 - 7 * 8 / 2) as i16, -(HEIGHT / 2 - 4) as i16).into());
|
||||
|
|
|
@ -11,7 +11,7 @@ use agb::{
|
|||
object::{Graphics, OamManaged, Object, Tag, TagMap},
|
||||
tiled::{
|
||||
InfiniteScrolledMap, PartialUpdateStatus, RegularBackgroundSize, TileFormat, TileSet,
|
||||
TileSetting, TiledMap, VRamManager,
|
||||
TiledMap, VRamManager,
|
||||
},
|
||||
Priority, HEIGHT, WIDTH,
|
||||
},
|
||||
|
@ -101,7 +101,7 @@ mod map_tiles {
|
|||
}
|
||||
}
|
||||
|
||||
agb::include_background_gfx!(tile_sheet, "2ce8f4", background => "gfx/tile_sheet.png");
|
||||
agb::include_background_gfx!(tile_sheet, "2ce8f4", background => deduplicate "gfx/tile_sheet.png");
|
||||
|
||||
const GRAPHICS: &Graphics = agb::include_aseprite!("gfx/sprites.aseprite");
|
||||
const TAG_MAP: &TagMap = GRAPHICS.tags();
|
||||
|
@ -801,7 +801,7 @@ pub fn main(mut agb: agb::Gba) -> ! {
|
|||
&mut vram,
|
||||
(x, y).into(),
|
||||
&tileset,
|
||||
TileSetting::from_raw(level_display::BLANK),
|
||||
tile_sheet::background.tile_settings[level_display::BLANK],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -846,6 +846,7 @@ pub fn main(mut agb: agb::Gba) -> ! {
|
|||
current_level % 8 + 1,
|
||||
&tileset,
|
||||
&mut vram,
|
||||
tile_sheet::background.tile_settings,
|
||||
);
|
||||
|
||||
world_display.commit(&mut vram);
|
||||
|
@ -865,12 +866,11 @@ pub fn main(mut agb: agb::Gba) -> ! {
|
|||
let level = &map_tiles::LEVELS[map_current_level as usize];
|
||||
(
|
||||
&tileset,
|
||||
TileSetting::from_raw(
|
||||
*level
|
||||
.background
|
||||
.get((pos.y * level.dimensions.x as i32 + pos.x) as usize)
|
||||
.unwrap_or(&0),
|
||||
),
|
||||
tile_sheet::background.tile_settings[*level
|
||||
.background
|
||||
.get((pos.y * level.dimensions.x as i32 + pos.x) as usize)
|
||||
.unwrap_or(&0)
|
||||
as usize],
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
@ -884,12 +884,11 @@ pub fn main(mut agb: agb::Gba) -> ! {
|
|||
let level = &map_tiles::LEVELS[map_current_level as usize];
|
||||
(
|
||||
&tileset,
|
||||
TileSetting::from_raw(
|
||||
*level
|
||||
.foreground
|
||||
.get((pos.y * level.dimensions.x as i32 + pos.x) as usize)
|
||||
.unwrap_or(&0),
|
||||
),
|
||||
tile_sheet::background.tile_settings[*level
|
||||
.foreground
|
||||
.get((pos.y * level.dimensions.x as i32 + pos.x) as usize)
|
||||
.unwrap_or(&0)
|
||||
as usize],
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use super::sfx::SfxPlayer;
|
||||
use agb::display::tiled::{RegularMap, TileFormat, TileSet, TileSetting, TiledMap, VRamManager};
|
||||
use agb::display::tiled::{RegularMap, TileFormat, TileSet, TiledMap, VRamManager};
|
||||
|
||||
agb::include_background_gfx!(splash_screens,
|
||||
splash => "gfx/splash.png",
|
||||
thanks_for_playing => "gfx/thanks_for_playing.png",
|
||||
splash => deduplicate "gfx/splash.png",
|
||||
thanks_for_playing => deduplicate "gfx/thanks_for_playing.png",
|
||||
);
|
||||
|
||||
pub enum SplashScreen {
|
||||
|
@ -18,12 +18,18 @@ pub fn show_splash_screen(
|
|||
vram: &mut VRamManager,
|
||||
) {
|
||||
map.set_scroll_pos((0i16, 0i16).into());
|
||||
let tileset = match which {
|
||||
SplashScreen::Start => TileSet::new(splash_screens::splash.tiles, TileFormat::FourBpp),
|
||||
let (tileset, settings) = match which {
|
||||
SplashScreen::Start => (
|
||||
TileSet::new(splash_screens::splash.tiles, TileFormat::FourBpp),
|
||||
splash_screens::splash.tile_settings,
|
||||
),
|
||||
|
||||
SplashScreen::End => TileSet::new(
|
||||
splash_screens::thanks_for_playing.tiles,
|
||||
TileFormat::FourBpp,
|
||||
SplashScreen::End => (
|
||||
TileSet::new(
|
||||
splash_screens::thanks_for_playing.tiles,
|
||||
TileFormat::FourBpp,
|
||||
),
|
||||
splash_screens::thanks_for_playing.tile_settings,
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -40,7 +46,7 @@ pub fn show_splash_screen(
|
|||
vram,
|
||||
(x, y).into(),
|
||||
&tileset,
|
||||
TileSetting::from_raw(y * 30 + x),
|
||||
settings[(y * 30 + x) as usize],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,7 @@ use alloc::{boxed::Box, vec::Vec};
|
|||
use agb::{
|
||||
display::{
|
||||
object::{Graphics, OamManaged, Object, Sprite, Tag, TagMap},
|
||||
tiled::{
|
||||
InfiniteScrolledMap, RegularBackgroundSize, TileFormat, TileSet, TileSetting,
|
||||
VRamManager,
|
||||
},
|
||||
tiled::{InfiniteScrolledMap, RegularBackgroundSize, TileFormat, TileSet, VRamManager},
|
||||
Priority, HEIGHT, WIDTH,
|
||||
},
|
||||
fixnum::{num, FixedNum, Rect, Vector2D},
|
||||
|
@ -57,7 +54,7 @@ const SWORDLESS_JUMP: &Tag = TAG_MAP.get("jump swordless");
|
|||
const SWORDLESS_ATTACK: &Tag = KNIFE_ATTACK;
|
||||
const SWORDLESS_JUMP_ATTACK: &Tag = KNIFE_JUMP_ATTACK;
|
||||
|
||||
agb::include_background_gfx!(background, "53269a", background => "gfx/background.aseprite");
|
||||
agb::include_background_gfx!(background, "53269a", background => deduplicate "gfx/background.aseprite");
|
||||
|
||||
type Number = FixedNum<8>;
|
||||
|
||||
|
@ -2207,11 +2204,10 @@ fn game_with_level(gba: &mut agb::Gba) {
|
|||
Box::new(|pos| {
|
||||
(
|
||||
&tileset,
|
||||
TileSetting::from_raw(
|
||||
*tilemap::BACKGROUND_MAP
|
||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||
.unwrap_or(&0),
|
||||
),
|
||||
background::background.tile_settings[*tilemap::BACKGROUND_MAP
|
||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||
.unwrap_or(&0)
|
||||
as usize],
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
@ -2225,11 +2221,10 @@ fn game_with_level(gba: &mut agb::Gba) {
|
|||
Box::new(|pos| {
|
||||
(
|
||||
&tileset,
|
||||
TileSetting::from_raw(
|
||||
*tilemap::FOREGROUND_MAP
|
||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||
.unwrap_or(&0),
|
||||
),
|
||||
background::background.tile_settings[*tilemap::FOREGROUND_MAP
|
||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||
.unwrap_or(&0)
|
||||
as usize],
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
@ -2243,11 +2238,10 @@ fn game_with_level(gba: &mut agb::Gba) {
|
|||
Box::new(|pos| {
|
||||
(
|
||||
&tileset,
|
||||
TileSetting::from_raw(
|
||||
*tilemap::CLOUD_MAP
|
||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||
.unwrap_or(&0),
|
||||
),
|
||||
background::background.tile_settings[*tilemap::CLOUD_MAP
|
||||
.get((pos.x + tilemap::WIDTH * pos.y) as usize)
|
||||
.unwrap_or(&0)
|
||||
as usize],
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue