Actually output some rust code

This commit is contained in:
Gwilym Kuiper 2021-04-20 20:41:04 +01:00
parent 4728f22806
commit 4daafdec20
6 changed files with 123 additions and 1 deletions

View file

@ -9,4 +9,9 @@ impl Colour {
pub fn from_rgb(r: u8, g: u8, b: u8) -> Self {
Colour { r, g, b }
}
pub fn to_rgb15(&self) -> u16 {
let (r, g, b) = (self.r as u16, self.g as u16, self.b as u16);
((r >> 3) & 31) | (((g >> 3) & 31) << 5) | (((b >> 3) & 31) << 10)
}
}

View file

@ -3,6 +3,7 @@ use std::path::PathBuf;
mod colour;
mod image_loader;
mod palette16;
mod rust_generator;
use image_loader::Image;
@ -41,7 +42,18 @@ pub fn convert_image(settings: &ImageConverterConfig) {
let optimiser = optimiser_for_image(&image, tile_size);
let optimisation_results = optimiser.optimise_palettes(settings.transparent_colour);
println!("{:#?}", optimisation_results);
let stdout = std::io::stdout();
let handle = stdout.lock();
let mut writer = std::io::BufWriter::new(handle);
rust_generator::generate_code(
&mut writer,
&optimisation_results,
&image,
settings.tile_size,
"HELLO",
)
.expect("Failed to write data");
}
fn optimiser_for_image(image: &Image, tile_size: usize) -> palette16::Palette16Optimiser {

View file

@ -27,6 +27,12 @@ impl Palette16 {
self.colours.push(colour);
true
}
pub fn colour_index(&self, colour: Colour) -> u8 {
self.colours
.iter()
.position(|c| *c == colour)
.expect("Can't get a colour index without it existing") as u8
}
fn union_length(&self, other: &Palette16) -> usize {
self.colours
@ -44,6 +50,15 @@ impl Palette16 {
}
}
impl IntoIterator for Palette16 {
type Item = Colour;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.colours.into_iter()
}
}
pub(crate) struct Palette16Optimiser {
palettes: Vec<Palette16>,
colours: Vec<Colour>,

View file

@ -0,0 +1,80 @@
use std::io;
use std::io::Write;
use crate::image_loader::Image;
use crate::palette16::Palette16OptimisationResults;
use crate::TileSize;
pub(crate) fn generate_code(
output: &mut dyn Write,
results: &Palette16OptimisationResults,
image: &Image,
tile_size: TileSize,
tile_name: &str,
) -> io::Result<()> {
write!(
output,
"pub const {}_PALETTE_DATA: &'static [agb::display::palette16::Palette16] = &[\n",
tile_name
)?;
for palette in &results.optimised_palettes {
write!(output, " agb::display::palette16::Palette16::new([")?;
for colour in palette.clone() {
write!(output, "0x{:08x}, ", colour.to_rgb15())?;
}
write!(output, "]),\n")?;
}
write!(output, "];\n\n")?;
write!(
output,
"pub const {}_TILE_DATA: &'static [u32] = &[\n",
tile_name
)?;
let tile_size = tile_size.to_size();
let tiles_x = image.width / tile_size;
let tiles_y = image.height / tile_size;
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];
write!(
output,
" /* {}, {} (palette index {}) */\n",
x, y, palette_index
)?;
for inner_y in 0..tile_size / 8 {
write!(output, " ")?;
for inner_x in 0..tile_size / 8 {
for j in inner_y * 8..inner_y * 8 + 8 {
write!(output, "0x")?;
for i in (inner_x * 8..inner_x * 8 + 7).rev() {
let colour = image.colour(x * tile_size + i, y * tile_size + j);
let colour_index = palette.colour_index(colour);
write!(output, "{:x}", colour_index)?;
}
write!(output, ", ")?;
}
}
}
write!(output, "\n")?;
}
}
write!(output, "];\n")?;
Ok(())
}

View file

@ -7,6 +7,7 @@ use video::Video;
pub mod bitmap3;
pub mod bitmap4;
pub mod object;
pub mod palette16;
pub mod tiled0;
pub mod vblank;
pub mod video;

View file

@ -0,0 +1,9 @@
pub struct Palette16 {
colours: [u16; 16],
}
impl Palette16 {
pub const fn new(colours: [u16; 16]) -> Self {
Palette16 { colours }
}
}