summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lowlevel/data.rs1
-rw-r--r--src/lowlevel/layer.rs44
-rw-r--r--src/lowlevel/layer_tile.rs73
-rw-r--r--src/lowlevel/map.rs70
-rw-r--r--src/lowlevel/mod.rs42
-rw-r--r--src/lowlevel/objects.draft.rs92
-rw-r--r--src/lowlevel/tileset.rs208
-rw-r--r--src/main.rs8
8 files changed, 506 insertions, 32 deletions
diff --git a/src/lowlevel/data.rs b/src/lowlevel/data.rs
index e2833b5..59a0b3e 100644
--- a/src/lowlevel/data.rs
+++ b/src/lowlevel/data.rs
@@ -1,4 +1,3 @@
-struct LayerData {}
#[derive(Debug, PartialEq)]
/// The encoding used to encode the tile layer data. When used, it can be “base64” and “csv” at the moment.
pub enum Encoding {
diff --git a/src/lowlevel/layer.rs b/src/lowlevel/layer.rs
index ebb6cae..90fbb14 100644
--- a/src/lowlevel/layer.rs
+++ b/src/lowlevel/layer.rs
@@ -1,8 +1,10 @@
-pub struct LayerTile {
- /// Global Tile Id
- pub gid: u32,
-}
+use std::u32;
+
+use rgb::RGBA;
+
+use super::layer_tile::LayerTile;
+#[derive(Debug)]
pub struct LayerChunk {
pub x: u32,
pub y: u32,
@@ -11,7 +13,41 @@ pub struct LayerChunk {
pub data: Vec<LayerTile>,
}
+#[derive(Debug)]
pub enum LayerData {
Tiles(Vec<LayerTile>),
Chunks(Vec<LayerChunk>),
}
+
+#[derive(Debug)]
+pub struct Layer {
+ /// Unique ID of the layer. Each layer that added to a map gets a unique id. Even if a layer is
+ /// deleted, no layer ever gets the same ID. Can not be changed in Tiled. (since Tiled 1.2)
+ pub id: u32,
+ /// The name of the layer. (defaults to “”)
+ pub name: String,
+ /// The x coordinate of the layer in tiles. Defaults to 0 and can not be changed in Tiled.
+ pub x: u32,
+ /// The y coordinate of the layer in tiles. Defaults to 0 and can not be changed in Tiled.
+ pub y: u32,
+ /// The width of the layer in tiles. Always the same as the map width for fixed-size maps.
+ pub width: u32,
+ /// The height of the layer in tiles. Always the same as the map height for fixed-size maps.
+ pub height: u32,
+ /// The opacity of the layer as a value from 0 to 1. Defaults to 1.
+ pub opacity: f32,
+ /// Whether the layer is shown (1) or hidden (0). Defaults to 1.
+ pub visible: bool,
+ /// A tint color that is multiplied with any tiles drawn by this layer in #AARRGGBB or #RRGGBB format (optonal).
+ pub tintcolor: Option<RGBA<u8>>,
+ /// Horizontal offset for this layer in pixels. Defaults to 0. (since 0.14)
+ pub offsetx: u32,
+ /// Vertical offset for this layer in pixels. Defaults to 0. (since 0.14)
+ pub offsety: u32,
+ // /// Horizontal parallax factor for this layer. Defaults to 1. (since 1.5)
+ // pub parallaxx: ?
+ // /// Vertical parallax factor for this layer. Defaults to 1. (since 1.5)
+ // pub parallaxy: ?
+ pub properties: Option<super::property::Properties>,
+ pub data: LayerData,
+}
diff --git a/src/lowlevel/layer_tile.rs b/src/lowlevel/layer_tile.rs
new file mode 100644
index 0000000..bca5daf
--- /dev/null
+++ b/src/lowlevel/layer_tile.rs
@@ -0,0 +1,73 @@
+// Bits on the far end of the 32-bit global tile ID are used for tile flags
+const FLIPPED_HORIZONTALLY_FLAG: u32 = 0x80000000;
+const FLIPPED_VERTICALLY_FLAG: u32 = 0x40000000;
+const FLIPPED_DIAGONALLY_FLAG: u32 = 0x20000000;
+
+#[derive(Debug, Default, PartialEq)]
+pub struct TileFlip {
+ // whether tile is flipped diagonally (should be the first operation)
+ pub diagonally: bool,
+ // whether tile is flipped horizontally (should be the second operation)
+ pub horizontally: bool,
+ // whether tile is flipped vertically (should be the third operation)
+ pub vertically: bool,
+}
+
+impl TileFlip {
+ fn new(diagonally: bool, horizontally: bool, vertically: bool) -> Self {
+ Self {
+ diagonally,
+ horizontally,
+ vertically,
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct LayerTile(u32);
+
+impl LayerTile {
+ /// Global Tile Id
+ pub fn gid(&self) -> u32 {
+ // Clear the flags
+ self.0 & !(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG)
+ }
+
+ pub fn get_flip(&self) -> TileFlip {
+ // Read out the flags
+ TileFlip {
+ diagonally: (self.0 & FLIPPED_DIAGONALLY_FLAG) > 0,
+ horizontally: (self.0 & FLIPPED_HORIZONTALLY_FLAG) > 0,
+ vertically: (self.0 & FLIPPED_VERTICALLY_FLAG) > 0,
+ }
+ }
+}
+
+#[cfg(test)]
+mod test_layer_tile {
+ use crate::lowlevel::{layer_tile::*};
+
+ #[test]
+ fn test_get_flip() {
+ assert_eq!(LayerTile(13).get_flip(), TileFlip::default());
+ assert_eq!(
+ LayerTile(3451 | FLIPPED_DIAGONALLY_FLAG).get_flip(),
+ TileFlip::new(true, false, false)
+ );
+ }
+
+ #[test]
+ fn test_gid() {
+ assert_eq!(LayerTile(5).gid(), 5);
+ assert_eq!(
+ LayerTile(
+ 52 | (FLIPPED_HORIZONTALLY_FLAG
+ | FLIPPED_VERTICALLY_FLAG
+ | FLIPPED_DIAGONALLY_FLAG)
+ )
+ .gid(),
+ 52
+ );
+ assert_eq!(LayerTile(798 | (FLIPPED_DIAGONALLY_FLAG)).gid(), 798);
+ }
+}
diff --git a/src/lowlevel/map.rs b/src/lowlevel/map.rs
index 63cc9e1..9d0b715 100644
--- a/src/lowlevel/map.rs
+++ b/src/lowlevel/map.rs
@@ -1,10 +1,15 @@
+use crate::{ensure_element, ensure_tag_name, get_attribute};
use anyhow::anyhow;
use rgb::RGBA;
+use super::property::Properties;
+use super::tileset::TileSetElement;
+
// https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#map
/// Map orientation
/// Tiled supports “orthogonal”, “isometric”, “staggered” and “hexagonal” (since 0.11).
+#[derive(Debug)]
pub enum MapOrientation {
Orthogonal,
Isometric,
@@ -85,6 +90,7 @@ impl MapOrientation {
/// The order in which tiles on tile layers are rendered.
/// In all cases, the map is drawn row-by-row. (only supported for orthogonal maps at the moment)
+#[derive(Debug)]
pub enum MapRenderOrder {
/// RightDown - The default
RightDown,
@@ -121,6 +127,7 @@ impl MapRenderOrder {
}
/// For staggered and hexagonal maps, determines which axis (“x” or “y”) is staggered. (since 0.11)
+#[derive(Debug)]
pub enum StaggerAxis {
X,
Y,
@@ -144,6 +151,7 @@ impl StaggerAxis {
}
/// For staggered and hexagonal maps, determines whether the “even” or “odd” indexes along the staggered axis are shifted. (since 0.11)
+#[derive(Debug)]
pub enum StaggerIndex {
Even,
Odd,
@@ -166,13 +174,11 @@ impl StaggerIndex {
}
}
+#[derive(Debug)]
pub struct Map {
/// The TMX format version. Was “1.0” so far, and will be incremented to match minor Tiled releases.
pub version: String,
- /// The Tiled version used to save the file (since Tiled 1.0.1). May be a date (for snapshot builds). (optional)
- pub tiled_version: Option<String>,
-
/// Map orientation. Tiled supports “orthogonal”, “isometric”, “staggered” and “hexagonal” (since 0.11).
pub orientation: MapOrientation,
@@ -180,7 +186,7 @@ pub struct Map {
pub render_order: MapRenderOrder,
/// The compression level to use for tile layer data (defaults to -1, which means to use the algorithm default).
- pub compression_level: Option<isize>, // TODO seems optional, please validate
+ pub compression_level: isize,
// The map width in tiles.
pub width: usize,
@@ -214,10 +220,60 @@ pub struct Map {
impl Map {
pub fn from_xml(doc: roxmltree::Document) -> anyhow::Result<Map> {
- doc.root_element();
+ let node = doc.root_element();
+
+ ensure_element!(node);
+ ensure_tag_name!(node, "map");
+
+ let version = get_attribute!(node, "version")?.to_owned();
+
+ let orientation = MapOrientation::from_xml_map_node(&node)?;
+
+ let render_order = MapRenderOrder::from_string(get_attribute!(node, "renderorder")?)?;
- assert!(doc.root_element().has_tag_name("map"));
+ let compression_level = if let Ok(clevel) = get_attribute!(node, "compressionlevel") {
+ clevel.parse()?
+ } else {
+ -1
+ };
+
+ let infinite = if let Ok(inf) = get_attribute!(node, "infinite") {
+ match inf {
+ "1" => true,
+ "0" | _ => false,
+ }
+ } else {
+ false
+ };
+
+ let properties: Properties = match node.children().find(|&c| c.has_tag_name("properties")) {
+ Some(child_node) => Properties::from_xml(child_node)?,
+ None => Properties::default(),
+ };
+
+ let mut tilesets = Vec::new();
+
+ for tileset_node in node.children().filter(|n| n.has_tag_name("tileset")) {
+ println!("->{:?}", &tileset_node);
+ tilesets.push(TileSetElement::from_xml(tileset_node)?);
+ }
- Err(anyhow!("not implemented"))
+ Ok(Map {
+ version,
+ orientation,
+ render_order,
+ compression_level,
+ width: get_attribute!(node, "width")?.parse()?,
+ height: get_attribute!(node, "height")?.parse()?,
+ tile_width: get_attribute!(node, "tilewidth")?.parse()?,
+ tile_height: get_attribute!(node, "tileheight")?.parse()?,
+ background_color: None, // TODO
+ next_layer_id: 4242, // TODO
+ next_object_id: 4242, // TODO
+ infinite,
+ properties,
+ tilesets,
+ layer: vec![], // TODO
+ })
}
}
diff --git a/src/lowlevel/mod.rs b/src/lowlevel/mod.rs
index 824c693..2eb951e 100644
--- a/src/lowlevel/mod.rs
+++ b/src/lowlevel/mod.rs
@@ -1,3 +1,9 @@
+use anyhow::{anyhow, bail};
+
+use crate::get_attribute;
+
+use self::tileset::TileSetElement;
+
pub mod map;
pub mod property;
@@ -9,7 +15,41 @@ pub mod image;
pub mod data;
pub mod layer;
+pub mod layer_tile;
pub(crate) mod macros;
-pub mod wangset; \ No newline at end of file
+pub mod wangset;
+
+pub fn parse_map(input: &str) -> anyhow::Result<map::Map> {
+ let doc = roxmltree::Document::parse(input).unwrap();
+ map::Map::from_xml(doc)
+}
+
+pub fn parse_tileset(input: &str) -> anyhow::Result<tileset::TileSet> {
+ let doc = roxmltree::Document::parse(input).unwrap();
+ let elem = doc.root_element();
+ tileset::TileSet::from_xml(&elem)
+}
+
+pub fn get_tile_set_elements_from_map(input: &str) -> anyhow::Result<Vec<tileset::TileSetElement>> {
+ let doc = roxmltree::Document::parse(input).unwrap();
+ let node = doc.root_element();
+ let mut tilesets = Vec::new();
+ for tileset_node in node.children().filter(|n| n.has_tag_name("tileset")) {
+ tilesets.push(TileSetElement::from_xml(tileset_node)?);
+ }
+ Ok(tilesets)
+}
+
+/// The Tiled version used to save the file (since Tiled 1.0.1). May be a date (for snapshot builds). (optional)
+fn parse_tiled_version(node: &roxmltree::Node) -> anyhow::Result<Option<String>> {
+ if !node.is_root() {
+ bail!("not a root node")
+ }
+
+ Ok(match get_attribute!(node, "tiledversion") {
+ Ok(v) => Some(v.to_owned()),
+ Err(_) => None,
+ })
+}
diff --git a/src/lowlevel/objects.draft.rs b/src/lowlevel/objects.draft.rs
new file mode 100644
index 0000000..9416e27
--- /dev/null
+++ b/src/lowlevel/objects.draft.rs
@@ -0,0 +1,92 @@
+enum TextHAlign {
+ Left,
+ Center,
+ Right,
+ Justify,
+}
+
+impl Default for TextHAlign {
+ fn default() -> Self {
+ TextHAlign::Left
+ }
+}
+
+enum TextVAlign {
+ Top,
+ Center,
+ Bottom,
+}
+
+impl Default for TextVAlign {
+ fn default() -> Self {
+ TextVAlign::Top
+ }
+}
+
+enum Object {
+ Tile {
+ gid: usize,
+ },
+ Ellipse,
+ Point,
+ Polygon {
+ points: Vec<(i64, i64)>,
+ },
+ Polyline {
+ points: Vec<(i64, i64)>,
+ },
+ Text {
+ /// The font family used (defaults to “sans-serif”)
+ fonfamily: String,
+ /// The size of the font in pixels (not using points, because other sizes in the TMX format are also using pixels) (defaults to 16)
+ pixelsize: u32,
+
+ /// Whether word wrapping is enabled (1) or disabled (0). (defaults to 0)
+ wrap: bool,
+
+ /// Color of the text in #AARRGGBB or #RRGGBB format (defaults to #000000)
+ color: rgb::RGBA8,
+
+ /// Whether the font is bold (1) or not (0). (defaults to 0)
+ bold: bool,
+ /// Whether the font is italic (1) or not (0). (defaults to 0)
+ italic: bool,
+ /// Whether a line should be drawn below the text (1) or not (0). (defaults to 0)
+ underline: bool,
+ /// Whether a line should be drawn through the text (1) or not (0). (defaults to 0)
+ strikeout: bool,
+ /// Whether kerning should be used while rendering the text (1) or not (0). (defaults to 1)
+ kerning: bool,
+
+ /// Horizontal alignment of the text within the object ( left, center, right or justify, defaults to left) (since Tiled 1.2.1)
+ halign: TextHAlign,
+ /// Vertical alignment of the text within the object ( top, center or bottom, defaults to top)
+ valign: TextVAlign,
+ },
+}
+
+struct BaseObject {
+ object: Object,
+ /// Unique ID of the object. Each object that is placed on a map gets a unique id. Even if an object was deleted, no object gets the same ID. Can not be changed in Tiled. (since Tiled 0.11)
+ id: usize,
+ /// The name of the object. An arbitrary string. (defaults to “”)
+ name: String,
+ /// The type of the object. An arbitrary string. (defaults to “”)
+ r#type: String,
+ /// The x coordinate of the object in pixels. (defaults to 0)
+ x: u64,
+ /// The y coordinate of the object in pixels. (defaults to 0)
+ y: u64,
+ /// The width of the object in pixels. (defaults to 0)
+ width: u64,
+ /// The height of the object in pixels. (defaults to 0)
+ height: u64,
+ /// The rota�on of the object in degrees clockwise around (x, y). (defaults to 0)
+ rotation: ?,
+ /// Whether the object is shown (1) or hidden (0). (defaults to 1)
+ visible: bool,
+ /// A reference to a template file. (op�onal)
+ template: Option<String>
+}
+
+// todo ask in tiled discord if representation is ok
diff --git a/src/lowlevel/tileset.rs b/src/lowlevel/tileset.rs
index 9db86c8..ab96af4 100644
--- a/src/lowlevel/tileset.rs
+++ b/src/lowlevel/tileset.rs
@@ -1,5 +1,5 @@
use crate::{ensure_element, ensure_tag_name, get_attribute};
-use anyhow::anyhow;
+use anyhow::{anyhow, bail, Context};
use super::image::Image;
use super::property::Properties;
@@ -49,10 +49,10 @@ impl ObjectAlignment {
#[derive(Debug, PartialEq)]
pub struct Frame {
/// The local ID of a tile within the parent <tileset>.
- tileid: u32,
+ pub tileid: u32,
// How long (in milliseconds) this frame should be displayed before advancing to the next frame.
- duration: u32,
+ pub duration: u32,
}
impl Frame {
@@ -413,7 +413,7 @@ pub struct Terrain {
/// The name of the terrain type.
pub name: String,
/// The local tile-id of the tile that represents the terrain visually.
- pub tile: u32,
+ pub tile: i32, // TODO find out why `-1` is allowed here and maybe if there is a better way to represent it in rust?
pub properties: Properties,
}
@@ -437,7 +437,6 @@ impl Terrain {
}
}
-
/// This element is used to describe which transformations can be applied to the tiles
/// (e.g. to extend a Wang set by transforming existing tiles).
#[derive(PartialEq, Debug)]
@@ -538,6 +537,9 @@ mod test_transformations {
#[derive(Debug, PartialEq)]
pub struct TileSet {
+ /// The TSX format version.
+ pub version: Option<String>,
+
/// The name of this tileset.
pub name: String,
/// The (maximum) width of the tiles in this tileset.
@@ -579,10 +581,10 @@ pub struct TileSet {
pub properties: super::property::Properties,
- pub terrain_types: Option<Vec<Terrain>>,
+ pub terrain_types: Vec<Terrain>,
/// (since 1.1)
- pub wangsets: Option<Vec<WangSet>>,
+ pub wangsets: Vec<WangSet>,
/// (since 1.5)
pub transformations: TileSetTransformations,
@@ -637,22 +639,116 @@ impl TileSet {
None => TileSetTransformations::default(),
};
+ let mut wangsets = Vec::new();
+
+ if let Some(wangsets_node) = node.children().find(|&c| c.has_tag_name("wangsets")) {
+ for wangset_node in wangsets_node
+ .children()
+ .filter(|n| n.has_tag_name("wangset"))
+ {
+ wangsets.push(WangSet::from_xml(wangset_node)?);
+ }
+ }
+
+ let mut terrain_types = Vec::new();
+
+ if let Some(terraintypes_node) = node.children().find(|&c| c.has_tag_name("terraintypes")) {
+ for terrain_node in terraintypes_node
+ .children()
+ .filter(|n| n.has_tag_name("terrain"))
+ {
+ terrain_types.push(Terrain::from_xml(terrain_node).with_context(|| {
+ format!("Failed to parse terraintype from:\n{:?}", terrain_node,)
+ })?);
+ }
+ }
+
+ let version = if let Ok(v) = get_attribute!(node, "version") {
+ Some(v.to_owned())
+ } else {
+ None
+ };
+
+ let tile_width = get_attribute!(node, "tilewidth")?.parse()?;
+ let tile_height = get_attribute!(node, "tileheight")?.parse()?;
+
+ let tile_count: usize = match get_attribute!(node, "tilecount") {
+ Ok(tc_string) => tc_string.parse()?,
+ Err(err) => {
+ if let Some(img) = &image {
+ // there is no tilecount, but an image so we can guess/calculate the tilecount
+ // TODO TEST for this
+ if spacing != 0 {
+ bail!("tilecount not set, and calculationg it with spacing enabled is not implemented yet.");
+ }
+
+ if let Some(image_width) = img.width {
+ if let Some(image_heigth) = img.height {
+ let real_tile_with = tile_width + (margin * 2);
+ let real_tile_height = tile_height + (margin * 2);
+
+ let columns = image_width / real_tile_with;
+ let rows = image_heigth / real_tile_height;
+ columns * rows
+ } else {
+ bail!("tilecount not set, calculating failed: image has no height");
+ }
+ } else {
+ bail!("tilecount not set, calculating failed: image has no width");
+ }
+ } else {
+ return Err(err);
+ }
+ }
+ };
+
+ let columns: usize = match get_attribute!(node, "columns") {
+ Ok(c) => c.parse()?,
+ Err(err) => {
+ if let Some(img) = &image {
+ // there is no columns attribute, but an image so we can guess/calculate the columns
+ // TODO TEST for this
+ if spacing != 0 {
+ bail!("columns not set, and calculationg it with spacing enabled is not implemented yet.");
+ }
+
+ if let Some(image_width) = img.width {
+ if let Some(image_heigth) = img.height {
+ let real_tile_with = tile_width + (margin * 2);
+ let real_tile_height = tile_height + (margin * 2);
+
+ let columns = image_width / real_tile_with;
+ let rows = image_heigth / real_tile_height;
+ columns * rows
+ } else {
+ bail!("columns not set, calculating failed: image has no height");
+ }
+ } else {
+ bail!("columns not set, calculating failed: image has no width");
+ }
+ } else {
+ return Err(err);
+ }
+ }
+ };
+
Ok(TileSet {
+ version,
name: get_attribute!(node, "name")?.to_owned(),
- tile_width: get_attribute!(node, "tilewidth")?.parse()?,
- tile_height: get_attribute!(node, "tileheight")?.parse()?,
+ tile_width,
+ tile_height,
spacing,
margin,
- tile_count: get_attribute!(node, "tilecount")?.parse()?,
- columns: get_attribute!(node, "columns")?.parse()?,
+ tile_count,
+ columns,
object_alignment,
tile: tiles,
image,
tile_offset,
grid,
properties,
- terrain_types: None, // TODO
- wangsets: None, // TODO
+ terrain_types,
+ wangsets,
transformations,
})
}
@@ -673,6 +769,7 @@ mod test_tileset {
assert_eq!(
tile_set,
TileSet {
+ version: None,
name: "beach_tileset".to_owned(),
tile_width: 16,
tile_height: 16,
@@ -742,8 +839,8 @@ mod test_tileset {
tile_offset: TileOffset::default(),
grid: None,
properties: Properties::default(),
- terrain_types: None,
- wangsets: None,
+ terrain_types: vec![],
+ wangsets: vec![],
transformations: TileSetTransformations::default()
}
);
@@ -752,7 +849,88 @@ mod test_tileset {
// todo more tests
}
+/// represents a tileset element inside of a tilemap
+#[derive(Debug, PartialEq)]
pub enum TileSetElement {
Embedded { first_gid: usize, tileset: TileSet },
External { first_gid: usize, source: String },
}
+
+impl TileSetElement {
+ pub fn from_xml(node: roxmltree::Node) -> anyhow::Result<TileSetElement> {
+ ensure_element!(node);
+ ensure_tag_name!(node, "tileset");
+
+ let first_gid = get_attribute!(node, "firstgid")?.parse()?;
+
+ if let Ok(source) = get_attribute!(node, "source") {
+ Ok(TileSetElement::External {
+ first_gid,
+ source: source.to_owned(),
+ })
+ } else {
+ Ok(TileSetElement::Embedded {
+ first_gid,
+ tileset: TileSet::from_xml(&node)?,
+ })
+ }
+ }
+}
+
+#[cfg(test)]
+mod test_tileset_element {
+ use crate::lowlevel::image::*;
+ use crate::lowlevel::tileset::*;
+
+ #[test]
+ fn embedded_tilemap() {
+ crate::parse_property_test!(
+ TileSetElement,
+ r##"<tileset firstgid="1" name="hex mini" tilewidth="18" tileheight="18" tilecount="20" columns="5">
+ <tileoffset x="0" y="1"/>
+ <image source="hexmini.png" width="106" height="72"/>
+ </tileset>"##,
+ TileSetElement::Embedded {
+ first_gid: 1,
+ tileset: TileSet {
+ version: None,
+ name: "hex mini".to_owned(),
+ tile_width: 18,
+ tile_height: 18,
+ tile_offset: TileOffset { x: 0, y: 1 },
+ terrain_types: vec![],
+ wangsets: vec![],
+ spacing: 0,
+ margin: 0,
+ tile_count: 20,
+ columns: 5,
+ object_alignment: ObjectAlignment::default(),
+ tile: vec![],
+ image: Some(Image {
+ source: ImageSource::External {
+ source: "hexmini.png".to_owned()
+ },
+ transparent_color: None,
+ width: Some(106),
+ height: Some(72)
+ }),
+ grid: None,
+ properties: Properties::default(),
+ transformations: TileSetTransformations::default(),
+ }
+ }
+ );
+ }
+
+ #[test]
+ fn external_tilemap() {
+ crate::parse_property_test!(
+ TileSetElement,
+ r##"<tileset firstgid="1" source="beach_tileset.tsx"/>"##,
+ TileSetElement::External {
+ first_gid: 1,
+ source: "beach_tileset.tsx".to_owned()
+ }
+ );
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index ee455d9..1fab2ec 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,8 +7,8 @@ use std::{fs::File, usize};
mod lowlevel;
-fn main1() -> anyhow::Result<()> {
- let file = File::open("./testing_data/tiled_examples/desert.tmx")?;
+fn main1() -> anyhow::Result<lowlevel::map::Map> {
+ let file = File::open("./testing_data/018-4.tmx")?;
let mut reader = BufReader::new(file);
let mut string = "".to_owned();
@@ -22,9 +22,9 @@ fn main1() -> anyhow::Result<()> {
println!("{:?}", t);
}
- let map = lowlevel::map::Map::from_xml(doc);
+ let map = lowlevel::map::Map::from_xml(doc)?;
- Ok(())
+ Ok(map)
}
fn main() {