diff --git a/agb-image-converter/Cargo.lock b/agb-image-converter/Cargo.lock
index 71a2c9ee..531ab8ed 100644
--- a/agb-image-converter/Cargo.lock
+++ b/agb-image-converter/Cargo.lock
@@ -18,15 +18,29 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
name = "agb_image_converter"
version = "0.6.0"
dependencies = [
+ "asefile",
"image",
"proc-macro2",
"quote",
"serde",
- "serde_json",
"syn",
"toml",
]
+[[package]]
+name = "asefile"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0d5f7de918fd4cb18249819fc4bd27f6a5dbfbc9dcb271727f27dacf17ce880"
+dependencies = [
+ "bitflags",
+ "byteorder",
+ "flate2",
+ "image",
+ "log",
+ "nohash",
+]
+
[[package]]
name = "autocfg"
version = "1.1.0"
@@ -81,6 +95,18 @@ dependencies = [
"adler32",
]
+[[package]]
+name = "flate2"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
+dependencies = [
+ "cfg-if",
+ "crc32fast",
+ "libc",
+ "miniz_oxide 0.4.4",
+]
+
[[package]]
name = "image"
version = "0.24.1"
@@ -97,10 +123,19 @@ dependencies = [
]
[[package]]
-name = "itoa"
-version = "1.0.1"
+name = "libc"
+version = "0.2.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
+checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
[[package]]
name = "miniz_oxide"
@@ -111,6 +146,22 @@ dependencies = [
"adler",
]
+[[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 = "nohash"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0f889fb66f7acdf83442c35775764b51fed3c606ab9cee51500dbde2cf528ca"
+
[[package]]
name = "num-integer"
version = "0.1.44"
@@ -161,7 +212,7 @@ dependencies = [
"bitflags",
"crc32fast",
"deflate",
- "miniz_oxide",
+ "miniz_oxide 0.3.7",
]
[[package]]
@@ -182,12 +233,6 @@ dependencies = [
"proc-macro2",
]
-[[package]]
-name = "ryu"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
-
[[package]]
name = "serde"
version = "1.0.136"
@@ -208,17 +253,6 @@ dependencies = [
"syn",
]
-[[package]]
-name = "serde_json"
-version = "1.0.79"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
[[package]]
name = "syn"
version = "1.0.86"
diff --git a/agb-image-converter/Cargo.toml b/agb-image-converter/Cargo.toml
index 52fdf639..63f41d98 100644
--- a/agb-image-converter/Cargo.toml
+++ b/agb-image-converter/Cargo.toml
@@ -16,4 +16,4 @@ serde = { version = "1.0", features = ["derive"] }
syn = "1.0.86"
proc-macro2 = "1.0.36"
quote = "1.0.15"
-serde_json = "1.0"
\ No newline at end of file
+asefile = "0.3.2"
diff --git a/agb-image-converter/src/aseprite.rs b/agb-image-converter/src/aseprite.rs
index 72a6cbb4..694c0cfd 100644
--- a/agb-image-converter/src/aseprite.rs
+++ b/agb-image-converter/src/aseprite.rs
@@ -1,102 +1,23 @@
-use std::{
- fs::File,
- path::{Path, PathBuf},
- process::Command,
- str,
-};
+use std::path::Path;
+use asefile::{AsepriteFile, Tag};
use image::DynamicImage;
-use serde::Deserialize;
-#[derive(Deserialize)]
-pub struct Aseprite {
- pub frames: Vec,
- pub meta: Meta,
-}
-
-#[derive(Deserialize)]
-pub struct Meta {
- pub app: String,
- pub version: String,
- pub image: String,
- pub format: String,
- pub size: Size,
- pub scale: String,
- #[serde(rename = "frameTags")]
- pub frame_tags: Vec,
-}
-
-#[derive(Deserialize)]
-pub struct Size {
- pub w: u32,
- pub h: u32,
-}
-
-#[derive(Deserialize, Clone, Copy)]
-#[serde(rename_all = "lowercase")]
-pub enum Direction {
- Forward,
- Backward,
- Pingpong,
-}
-
-#[derive(Deserialize, Clone)]
-pub struct FrameTag {
- pub name: String,
- pub from: u32,
- pub to: u32,
- pub direction: Direction,
-}
-
-#[derive(Deserialize, Clone)]
-pub struct Frame {
- pub frame: Frame2,
- pub trimmed: bool,
-}
-
-#[derive(Deserialize, Clone)]
-pub struct Frame2 {
- pub x: u32,
- pub y: u32,
- pub w: u32,
- pub h: u32,
-}
-
-pub fn generate_from_file(filename: &Path) -> (Aseprite, DynamicImage) {
- let out_dir = std::env::var("OUT_DIR").expect("Expected OUT_DIR");
-
- let output_filename = Path::new(&out_dir).join(filename.file_name().unwrap());
-
- let image_output = output_filename.with_extension("png");
- let json_output = output_filename.with_extension("json");
-
- let command = Command::new("aseprite")
- .args([
- &PathBuf::from("-b"),
- &PathBuf::from(filename),
- &"--sheet".into(),
- &image_output,
- &"--format".into(),
- &"json-array".into(),
- &"--data".into(),
- &json_output,
- &"--list-tags".into(),
- ])
- .output()
- .expect("Could not run aseprite");
- assert!(
- command.status.success(),
- "Aseprite did not complete successfully : {}",
- str::from_utf8(&*command.stdout).unwrap_or("Output contains invalid string")
- );
-
- let json: Aseprite = serde_json::from_reader(
- File::open(&json_output).expect("The json output from aseprite could not be openned"),
- )
- .expect("The output from aseprite could not be decoded");
-
- (
- json,
- image::open(image_output).expect("Image should be readable"),
- )
+pub fn generate_from_file(filename: &Path) -> (Vec, Vec) {
+ let ase = AsepriteFile::read_file(filename).expect("Aseprite file should exist");
+
+ let mut images = Vec::new();
+ let mut tags = Vec::new();
+
+ for frame in 0..ase.num_frames() {
+ let image = ase.frame(frame).image();
+
+ images.push(DynamicImage::ImageRgba8(image))
+ }
+
+ for tag in 0..ase.num_tags() {
+ tags.push(ase.tag(tag).clone())
+ }
+
+ (images, tags)
}
diff --git a/agb-image-converter/src/lib.rs b/agb-image-converter/src/lib.rs
index 4c1a93ae..3278147e 100644
--- a/agb-image-converter/src/lib.rs
+++ b/agb-image-converter/src/lib.rs
@@ -16,6 +16,7 @@ mod image_loader;
mod palette16;
mod rust_generator;
+use image::GenericImageView;
use image_loader::Image;
use colour::Colour;
@@ -93,7 +94,6 @@ pub fn include_aseprite_inner(input: TokenStream) -> TokenStream {
let mut optimiser = palette16::Palette16Optimiser::new();
let mut images = Vec::new();
- let mut frames = Vec::new();
let mut tags = Vec::new();
let root = std::env::var("CARGO_MANIFEST_DIR").expect("Failed to get cargo manifest dir");
@@ -105,24 +105,18 @@ pub fn include_aseprite_inner(input: TokenStream) -> TokenStream {
.collect();
for filename in filenames.iter() {
- let (json, image) = aseprite::generate_from_file(filename);
- let tile_size = json.frames[0].frame.w;
+ let (frames, tag) = aseprite::generate_from_file(filename);
- for frame in json.frames.iter() {
- assert!(frame.frame.w == tile_size);
- assert!(
- frame.frame.w == frame.frame.h
- && frame.frame.w.is_power_of_two()
- && frame.frame.w <= 32
- );
+ tags.push((tag, images.len()));
+
+ for frame in frames {
+ let width = frame.width();
+ assert!(width == frame.height() && width.is_power_of_two() && width <= 32);
+
+ let image = Image::load_from_dyn_image(frame);
+ add_to_optimiser(&mut optimiser, &image, width as usize);
+ images.push(image);
}
-
- let image = Image::load_from_dyn_image(image);
-
- add_to_optimiser(&mut optimiser, &image, tile_size as usize);
- images.push(image);
- frames.push(json.frames.clone());
- tags.push(json.meta.frame_tags.clone());
}
let optimised_results = optimiser.optimise_palettes(None);
@@ -138,17 +132,16 @@ pub fn include_aseprite_inner(input: TokenStream) -> TokenStream {
});
let mut pre = 0;
- let sprites = frames
+ let sprites = images
.iter()
- .flatten()
.zip(assignments.iter())
.map(|(f, assignment)| {
let start: usize = pre;
- let end: usize = pre + (f.frame.w as usize / 8) * (f.frame.h as usize / 8) * 32;
+ let end: usize = pre + (f.width / 8) * (f.height / 8) * 32;
let data = ByteString(&tile_data[start..end]);
pre = end;
- let width = f.frame.w as usize;
- let height = f.frame.h as usize;
+ let width = f.width;
+ let height = f.height;
quote! {
Sprite::new(
&PALETTES[#assignment],
@@ -160,15 +153,13 @@ pub fn include_aseprite_inner(input: TokenStream) -> TokenStream {
let tags = tags
.iter()
- .enumerate()
- .map(|(i, tag)| {
- tag.iter().map(move |tag| (i, tag)).map(|(i, tag)| {
- let offset: usize = frames[0..i].iter().map(|s| s.len()).sum();
- let start = tag.from as usize + offset;
- let end = tag.to as usize + offset;
- let direction = tag.direction as usize;
+ .map(|(tag, num_images)| {
+ tag.iter().map(move |tag| {
+ let start = tag.from_frame() as usize + num_images;
+ let end = tag.to_frame() as usize + num_images;
+ let direction = tag.animation_direction() as usize;
- let name = &tag.name;
+ let name = tag.name();
assert!(start <= end, "Tag {} has start > end", name);
quote! {
diff --git a/agb/Cargo.lock b/agb/Cargo.lock
index 3ba21947..017e679b 100644
--- a/agb/Cargo.lock
+++ b/agb/Cargo.lock
@@ -41,11 +41,11 @@ dependencies = [
name = "agb_image_converter"
version = "0.6.0"
dependencies = [
+ "asefile",
"image",
"proc-macro2",
"quote",
"serde",
- "serde_json",
"syn",
"toml",
]
@@ -80,6 +80,20 @@ dependencies = [
"version_check",
]
+[[package]]
+name = "asefile"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0d5f7de918fd4cb18249819fc4bd27f6a5dbfbc9dcb271727f27dacf17ce880"
+dependencies = [
+ "bitflags",
+ "byteorder",
+ "flate2",
+ "image",
+ "log",
+ "nohash",
+]
+
[[package]]
name = "autocfg"
version = "1.1.0"
@@ -140,6 +154,18 @@ dependencies = [
"adler32",
]
+[[package]]
+name = "flate2"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
+dependencies = [
+ "cfg-if",
+ "crc32fast",
+ "libc",
+ "miniz_oxide 0.4.4",
+]
+
[[package]]
name = "getrandom"
version = "0.2.5"
@@ -181,18 +207,21 @@ dependencies = [
"png",
]
-[[package]]
-name = "itoa"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
-
[[package]]
name = "libc"
version = "0.2.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "miniz_oxide"
version = "0.5.1"
@@ -202,6 +231,16 @@ dependencies = [
"adler",
]
+[[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 = "modular-bitfield"
version = "0.11.2"
@@ -223,6 +262,12 @@ dependencies = [
"syn",
]
+[[package]]
+name = "nohash"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0f889fb66f7acdf83442c35775764b51fed3c606ab9cee51500dbde2cf528ca"
+
[[package]]
name = "num-integer"
version = "0.1.44"
@@ -323,7 +368,7 @@ dependencies = [
"bitflags",
"crc32fast",
"deflate",
- "miniz_oxide",
+ "miniz_oxide 0.3.7",
]
[[package]]
@@ -402,12 +447,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
-[[package]]
-name = "ryu"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
-
[[package]]
name = "serde"
version = "1.0.136"
@@ -428,17 +467,6 @@ dependencies = [
"syn",
]
-[[package]]
-name = "serde_json"
-version = "1.0.79"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
[[package]]
name = "siphasher"
version = "0.3.9"