mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
Get first example working
This commit is contained in:
parent
916a3d4b20
commit
ff89f7f425
|
@ -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,
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
69
agb/examples/affine_background.rs
Normal file
69
agb/examples/affine_background.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
6
agb/examples/affine_tiles.toml
Normal file
6
agb/examples/affine_tiles.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
version = "1.0"
|
||||||
|
|
||||||
|
[image.water_tiles]
|
||||||
|
filename = "water_tiles.png"
|
||||||
|
tile_size = "8x8"
|
||||||
|
colours = 256
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue