Generate tile settings instead of palette assignments

This commit is contained in:
Gwilym Inzani 2023-08-29 14:07:19 +01:00
parent f097e152cc
commit b5af3a3aff
5 changed files with 59 additions and 13 deletions

View file

@ -4,6 +4,7 @@ use image::{DynamicImage, GenericImageView};
use crate::colour::Colour; use crate::colour::Colour;
#[derive(Clone)]
pub(crate) struct Image { pub(crate) struct Image {
pub width: usize, pub width: usize,
pub height: 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 { pub fn colour(&self, x: usize, y: usize) -> Colour {
self.colour_data[x + y * self.width] self.colour_data[x + y * self.width]
} }

View file

@ -15,6 +15,7 @@ use quote::{format_ident, quote, ToTokens};
mod aseprite; mod aseprite;
mod colour; mod colour;
mod config; mod config;
mod deduplicator;
mod font_loader; mod font_loader;
mod image_loader; mod image_loader;
mod palette16; mod palette16;
@ -429,6 +430,7 @@ fn convert_image(
) -> proc_macro2::TokenStream { ) -> proc_macro2::TokenStream {
let image_filename = &parent.join(settings.filename()); let image_filename = &parent.join(settings.filename());
let image = Image::load_from_file(image_filename); let image = Image::load_from_file(image_filename);
let deduplicate = settings.deduplicate();
rust_generator::generate_code( rust_generator::generate_code(
variable_name, variable_name,
@ -437,6 +439,7 @@ fn convert_image(
&image_filename.to_string_lossy(), &image_filename.to_string_lossy(),
crate_prefix.to_owned(), crate_prefix.to_owned(),
assignment_offset, assignment_offset,
deduplicate,
) )
} }

View file

@ -1,3 +1,4 @@
use crate::deduplicator::{DeduplicatedData, Transformation};
use crate::palette16::Palette16OptimisationResults; use crate::palette16::Palette16OptimisationResults;
use crate::{add_image_256_to_tile_data, add_image_to_tile_data, collapse_to_4bpp}; use crate::{add_image_256_to_tile_data, add_image_to_tile_data, collapse_to_4bpp};
use crate::{image_loader::Image, ByteString}; use crate::{image_loader::Image, ByteString};
@ -40,14 +41,32 @@ pub(crate) fn generate_code(
image_filename: &str, image_filename: &str,
crate_prefix: String, crate_prefix: String,
assignment_offset: Option<usize>, assignment_offset: Option<usize>,
deduplicate: bool,
) -> TokenStream { ) -> TokenStream {
let crate_prefix = format_ident!("{}", crate_prefix); let crate_prefix = format_ident!("{}", crate_prefix);
let output_variable_name = format_ident!("{}", output_variable_name); 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 (tile_data, assignments) = if let Some(assignment_offset) = assignment_offset { let (tile_data, assignments) = if let Some(assignment_offset) = assignment_offset {
let mut tile_data = Vec::new(); 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);
let tile_data = collapse_to_4bpp(&tile_data); let tile_data = collapse_to_4bpp(&tile_data);
@ -65,11 +84,22 @@ pub(crate) fn generate_code(
} else { } else {
let mut tile_data = Vec::new(); 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![]) (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); let data = ByteString(&tile_data);
quote! { quote! {
@ -91,11 +121,11 @@ pub(crate) fn generate_code(
&ALIGNED.bytes &ALIGNED.bytes
}; };
const PALETTE_ASSIGNMENT: &[u8] = &[ const TILE_SETTINGS: &[#crate_prefix::display::tiled::TileSetting] = &[
#(#assignments),* #(#tile_settings),*
]; ];
#crate_prefix::display::tile_data::TileData::new(TILE_DATA, PALETTE_ASSIGNMENT) #crate_prefix::display::tile_data::TileData::new(TILE_DATA, TILE_SETTINGS)
}; };
} }
} }

View file

@ -1,4 +1,4 @@
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 => "gfx/test_logo.png");
@ -11,10 +11,12 @@ pub fn display_logo(map: &mut RegularMap, vram: &mut VRamManager) {
for x in 0..30 { for x in 0..30 {
let tile_id = y * 30 + x; let tile_id = y * 30 + x;
let palette_entry = agb_logo::test_logo.palette_assignments[tile_id as usize]; map.set_tile(
let tile_setting = TileSetting::new(tile_id, false, false, palette_entry); vram,
(x as u16, y as u16).into(),
map.set_tile(vram, (x, y).into(), &background_tilemap, tile_setting); &background_tilemap,
agb_logo::test_logo.tile_settings[tile_id],
);
} }
} }

View file

@ -1,15 +1,17 @@
use super::tiled::TileSetting;
#[non_exhaustive] #[non_exhaustive]
pub struct TileData { pub struct TileData {
pub tiles: &'static [u8], pub tiles: &'static [u8],
pub palette_assignments: &'static [u8], pub tile_settings: &'static [TileSetting],
} }
impl TileData { impl TileData {
#[must_use] #[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 { TileData {
tiles, tiles,
palette_assignments, tile_settings,
} }
} }
} }