mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
Switch entirely to using quote
to generate the code
This commit is contained in:
parent
aa32be1a27
commit
fdff081c32
|
@ -3,7 +3,7 @@ use syn::parse_macro_input;
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use quote::{quote, format_ident};
|
use quote::{format_ident, quote};
|
||||||
|
|
||||||
mod colour;
|
mod colour;
|
||||||
mod config;
|
mod config;
|
||||||
|
@ -44,13 +44,18 @@ pub fn include_gfx(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
let config = config::parse(&path.to_string_lossy());
|
let config = config::parse(&path.to_string_lossy());
|
||||||
|
|
||||||
let module_name = format_ident!("{}", path.file_stem().expect("Expected a file stem").to_string_lossy());
|
let module_name = format_ident!(
|
||||||
|
"{}",
|
||||||
|
path.file_stem()
|
||||||
|
.expect("Expected a file stem")
|
||||||
|
.to_string_lossy()
|
||||||
|
);
|
||||||
let include_path = path.to_string_lossy();
|
let include_path = path.to_string_lossy();
|
||||||
|
|
||||||
let images = config.images();
|
let images = config.images();
|
||||||
let image_code = images
|
let image_code = images.iter().map(|(image_name, &image)| {
|
||||||
.iter()
|
convert_image(image, parent, &image_name, &config.crate_prefix())
|
||||||
.map(|(image_name, &image)| convert_image(image, parent, &image_name, &config.crate_prefix()));
|
});
|
||||||
|
|
||||||
let module = quote! {
|
let module = quote! {
|
||||||
pub mod #module_name {
|
pub mod #module_name {
|
||||||
|
@ -80,19 +85,14 @@ fn convert_image(
|
||||||
let optimiser = optimiser_for_image(&image, tile_size);
|
let optimiser = optimiser_for_image(&image, tile_size);
|
||||||
let optimisation_results = optimiser.optimise_palettes(settings.transparent_colour());
|
let optimisation_results = optimiser.optimise_palettes(settings.transparent_colour());
|
||||||
|
|
||||||
let mut writer = String::new();
|
|
||||||
|
|
||||||
rust_generator::generate_code(
|
rust_generator::generate_code(
|
||||||
&mut writer,
|
|
||||||
variable_name,
|
variable_name,
|
||||||
&optimisation_results,
|
&optimisation_results,
|
||||||
&image,
|
&image,
|
||||||
&image_filename.to_string_lossy(),
|
&image_filename.to_string_lossy(),
|
||||||
settings.tilesize(),
|
settings.tilesize(),
|
||||||
crate_prefix.to_owned(),
|
crate_prefix.to_owned(),
|
||||||
);
|
)
|
||||||
|
|
||||||
writer.parse().unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn optimiser_for_image(image: &Image, tile_size: usize) -> palette16::Palette16Optimiser {
|
fn optimiser_for_image(image: &Image, tile_size: usize) -> palette16::Palette16Optimiser {
|
||||||
|
|
|
@ -1,121 +1,87 @@
|
||||||
use std::fmt::Write;
|
|
||||||
|
|
||||||
use crate::image_loader::Image;
|
use crate::image_loader::Image;
|
||||||
use crate::palette16::Palette16OptimisationResults;
|
use crate::palette16::Palette16OptimisationResults;
|
||||||
use crate::TileSize;
|
use crate::TileSize;
|
||||||
|
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::{format_ident, quote};
|
||||||
|
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
pub(crate) fn generate_code(
|
pub(crate) fn generate_code(
|
||||||
output: &mut dyn Write,
|
|
||||||
output_variable_name: &str,
|
output_variable_name: &str,
|
||||||
results: &Palette16OptimisationResults,
|
results: &Palette16OptimisationResults,
|
||||||
image: &Image,
|
image: &Image,
|
||||||
image_filename: &str,
|
image_filename: &str,
|
||||||
tile_size: TileSize,
|
tile_size: TileSize,
|
||||||
crate_prefix: String,
|
crate_prefix: String,
|
||||||
) {
|
) -> TokenStream {
|
||||||
writeln!(output, "#[allow(non_upper_case_globals)]").unwrap();
|
let crate_prefix = format_ident!("{}", crate_prefix);
|
||||||
writeln!(
|
let output_variable_name = format_ident!("{}", output_variable_name);
|
||||||
output,
|
|
||||||
"pub const {}: {}::display::tile_data::TileData = {{",
|
|
||||||
output_variable_name, crate_prefix
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
writeln!(
|
let palette_data = results.optimised_palettes.iter().map(|palette| {
|
||||||
output,
|
let colours = palette
|
||||||
"const _: &[u8] = include_bytes!(\"{}\");",
|
.clone()
|
||||||
image_filename
|
.into_iter()
|
||||||
)
|
.map(|colour| colour.to_rgb15())
|
||||||
.unwrap();
|
.chain(iter::repeat(0))
|
||||||
|
.take(16);
|
||||||
|
|
||||||
writeln!(
|
quote! {
|
||||||
output,
|
#crate_prefix::display::palette16::Palette16::new([
|
||||||
"const PALETTE_DATA: &[{}::display::palette16::Palette16] = &[",
|
#(#colours),*
|
||||||
crate_prefix,
|
])
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for palette in &results.optimised_palettes {
|
|
||||||
write!(
|
|
||||||
output,
|
|
||||||
" {}::display::palette16::Palette16::new([",
|
|
||||||
crate_prefix
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for colour in palette.clone() {
|
|
||||||
write!(output, "0x{:08x}, ", colour.to_rgb15()).unwrap();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
for _ in palette.clone().into_iter().len()..16 {
|
|
||||||
write!(output, "0x00000000, ").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(output, "]),").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(output, "];").unwrap();
|
|
||||||
writeln!(output).unwrap();
|
|
||||||
|
|
||||||
writeln!(output, "const TILE_DATA: &[u32] = &[",).unwrap();
|
|
||||||
|
|
||||||
let tile_size = tile_size.to_size();
|
let tile_size = tile_size.to_size();
|
||||||
|
|
||||||
let tiles_x = image.width / tile_size;
|
let tiles_x = image.width / tile_size;
|
||||||
let tiles_y = image.height / tile_size;
|
let tiles_y = image.height / tile_size;
|
||||||
|
|
||||||
for y in 0..tiles_y {
|
let tile_data = (0..tiles_y)
|
||||||
for x in 0..tiles_x {
|
.map(|y| {
|
||||||
let palette_index = results.assignments[y * tiles_x + x];
|
(0..tiles_x).map(move |x| {
|
||||||
let palette = &results.optimised_palettes[palette_index];
|
let palette_index = results.assignments[y * tiles_x + x];
|
||||||
writeln!(
|
let palette = &results.optimised_palettes[palette_index];
|
||||||
output,
|
|
||||||
" /* {}, {} (palette index {}) */",
|
|
||||||
x, y, palette_index
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for inner_y in 0..tile_size / 8 {
|
(0..tile_size / 8).map(move |inner_y| {
|
||||||
write!(output, " ").unwrap();
|
(0..tile_size / 8).map(move |inner_x| {
|
||||||
|
(inner_y * 8..inner_y * 8 + 8).map(move |j| {
|
||||||
|
(inner_x * 8..inner_x * 8 + 8).rev().map(move |i| {
|
||||||
|
let colour = image.colour(x * tile_size + i, y * tile_size + j);
|
||||||
|
palette.colour_index(colour)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
.flatten();
|
||||||
|
|
||||||
for inner_x in 0..tile_size / 8 {
|
let assignments = &results.assignments;
|
||||||
for j in inner_y * 8..inner_y * 8 + 8 {
|
|
||||||
write!(output, "0x").unwrap();
|
|
||||||
|
|
||||||
for i in (inner_x * 8..inner_x * 8 + 8).rev() {
|
quote! {
|
||||||
let colour = image.colour(x * tile_size + i, y * tile_size + j);
|
#[allow(non_upper_case_globals)]
|
||||||
let colour_index = palette.colour_index(colour);
|
pub const #output_variable_name: #crate_prefix::display::tile_data::TileData = {
|
||||||
|
const _: &[u8] = include_bytes!(#image_filename);
|
||||||
|
|
||||||
write!(output, "{:x}", colour_index).unwrap();
|
const PALETTE_DATA: &[#crate_prefix::display::palette16::Palette16] = &[
|
||||||
}
|
#(#palette_data),*
|
||||||
|
];
|
||||||
|
|
||||||
write!(output, ", ").unwrap();
|
const TILE_DATA: &[u32] = &[
|
||||||
}
|
#(#tile_data),*
|
||||||
}
|
];
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(output).unwrap();
|
const PALETTE_ASSIGNMENT: &[u8] = &[
|
||||||
}
|
#(#assignments),*
|
||||||
|
];
|
||||||
|
|
||||||
|
#crate_prefix::display::tile_data::TileData::new(PALETTE_DATA, TILE_DATA, PALETTE_ASSIGNMENT)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
writeln!(output, "];").unwrap();
|
|
||||||
writeln!(output).unwrap();
|
|
||||||
|
|
||||||
write!(output, "const PALETTE_ASSIGNMENT: &[u8] = &[").unwrap();
|
|
||||||
|
|
||||||
for (i, assignment) in results.assignments.iter().enumerate() {
|
|
||||||
if i % 16 == 0 {
|
|
||||||
write!(output, "\n ").unwrap();
|
|
||||||
}
|
|
||||||
write!(output, "{}, ", assignment).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(output, "\n];").unwrap();
|
|
||||||
|
|
||||||
writeln!(
|
|
||||||
output,
|
|
||||||
"{}::display::tile_data::TileData::new(PALETTE_DATA, TILE_DATA, PALETTE_ASSIGNMENT)\n}};",
|
|
||||||
crate_prefix
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue