annotate tools/tileset/main.cpp @ 126:a8bddc9566b0

Server: make more comprehensive tests
author David Demelier <markand@malikania.fr>
date Fri, 22 Sep 2017 13:03:33 +0200
parents 0addfab87b17
children 4b292c20124c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
99
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * main.cpp -- create malikania tilesets from tiled
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <cassert>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <cerrno>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <cstring>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 #include <fstream>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include <iostream>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 #include <stdexcept>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
25
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 #include <boost/filesystem.hpp>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include <boost/property_tree/xml_parser.hpp>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 #include <json.hpp>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
30
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 #include <malikania/util.hpp>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
32
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 namespace fs = boost::filesystem;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 namespace ptree = boost::property_tree;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
35
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 namespace {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
37
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 * load_tileset
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 * ------------------------------------------------------------------
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 * In tiled maps, tilesets may be bundled in the map itself or can be in an
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 * other file referenced by a path.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 * This function check for the two case and return the XML data.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 ptree::ptree load_tileset(const fs::path& path)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 ptree::ptree xml;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
50
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 ptree::read_xml(path.string(), xml);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
52
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 if (path.extension() == ".tmx") {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 auto tileset = xml.get_child_optional("map.tileset");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
55
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 if (!tileset)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 throw std::runtime_error("no <tileset> node found");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
58
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 // Check if it's external or embeded.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 auto source = tileset->get_optional<std::string>("<xmlattr>.source");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
61
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 if (source) {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 fs::path source_path(*source);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
64
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 if (source_path.is_relative())
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 source_path = path.parent_path() / *source;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
67
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 ptree::read_xml(source_path.string(), xml);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
69
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 xml = xml.get_child("tileset");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 } else
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 xml = *tileset;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 } else
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 xml = xml.get_child("tileset");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
75
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 return xml;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
78
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 * read_tileset_properties
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 * ------------------------------------------------------------------
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 * Extract all properties from the XML and return a JSON object.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 * The XML looks like this:
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 * <tile id="123">
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 * <properties>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 * <property name="abc" value"def" />
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 * </properties>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 * </tile>
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 nlohmann::json read_tileset_properties(const ptree::ptree& tree)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 auto properties = tree.get_child_optional("properties");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 auto json = nlohmann::json::object();
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
97
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 if (properties) {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 for (const auto& prop : *properties) {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 auto name = prop.second.get<std::string>("<xmlattr>.name");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 auto value = prop.second.get<std::string>("<xmlattr>.value");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
102
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 json[name] = value;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
106
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 return json;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
109
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 * save_tileset_properties
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 * ------------------------------------------------------------------
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 * Read properties and add them to the JSON tile description.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 void save_tileset_properties(nlohmann::json& tiles,
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 const std::string& id,
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 const ptree::ptree& tree)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 tiles[id]["properties"] = read_tileset_properties(tree);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
122
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 * read_tileset_collisions
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 * ------------------------------------------------------------------
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 * Extract the collisions from the XML object description.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 * This function is used for rectangle and ellipses because they use the same
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 * attributes.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 nlohmann::json read_tileset_collision(const ptree::ptree& tree)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 auto ret = nlohmann::json::object({
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 { "x", tree.get<double>("<xmlattr>.x") },
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 { "y", tree.get<double>("<xmlattr>.y") },
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 { "width", tree.get<double>("<xmlattr>.width") },
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 { "height", tree.get<double>("<xmlattr>.height") }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 });
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
140
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 if (tree.count("ellipse") > 0)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 ret["type"] = "ellipse";
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 else
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 ret["type"] = "rectangle";
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
145
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 return ret;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
148
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 * read_tileset_collision_polyline
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 * ------------------------------------------------------------------
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 * Extract the collision description from a object of type polyline.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 nlohmann::json read_tileset_collision_polyline(const ptree::ptree& tree)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 auto points = tree.get<std::string>("polyline.<xmlattr>.points");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 auto array = nlohmann::json::array();
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
159
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 for (const auto& p : mlk::util::split(points, " "))
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 array.push_back(std::stod(p));
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
162
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 return {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 { "type", "polyline" },
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 { "points", std::move(array) }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 };
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
168
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 * save_tileset_collisions
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 * ------------------------------------------------------------------
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 * Read the collisions from the given XML tree and save them into the JSON
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 * description.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 void save_tileset_collisions(nlohmann::json& tiles,
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 const std::string& id,
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 const ptree::ptree& tree)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 auto objectgroup = tree.get_child_optional("objectgroup");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
181
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 if (!objectgroup)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 return;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
184
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 auto array = nlohmann::json::array();
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
186
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 for (const auto& obj : *objectgroup) {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 if (obj.first != "object")
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 continue;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
190
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 nlohmann::json collision;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
192
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 * Ellipse and rectangles are defined the same way, only check for
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 * polylines at the moment.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 if (obj.second.count("polyline") > 0)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 collision = read_tileset_collision_polyline(obj.second);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 else
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 collision = read_tileset_collision(obj.second);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
201
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 array.push_back(collision);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
204
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 tiles[id]["collisions"] = std::move(array);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
207
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 /*
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 * save_tileset
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 * ------------------------------------------------------------------
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 *
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 * Save the tileset at the given path from the XML description.
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 */
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 void save_tileset(const fs::path& path, const ptree::ptree& xml)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 std::ofstream out(path.string(), std::ofstream::trunc);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
217
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
218 if (!out)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 throw std::runtime_error(std::strerror(errno));
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
220
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 nlohmann::json json{
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 { "image", xml.get<std::string>("image.<xmlattr>.source") },
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 "cell", {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 { "width", xml.get<int>("<xmlattr>.tilewidth"), },
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 { "height", xml.get<int>("<xmlattr>.tileheight") }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 },
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 };
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
230
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 nlohmann::json tiles = nlohmann::json::object();
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
232
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 for (const auto& p : xml) {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 if (p.first == "tile") {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 auto id = p.second.get<std::string>("<xmlattr>.id");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
236
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 save_tileset_properties(tiles, id, p.second);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 save_tileset_collisions(tiles, id, p.second);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
241
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 if (!tiles.empty())
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 json["tiles"] = tiles;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
244
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 out << json.dump(4) << std::endl;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
247
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 } // !namespace
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
249
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 int main(int argc, char** argv)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 -- argc;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 ++ argv;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
254
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 if (argc < 1) {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 std::cerr << "usage mlk-tileset input.tmx [output.json]" << std::endl;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 std::cerr << " mlk-tileset input.tsx [output.json]" << std::endl;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 return 1;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
260
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 try {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 fs::path input(argv[0]);
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 fs::path output;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
264
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 if (argc >= 2)
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 output = argv[1];
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 else
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 output = fs::path(input).replace_extension(".json");
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
269
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 save_tileset(output, load_tileset(input));
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 } catch (const std::exception& ex) {
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 std::cerr << ex.what() << std::endl;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 return 1;
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 }
0addfab87b17 Common: implement basic tilesets, closes #664
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 }