1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
use ::map as mapfile;
use anyhow::Error;
use common::{num::Cast, vec};
use log::{info, log};
use ndarray::Array2;
use std::{
collections::{hash_map, HashMap},
fs::File,
mem,
};
pub use mapfile::format;
pub use mapfile::{
format::Tile,
reader::{self, Color, LayerTilemapType},
};
pub const TILE_NUM: u32 = 16;
pub struct Layer {
pub color: Color,
pub image: Option<usize>,
pub tiles: Array2<Tile>,
pub kind: LayerTilemapType,
}
pub struct Map {
pub layers: Vec<Layer>,
pub tilesets: HashMap<Option<usize>, Array2<Color>>,
}
impl Map {
pub fn empty() -> Self {
Self {
layers: Vec::new(),
tilesets: HashMap::new(),
}
}
pub fn load(file: File) -> Result<Self, Error> {
info!("loading map");
let datafile = datafile::Reader::new(file).unwrap();
let mut map = mapfile::Reader::from_datafile(datafile);
let mut layers = vec![];
for group_idx in map.group_indices() {
let group = map.group(group_idx).unwrap();
if group.parallax_x != 100
|| group.parallax_y != 100
|| group.offset_x != 0
|| group.offset_y != 0
|| group.clipping.is_some()
{
continue;
}
for layer_idx in group.layer_indices {
let layer = map.layer(layer_idx).unwrap();
let tilemap = if let reader::LayerType::Tilemap(t) = layer.t {
t
} else {
continue;
};
let normal = if let Some(n) = tilemap.type_.to_normal() {
n
} else {
continue;
};
let tiles = map.layer_tiles(tilemap.tiles(normal.data)).unwrap();
layers.push(Layer {
color: normal.color,
image: normal.image,
kind: tilemap.type_,
tiles,
});
}
}
let mut tilesets = HashMap::new();
for layer in &layers {
match tilesets.entry(layer.image) {
hash_map::Entry::Occupied(_) => {}
hash_map::Entry::Vacant(v) => {
let data = match layer.image {
None => Array2::from_elem(
(1, 1),
Color {
alpha: 255,
red: 255,
blue: 255,
green: 0,
},
),
Some(image_idx) => {
let image = map.image(image_idx).unwrap();
let height = image.height.usize();
let width = image.width.usize();
match image.data {
Some(d) => {
let data = map.image_data(d).unwrap();
if data.len() % mem::size_of::<Color>() != 0 {
panic!("image shape invalid");
}
let data: Vec<Color> = unsafe { vec::transmute(data) };
Array2::from_shape_vec((height, width), data).unwrap()
}
None => {
continue;
// let image_name = map.image_name(image.name)?;
// // WARN? Unknown external image
// // WARN! Wrong dimensions
// str::from_utf8(&image_name).ok()
// .and_then(sanitize)
// .map(&mut external_tileset_loader)
// .transpose()?
// .unwrap_or(None)
// .unwrap_or_else(|| Array2::from_elem((1, 1), Color::white()))
}
}
}
};
v.insert(data);
}
}
}
info!(
"{} layers + {} tilesets loaded",
layers.len(),
tilesets.len()
);
Ok(Self { tilesets, layers })
}
}
|