Get first example working

This commit is contained in:
Gwilym Kuiper 2022-08-11 23:48:57 +01:00
parent 916a3d4b20
commit ff89f7f425
6 changed files with 147 additions and 24 deletions

View file

@ -112,13 +112,18 @@ pub fn include_gfx(input: TokenStream) -> TokenStream {
let mut image_code = vec![]; let mut image_code = vec![];
for (image_name, &image) in images.iter() { for (image_name, &image) in images.iter() {
let assignment_offset = match image.colours() {
Colours::Colours16 => Some(assignment_offsets[image_name]),
_ => None,
};
image_code.push(convert_image( image_code.push(convert_image(
image, image,
parent, parent,
image_name, image_name,
&config.crate_prefix(), &config.crate_prefix(),
&optimisation_results, &optimisation_results,
assignment_offsets[image_name], assignment_offset,
)); ));
} }
@ -268,7 +273,7 @@ fn convert_image(
variable_name: &str, variable_name: &str,
crate_prefix: &str, crate_prefix: &str,
optimisation_results: &Palette16OptimisationResults, optimisation_results: &Palette16OptimisationResults,
assignment_offset: usize, assignment_offset: Option<usize>,
) -> 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);
@ -384,6 +389,38 @@ fn add_image_to_tile_data(
} }
} }
fn add_image_256_to_tile_data(
tile_data: &mut Vec<u8>,
image: &Image,
tile_size: TileSize,
optimiser: &Palette16OptimisationResults,
) {
let tile_size = tile_size.to_size();
let tiles_x = image.width / tile_size;
let tiles_y = image.height / tile_size;
let all_colours: Vec<_> = optimiser
.optimised_palettes
.iter()
.flat_map(|p| p.colours())
.collect();
for y in 0..tiles_y {
for x in 0..tiles_x {
for inner_y in 0..tile_size / 8 {
for inner_x in 0..tile_size / 8 {
for j in inner_y * 8..inner_y * 8 + 8 {
for i in inner_x * 8..inner_x * 8 + 8 {
let colour = image.colour(x * tile_size + i, y * tile_size + j);
tile_data.push(all_colours.iter().position(|c| **c == colour).unwrap() as u8);
}
}
}
}
}
}
}
fn flatten_group(expr: &Expr) -> &Expr { fn flatten_group(expr: &Expr) -> &Expr {
match expr { match expr {
Expr::Group(group) => &group.expr, Expr::Group(group) => &group.expr,

View file

@ -1,5 +1,5 @@
use crate::palette16::Palette16OptimisationResults; use crate::palette16::Palette16OptimisationResults;
use crate::{add_image_to_tile_data, collapse_to_4bpp, TileSize}; use crate::{add_image_256_to_tile_data, add_image_to_tile_data, collapse_to_4bpp, TileSize};
use crate::{image_loader::Image, ByteString}; use crate::{image_loader::Image, ByteString};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
@ -14,7 +14,7 @@ pub(crate) fn generate_code(
image_filename: &str, image_filename: &str,
tile_size: TileSize, tile_size: TileSize,
crate_prefix: String, crate_prefix: String,
assignment_offset: usize, assignment_offset: Option<usize>,
) -> 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);
@ -35,23 +35,34 @@ pub(crate) fn generate_code(
} }
}); });
let mut tile_data = Vec::new(); let (tile_data, assignments) = if let Some(assignment_offset) = assignment_offset {
let mut tile_data = Vec::new();
add_image_to_tile_data(&mut tile_data, image, tile_size, results, assignment_offset); add_image_to_tile_data(&mut tile_data, image, tile_size, results, assignment_offset);
let tile_data = collapse_to_4bpp(&tile_data); let tile_data = collapse_to_4bpp(&tile_data);
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();
add_image_256_to_tile_data(&mut tile_data, image, tile_size, results);
(tile_data, vec![])
};
let data = ByteString(&tile_data); let data = ByteString(&tile_data);
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);
quote! { quote! {
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
pub const #output_variable_name: #crate_prefix::display::tile_data::TileData = { pub const #output_variable_name: #crate_prefix::display::tile_data::TileData = {

View file

@ -0,0 +1,69 @@
#![no_std]
#![no_main]
use agb::{
display::{
tiled::{AffineBackgroundSize, TileFormat, TileSet, TiledMap},
Priority,
},
fixnum::{num, Num},
include_gfx,
input::Tri,
};
include_gfx!("examples/affine_tiles.toml");
#[agb::entry]
fn main(mut gba: agb::Gba) -> ! {
let (gfx, mut vram) = gba.display.video.tiled2();
let vblank = agb::interrupt::VBlank::get();
let tileset = TileSet::new(affine_tiles::water_tiles.tiles, TileFormat::EightBpp);
vram.set_background_palettes(affine_tiles::water_tiles.palettes);
let mut bg = gfx.background(Priority::P0, AffineBackgroundSize::Background32x32);
for y in 0..32u16 {
for x in 0..32u16 {
bg.set_tile(&mut vram, (x, y).into(), &tileset, 1);
}
}
bg.commit(&mut vram);
bg.show();
let mut rotation = num!(0.);
let rotation_increase = num!(1.);
let mut input = agb::input::ButtonController::new();
loop {
input.update();
let x_dir = match input.x_tri() {
Tri::Positive => (1, 0).into(),
Tri::Negative => (-1, 0).into(),
_ => (0, 0).into(),
};
let y_dir = match input.y_tri() {
Tri::Positive => (0, 1).into(),
Tri::Negative => (0, -1).into(),
_ => (0, 0).into(),
};
let new_scroll_pos = bg.scroll_pos() + x_dir + y_dir;
agb::println!("{:?}", new_scroll_pos);
bg.set_scroll_pos(new_scroll_pos);
bg.set_transform((0i16, 0i16).into(), (1, 1).into(), rotation);
rotation += rotation_increase;
if rotation >= num!(255.) {
rotation = 0.into();
}
vblank.wait_for_vblank();
bg.commit(&mut vram);
}
}

View file

@ -0,0 +1,6 @@
version = "1.0"
[image.water_tiles]
filename = "water_tiles.png"
tile_size = "8x8"
colours = 256

View file

@ -278,16 +278,16 @@ impl TiledMapPrivate for AffineMap {
&mut self.tiles_dirty &mut self.tiles_dirty
} }
fn x_scroll_mut(&mut self) -> &mut Self::Position { fn x_scroll_mut(&mut self) -> &mut Self::Position {
&mut self.transform.position.x &mut self.bg_center.x
} }
fn y_scroll_mut(&mut self) -> &mut Self::Position { fn y_scroll_mut(&mut self) -> &mut Self::Position {
&mut self.transform.position.y &mut self.bg_center.y
} }
fn x_scroll(&self) -> Self::Position { fn x_scroll(&self) -> Self::Position {
self.transform.position.x self.bg_center.x
} }
fn y_scroll(&self) -> Self::Position { fn y_scroll(&self) -> Self::Position {
self.transform.position.y self.bg_center.y
} }
fn affine_matrix(&self) -> Self::AffineMatrix { fn affine_matrix(&self) -> Self::AffineMatrix {
self.transform.matrix self.transform.matrix
@ -377,7 +377,7 @@ impl AffineMap {
&mut self, &mut self,
display_center: Vector2D<i16>, display_center: Vector2D<i16>,
scale: Vector2D<Num<i16, 8>>, scale: Vector2D<Num<i16, 8>>,
rotation: Num<u8, 8>, rotation: Num<u16, 8>,
) { ) {
self.set_transform_raw(crate::syscall::bg_affine_matrix( self.set_transform_raw(crate::syscall::bg_affine_matrix(
self.bg_center, self.bg_center,

View file

@ -159,21 +159,21 @@ pub fn bg_affine_matrix(
bg_center: Vector2D<Num<i32, 8>>, bg_center: Vector2D<Num<i32, 8>>,
display_center: Vector2D<i16>, display_center: Vector2D<i16>,
scale: Vector2D<Num<i16, 8>>, scale: Vector2D<Num<i16, 8>>,
rotation: Num<u8, 8>, rotation: Num<u16, 8>,
) -> BgAffineSetData { ) -> BgAffineSetData {
#[repr(C, packed)] #[repr(C, packed)]
struct Input { struct Input {
bg_center: Vector2D<Num<i32, 8>>, bg_center: Vector2D<Num<i32, 8>>,
display_center: Vector2D<i16>, display_center: Vector2D<i16>,
scale: Vector2D<Num<i16, 8>>, scale: Vector2D<Num<i16, 8>>,
rotation: u16, rotation: Num<u16, 8>,
} }
let input = Input { let input = Input {
bg_center, bg_center,
display_center, display_center,
scale, scale,
rotation: u16::from(rotation.to_raw()) << 8, rotation,
}; };
let mut output = MaybeUninit::uninit(); let mut output = MaybeUninit::uninit();