aseprite_loader/binary/chunks/
tileset.rs1use bitflags::bitflags;
2use nom::{
3 bytes::complete::take,
4 combinator::{cond, flat_map},
5};
6
7use crate::binary::{
8 errors::ParseResult,
9 scalars::{dword, parse_string, short, word, Dword, Short, Word},
10};
11
12#[derive(Debug)]
13pub struct TilesetChunk<'a> {
14 pub id: Dword,
16 pub flags: TilesetFlags,
18 pub number_of_tiles: Dword,
20 pub width: Word,
22 pub height: Word,
24 pub base_index: Short,
31 pub name: &'a str,
33 pub external_file: Option<TilesetExternalFile>,
35 pub tiles: Option<TilesetTiles<'a>>,
37}
38
39#[derive(Debug, Copy, Clone)]
40pub struct TilesetExternalFile {
41 pub external_file_id: Dword,
44 pub tileset_id: Dword,
46}
47
48#[derive(Debug)]
49pub struct TilesetTiles<'a> {
50 pub data: &'a [u8],
53}
54
55bitflags! {
56 #[derive(Debug)]
57 pub struct TilesetFlags: Dword {
58 const EXTERNAL_FILE = 1;
60 const TILES = 2;
62 const TILE_0_EMPTY = 4;
67 const XFLIP = 8;
71 const YFLIP = 16;
73 const DFLIP = 32;
75 }
76}
77
78pub fn parse_tileset_chunk(input: &[u8]) -> ParseResult<'_, TilesetChunk<'_>> {
79 let (input, id) = dword(input)?;
80 let (input, flags) = dword(input)?;
81 let flags = TilesetFlags::from_bits_truncate(flags);
82 let (input, number_of_tiles) = dword(input)?;
83 let (input, width) = word(input)?;
84 let (input, height) = word(input)?;
85 let (input, base_index) = short(input)?;
86 let (input, _) = take(14usize)(input)?;
87 let (input, name) = parse_string(input)?;
88 let (input, external_file) = cond(
89 flags.contains(TilesetFlags::EXTERNAL_FILE),
90 parse_external_file,
91 )(input)?;
92 let (input, tiles) = cond(flags.contains(TilesetFlags::TILES), parse_tiles)(input)?;
93 Ok((
94 input,
95 TilesetChunk {
96 id,
97 flags,
98 number_of_tiles,
99 width,
100 height,
101 base_index,
102 name,
103 external_file,
104 tiles,
105 },
106 ))
107}
108
109pub fn parse_external_file(input: &[u8]) -> ParseResult<'_, TilesetExternalFile> {
110 let (input, external_file_id) = dword(input)?;
111 let (input, tileset_id) = dword(input)?;
112 Ok((
113 input,
114 TilesetExternalFile {
115 external_file_id,
116 tileset_id,
117 },
118 ))
119}
120
121use nom::combinator::map;
122
123pub fn parse_tiles(input: &[u8]) -> ParseResult<'_, TilesetTiles<'_>> {
124 map(flat_map(dword, take), |data| TilesetTiles { data })(input)
125}