agb/agb-image-converter/src/rust_generator.rs

104 lines
3 KiB
Rust
Raw Normal View History

2021-04-21 05:41:04 +10:00
use crate::palette16::Palette16OptimisationResults;
2022-08-12 08:48:57 +10:00
use crate::{add_image_256_to_tile_data, add_image_to_tile_data, collapse_to_4bpp, TileSize};
use crate::{image_loader::Image, ByteString};
2021-04-21 05:41:04 +10:00
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use std::iter;
pub(crate) fn generate_palette_code(
2021-04-21 05:41:04 +10:00
results: &Palette16OptimisationResults,
crate_prefix: &str,
) -> TokenStream {
let crate_prefix = format_ident!("{}", crate_prefix);
let palettes = results.optimised_palettes.iter().map(|palette| {
let colours = palette
.clone()
.into_iter()
.map(|colour| colour.to_rgb15())
.chain(iter::repeat(0))
2021-07-27 08:38:22 +10:00
.take(16)
.map(|colour| colour as u16);
quote! {
#crate_prefix::display::palette16::Palette16::new([
#(#colours),*
])
2021-04-21 05:41:04 +10:00
}
});
2021-04-21 05:41:04 +10:00
quote! {
pub const PALETTES: &[#crate_prefix::display::palette16::Palette16] = &[#(#palettes),*];
}
}
pub(crate) fn generate_code(
output_variable_name: &str,
results: &Palette16OptimisationResults,
image: &Image,
image_filename: &str,
tile_size: TileSize,
crate_prefix: String,
assignment_offset: Option<usize>,
) -> TokenStream {
let crate_prefix = format_ident!("{}", crate_prefix);
let output_variable_name = format_ident!("{}", output_variable_name);
2022-08-12 08:48:57 +10:00
let (tile_data, assignments) = if let Some(assignment_offset) = assignment_offset {
let mut tile_data = Vec::new();
2021-04-21 05:41:04 +10:00
2022-08-12 08:48:57 +10:00
add_image_to_tile_data(&mut tile_data, image, tile_size, results, assignment_offset);
2021-04-21 05:41:04 +10:00
2022-08-12 08:48:57 +10:00
let tile_data = collapse_to_4bpp(&tile_data);
2022-08-12 08:48:57 +10:00
let num_tiles = image.width * image.height / tile_size.to_size().pow(2);
let assignments = results
.assignments
.iter()
.skip(assignment_offset)
.take(num_tiles)
.map(|&x| x as u8)
.collect();
(tile_data, assignments)
} else {
let mut tile_data = Vec::new();
2021-07-27 08:38:22 +10:00
2022-08-12 08:48:57 +10:00
add_image_256_to_tile_data(&mut tile_data, image, tile_size, results);
2022-08-12 07:22:44 +10:00
2022-08-12 08:48:57 +10:00
(tile_data, vec![])
};
let data = ByteString(&tile_data);
quote! {
#[allow(non_upper_case_globals)]
pub const #output_variable_name: #crate_prefix::display::tile_data::TileData = {
const _: &[u8] = include_bytes!(#image_filename);
2022-10-22 22:41:58 +11:00
const TILE_DATA: &[u8] = {
pub struct AlignedAs<Align, Bytes: ?Sized> {
pub _align: [Align; 0],
pub bytes: Bytes,
}
const ALIGNED: &AlignedAs<u16, [u8]> = &AlignedAs {
_align: [],
bytes: *#data,
};
&ALIGNED.bytes
};
const PALETTE_ASSIGNMENT: &[u8] = &[
#(#assignments),*
];
#crate_prefix::display::tile_data::TileData::new(TILE_DATA, PALETTE_ASSIGNMENT)
};
2021-04-21 05:41:04 +10:00
}
}