From 62e0c346c503e26276f8589234bdc27263a1d8d9 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Tue, 20 Apr 2021 22:52:23 +0100 Subject: [PATCH] End-to-end logo working --- agb-image-converter/src/lib.rs | 21 +- agb-image-converter/src/rust_generator.rs | 24 +- agb/Cargo.lock | 324 ++++++++++++++++++++++ agb/Cargo.toml | 3 + agb/build.rs | 10 + agb/gfx/test_logo.png | Bin 1585 -> 1402 bytes agb/src/display/mod.rs | 1 + agb/src/display/palette16.rs | 2 +- agb/src/display/tiled0.rs | 17 +- 9 files changed, 363 insertions(+), 39 deletions(-) diff --git a/agb-image-converter/src/lib.rs b/agb-image-converter/src/lib.rs index 681b1be4..399abb3c 100644 --- a/agb-image-converter/src/lib.rs +++ b/agb-image-converter/src/lib.rs @@ -1,9 +1,6 @@ -use std::fs; use std::fs::File; -use std::io; use std::io::BufWriter; -use std::path::{Path, PathBuf}; -use std::time::SystemTime; +use std::path::PathBuf; mod colour; mod image_loader; @@ -34,19 +31,9 @@ pub struct ImageConverterConfig { pub tile_size: TileSize, pub input_image: PathBuf, pub output_file: PathBuf, - pub output_name: String, } pub fn convert_image(settings: &ImageConverterConfig) { - let source_modified_time = - get_modified_time(&settings.input_image).unwrap_or(SystemTime::now()); - let target_modified_time = - get_modified_time(&settings.output_file).unwrap_or(SystemTime::UNIX_EPOCH); - - if source_modified_time < target_modified_time { - return; - } - let image = Image::load_from_file(&settings.input_image); let tile_size = settings.tile_size.to_size(); @@ -65,7 +52,6 @@ pub fn convert_image(settings: &ImageConverterConfig) { &optimisation_results, &image, settings.tile_size, - &settings.output_name, ) .expect("Failed to write data"); } @@ -94,8 +80,3 @@ fn optimiser_for_image(image: &Image, tile_size: usize) -> palette16::Palette16O palette_optimiser } - -fn get_modified_time(path: impl AsRef) -> io::Result { - let metadata = fs::metadata(path)?; - metadata.modified() -} diff --git a/agb-image-converter/src/rust_generator.rs b/agb-image-converter/src/rust_generator.rs index 1f241f35..bac750c7 100644 --- a/agb-image-converter/src/rust_generator.rs +++ b/agb-image-converter/src/rust_generator.rs @@ -10,31 +10,29 @@ pub(crate) fn generate_code( 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 + "pub const PALETTE_DATA: &'static [crate::display::palette16::Palette16] = &[\n", )?; for palette in &results.optimised_palettes { - write!(output, " agb::display::palette16::Palette16::new([")?; + write!(output, " crate::display::palette16::Palette16::new([")?; for colour in palette.clone() { write!(output, "0x{:08x}, ", colour.to_rgb15())?; } + for _ in palette.clone().into_iter().len()..16 { + write!(output, "0x00000000, ")?; + } + write!(output, "]),\n")?; } write!(output, "];\n\n")?; - write!( - output, - "pub const {}_TILE_DATA: &'static [u32] = &[\n", - tile_name - )?; + write!(output, "pub const TILE_DATA: &'static [u32] = &[\n",)?; let tile_size = tile_size.to_size(); @@ -58,7 +56,7 @@ pub(crate) fn generate_code( for j in inner_y * 8..inner_y * 8 + 8 { write!(output, "0x")?; - for i in (inner_x * 8..inner_x * 8 + 7).rev() { + for i in (inner_x * 8..inner_x * 8 + 8).rev() { let colour = image.colour(x * tile_size + i, y * tile_size + j); let colour_index = palette.colour_index(colour); @@ -76,11 +74,7 @@ pub(crate) fn generate_code( write!(output, "];\n\n")?; - write!( - output, - "pub const {}_PALETTE_ASSIGNMENT: &'static [u8] = &[", - tile_name - )?; + write!(output, "pub const PALETTE_ASSIGNMENT: &'static [u8] = &[")?; for (i, assignment) in results.assignments.iter().enumerate() { if i % 16 == 0 { diff --git a/agb/Cargo.lock b/agb/Cargo.lock index e90be4aa..d18eca59 100644 --- a/agb/Cargo.lock +++ b/agb/Cargo.lock @@ -2,15 +2,339 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "agb" version = "0.1.1" dependencies = [ + "agb_image_converter", "bitflags", ] +[[package]] +name = "agb_image_converter" +version = "0.1.0" +dependencies = [ + "image", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bytemuck" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "gif" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a668f699973d0f573d15749b7002a9ac9e1f9c6b220e7b165601334c173d8de" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "hermit-abi" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +dependencies = [ + "libc", +] + +[[package]] +name = "image" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" +dependencies = [ + "rayon", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" + +[[package]] +name = "memoffset" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "rayon" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "tiff" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" +dependencies = [ + "jpeg-decoder", + "miniz_oxide 0.4.4", + "weezl", +] + +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" diff --git a/agb/Cargo.toml b/agb/Cargo.toml index 571cca77..580036b6 100644 --- a/agb/Cargo.toml +++ b/agb/Cargo.toml @@ -18,3 +18,6 @@ lto = true [dependencies] bitflags = "1.0" + +[build-dependencies] +agb_image_converter = { path = "../agb-image-converter" } \ No newline at end of file diff --git a/agb/build.rs b/agb/build.rs index 47275134..b46c17aa 100644 --- a/agb/build.rs +++ b/agb/build.rs @@ -1,6 +1,9 @@ +use agb_image_converter::{convert_image, Colour, ImageConverterConfig, TileSize}; + fn main() { println!("cargo:rerun-if-changed=crt0.s"); println!("cargo:rerun-if-changed=interrupt_simple.s"); + println!("cargo:rerun-if-changed=gfx/test_logo.png"); let out_file_name = "crt0.o"; let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR environment variable must be specified"); @@ -19,4 +22,11 @@ fn main() { } println!("cargo:rustc-link-search={}", out_dir); + + convert_image(&ImageConverterConfig { + transparent_colour: Some(Colour::from_rgb(1, 1, 1)), + tile_size: TileSize::Tile8, + input_image: "gfx/test_logo.png".into(), + output_file: format!("{}/test_logo.rs", out_dir).into(), + }); } diff --git a/agb/gfx/test_logo.png b/agb/gfx/test_logo.png index 07b3017d537d30bfc7442fdf830ac50e91a7ac43..e0c3f5abf67009552486721c6b39879c9e63ff90 100644 GIT binary patch literal 1402 zcmeAS@N?(olHy`uVBq!ia0vp^AAooP2OE$yy8SQ}NHG=%xjQkeJ16s!fq~V;)5S5Q zV$R#U2fJiLnT~yY-^VDesN2LC`1ppKxR6so6GziC!80j#4aAR)6!Wl4hW2NQ%n$0)g)VztA{5ber=9vqY`d@3WXRUi}_yJtYBe){-UeXSU#~si_HW&!C*RlCpQ)C=!}~KXu2_HJ!W+-t zmhX>#68|Ac`9sj@v~1IF)e@I1s^*)xC1|K2A+wjgGTCzv%FN2N>oh(Yd}gcSQJ$}V z6EP!o@o5idZ&zGNZJWwO4q7N1hzKJg>A9`pa^{ZcFyT_;gHbCYu>Y+}lwe<6VaChUM%2{yKS%eg6IZMg0D(KXzm0fj3tc z-~VUzqv3J$-~Ye2Zd6?{dD|J2lKZQUw6VOiM{^F)X}48w^4UJp=D7xce0%{XW7PUzcbIKo|}K2gXbs<68gvdKrwu-`S14K Qz`~Tl)78&qol`;+0Ik-9#Q*>R literal 1585 zcmeAS@N?(olHy`uVBq!ia0y~yU~~YoKX9-C$wJ+|*+7c1ILO_JVcj{ImkbQ7uRUEH zLn`LHy?by~XsXPyhvnBBRbIGE5SThMvRR;0Nr_{VcgD2^jphQqi(YFS7c>#r)v_Q^ zTp%OiiiUQN5_^`($_(=fX?%7cFK>-`|G8&-_WHfoZra;fzOLVQw{HJ^_5~N1z2`F= z2x1Xfq1xb}%gB<&sSx1J&=|$UaYe{s!88V@t$fp}9^cI~|61YAyXDM3nZ<7Q?{A&Y z*S@vxbC}(FQFPTP24(+JIq^dH(dPLt=KbC0UE8;G&ELA5qqo)<->%)vgvBa^X5DS- z9<#T;Z`}0l^X;y!@z1yIOwE(x=RH4i%1U$C=yN6A{DK6Zh2DH<()_=m< zH@b{D^YI(@I^o-sW4qt~xA4T%AW``5m#=i`pJ_J6-e z^}CzllU3CFWjrU%sd#f<BrLblT`TsmVB<5zFvOs&-ZdQ%AQ4kk0efda^>Mom6H=MpI7nx zSNYUy(v!W1)hDTl@B3-w`RVpiZqG^D;q`u#Vs`(^p7i9#)$5a0*2n&~@htk)I(@Rr zf4l#Flb&=hxA&U#=kHy8&q@6D`zq(${@FSc==JRBDX%`WZkBJhtbh08!s~6HX0#kn z$jjCKUOpxC&fcB(!+;4-`@qzVOnbJjy%T@!X+qhCTWe}3rD?x0J$(1U{sY*PB_dF= zOG&X7s`=#pK0J1Td;NS1nX0=lQaU>)Mq7i!{>?+i@^ko8?N;wi@|6!~8q53C zKE8Nz(#>r~jYd|6Myql+rF{AI_PcXD|GQvNjA1J(pmB1y?nB^rV3ARB;HI$hW?j=p zqpX#lQ*TaIU7Y5>U`_3z^^SzHvjp}=i9$^P7GZ9Je@#X*l{vNZ~E5RzBb~ORW$za#g?X^ zr6oKF_TSg96)M;-efRRA>u;}3+f_%vxBnT~Z-!1_O+NS?SO+k8y85}Sb4q9e0IQ~f ARsaA1 diff --git a/agb/src/display/mod.rs b/agb/src/display/mod.rs index 614c8cdf..456b46c1 100644 --- a/agb/src/display/mod.rs +++ b/agb/src/display/mod.rs @@ -6,6 +6,7 @@ use video::Video; pub mod bitmap3; pub mod bitmap4; +pub mod example_logo; pub mod object; pub mod palette16; pub mod tiled0; diff --git a/agb/src/display/palette16.rs b/agb/src/display/palette16.rs index dd9ecf80..ea653a48 100644 --- a/agb/src/display/palette16.rs +++ b/agb/src/display/palette16.rs @@ -1,5 +1,5 @@ pub struct Palette16 { - colours: [u16; 16], + pub(crate) colours: [u16; 16], } impl Palette16 { diff --git a/agb/src/display/tiled0.rs b/agb/src/display/tiled0.rs index 100deaa0..e220eb44 100644 --- a/agb/src/display/tiled0.rs +++ b/agb/src/display/tiled0.rs @@ -3,8 +3,8 @@ use core::convert::TryInto; use crate::memory_mapped::MemoryMapped1DArray; use super::{ - object::ObjectControl, set_graphics_mode, set_graphics_settings, DisplayMode, GraphicsSettings, - DISPLAY_CONTROL, + object::ObjectControl, palette16, set_graphics_mode, set_graphics_settings, DisplayMode, + GraphicsSettings, DISPLAY_CONTROL, }; const PALETTE_BACKGROUND: MemoryMapped1DArray = @@ -12,7 +12,7 @@ const PALETTE_BACKGROUND: MemoryMapped1DArray = const PALETTE_SPRITE: MemoryMapped1DArray = unsafe { MemoryMapped1DArray::new(0x0500_0200) }; -const TILE_BACKGROUND: MemoryMapped1DArray = +const TILE_BACKGROUND: MemoryMapped1DArray = unsafe { MemoryMapped1DArray::new(0x06000000) }; const TILE_SPRITE: MemoryMapped1DArray = unsafe { MemoryMapped1DArray::new(0x06010000) }; @@ -144,6 +144,17 @@ impl Tiled0 { } } + pub fn set_background_palettes(&mut self, palettes: &[palette16::Palette16]) { + for (palette_index, entry) in palettes.iter().enumerate() { + for (colour_index, &colour) in entry.colours.iter().enumerate() { + self.set_background_palette_entry( + (palette_index * 16 + colour_index) as u8, + colour, + ); + } + } + } + pub fn set_sprite_tilemap(&mut self, tiles: &[u32]) { for (index, &tile) in tiles.iter().enumerate() { self.set_sprite_tilemap_entry(index as u32, tile)