2021-04-21 05:41:04 +10:00
|
|
|
use crate::palette16::Palette16OptimisationResults;
|
|
|
|
use crate::TileSize;
|
2022-03-22 09:41:11 +11:00
|
|
|
use crate::{image_loader::Image, ByteString};
|
2021-04-21 05:41:04 +10:00
|
|
|
|
2021-07-27 08:27:16 +10:00
|
|
|
use proc_macro2::TokenStream;
|
|
|
|
use quote::{format_ident, quote};
|
|
|
|
|
|
|
|
use std::iter;
|
|
|
|
|
2021-04-21 05:41:04 +10:00
|
|
|
pub(crate) fn generate_code(
|
2021-07-22 06:01:24 +10:00
|
|
|
output_variable_name: &str,
|
2021-04-21 05:41:04 +10:00
|
|
|
results: &Palette16OptimisationResults,
|
|
|
|
image: &Image,
|
2021-07-22 07:07:09 +10:00
|
|
|
image_filename: &str,
|
2021-04-21 05:41:04 +10:00
|
|
|
tile_size: TileSize,
|
2021-06-06 02:47:13 +10:00
|
|
|
crate_prefix: String,
|
2021-07-27 08:27:16 +10:00
|
|
|
) -> TokenStream {
|
|
|
|
let crate_prefix = format_ident!("{}", crate_prefix);
|
|
|
|
let output_variable_name = format_ident!("{}", output_variable_name);
|
|
|
|
|
|
|
|
let palette_data = 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);
|
2021-07-27 08:27:16 +10:00
|
|
|
|
|
|
|
quote! {
|
|
|
|
#crate_prefix::display::palette16::Palette16::new([
|
|
|
|
#(#colours),*
|
|
|
|
])
|
2021-04-21 05:41:04 +10:00
|
|
|
}
|
2021-07-27 08:27:16 +10:00
|
|
|
});
|
2021-04-21 05:41:04 +10:00
|
|
|
|
|
|
|
let tile_size = tile_size.to_size();
|
|
|
|
|
|
|
|
let tiles_x = image.width / tile_size;
|
|
|
|
let tiles_y = image.height / tile_size;
|
|
|
|
|
2021-07-27 08:30:46 +10:00
|
|
|
let mut tile_data = vec![];
|
2021-07-27 08:27:16 +10:00
|
|
|
|
2021-07-27 08:30:46 +10:00
|
|
|
for y in 0..tiles_y {
|
|
|
|
for x in 0..tiles_x {
|
|
|
|
let palette_index = results.assignments[y * tiles_x + x];
|
|
|
|
let palette = &results.optimised_palettes[palette_index];
|
2022-03-22 09:41:11 +11:00
|
|
|
|
2021-07-27 08:30:46 +10:00
|
|
|
for inner_y in 0..tile_size / 8 {
|
|
|
|
for inner_x in 0..tile_size / 8 {
|
2022-03-22 09:41:11 +11:00
|
|
|
for j in inner_y * 8..inner_y * 8 + 8 {
|
|
|
|
for i in inner_x * 8..inner_x * 8 + 8 {
|
2021-07-27 08:30:46 +10:00
|
|
|
let colour = image.colour(x * tile_size + i, y * tile_size + j);
|
2022-05-23 04:23:29 +10:00
|
|
|
tile_data
|
|
|
|
.push(palette.colour_index(colour, results.transparent_colour));
|
2021-07-27 08:30:46 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-27 08:27:16 +10:00
|
|
|
|
2022-03-22 09:41:11 +11:00
|
|
|
let tile_data: Vec<_> = tile_data
|
|
|
|
.chunks(2)
|
|
|
|
.map(|chunk| (chunk[1] << 4) | chunk[0])
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
let data = ByteString(&tile_data);
|
2021-07-27 08:38:22 +10:00
|
|
|
|
|
|
|
let assignments = results.assignments.iter().map(|&x| x as u8);
|
2021-07-27 08:27:16 +10:00
|
|
|
|
|
|
|
quote! {
|
|
|
|
#[allow(non_upper_case_globals)]
|
|
|
|
pub const #output_variable_name: #crate_prefix::display::tile_data::TileData = {
|
|
|
|
const _: &[u8] = include_bytes!(#image_filename);
|
|
|
|
|
|
|
|
const PALETTE_DATA: &[#crate_prefix::display::palette16::Palette16] = &[
|
|
|
|
#(#palette_data),*
|
|
|
|
];
|
|
|
|
|
2022-03-22 09:41:11 +11:00
|
|
|
const TILE_DATA: &[u8] = #data;
|
2021-07-27 08:27:16 +10:00
|
|
|
|
|
|
|
const PALETTE_ASSIGNMENT: &[u8] = &[
|
|
|
|
#(#assignments),*
|
|
|
|
];
|
|
|
|
|
|
|
|
#crate_prefix::display::tile_data::TileData::new(PALETTE_DATA, TILE_DATA, PALETTE_ASSIGNMENT)
|
|
|
|
};
|
2021-04-21 05:41:04 +10:00
|
|
|
}
|
|
|
|
}
|