diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/mkasset.py | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/tools/mkasset.py b/tools/mkasset.py index a402e3c..1be0573 100644 --- a/tools/mkasset.py +++ b/tools/mkasset.py | |||
@@ -12,6 +12,7 @@ | |||
12 | # | 12 | # |
13 | import argparse | 13 | import argparse |
14 | import ctypes | 14 | import ctypes |
15 | import struct | ||
15 | import sys | 16 | import sys |
16 | from enum import IntEnum | 17 | from enum import IntEnum |
17 | from typing import Generator | 18 | from typing import Generator |
@@ -80,7 +81,8 @@ def convert_tsx(input_filepath, output_filepath): | |||
80 | assert (tileset.tag == "tileset") | 81 | assert (tileset.tag == "tileset") |
81 | 82 | ||
82 | # Header. | 83 | # Header. |
83 | tileset_tile_count = int(tileset.attrib["tilecount"]) | 84 | # +1 for the 0-tile. |
85 | tileset_tile_count = int(tileset.attrib["tilecount"]) + 1 | ||
84 | tileset_tile_width = int(tileset.attrib["tilewidth"]) | 86 | tileset_tile_width = int(tileset.attrib["tilewidth"]) |
85 | tileset_tile_height = int(tileset.attrib["tileheight"]) | 87 | tileset_tile_height = int(tileset.attrib["tileheight"]) |
86 | 88 | ||
@@ -88,17 +90,14 @@ def convert_tsx(input_filepath, output_filepath): | |||
88 | print(f"Tile width: {tileset_tile_width}") | 90 | print(f"Tile width: {tileset_tile_width}") |
89 | print(f"Tile height: {tileset_tile_height}") | 91 | print(f"Tile height: {tileset_tile_height}") |
90 | 92 | ||
91 | pixels = [] # List of byte arrays | 93 | pixels = bytearray() |
92 | pixels_offset = 0 | ||
93 | 94 | ||
94 | def output_tile(output, tile_width, tile_height, tile_image_bytes): | 95 | def output_tile(output, tile_width, tile_height, tile_image_bytes): |
95 | # Expecting RGBA pixels. | 96 | # Expecting RGBA pixels. |
96 | assert (len(tile_image_bytes) == (tile_width * tile_height * 4)) | 97 | assert (len(tile_image_bytes) == (tile_width * tile_height * 4)) |
97 | 98 | ||
98 | nonlocal pixels_offset | 99 | tile_pixels_offset = len(pixels) |
99 | tile_pixels_offset = pixels_offset | 100 | pixels.extend(tile_image_bytes) |
100 | pixels.append(tile_image_bytes) | ||
101 | pixels_offset += len(tile_image_bytes) | ||
102 | 101 | ||
103 | output.write(ctypes.c_uint16(tile_width)) | 102 | output.write(ctypes.c_uint16(tile_width)) |
104 | output.write(ctypes.c_uint16(tile_height)) | 103 | output.write(ctypes.c_uint16(tile_height)) |
@@ -111,6 +110,10 @@ def convert_tsx(input_filepath, output_filepath): | |||
111 | output.write(ctypes.c_uint16(tileset_tile_height)) | 110 | output.write(ctypes.c_uint16(tileset_tile_height)) |
112 | output.write(ctypes.c_uint16(0)) # Pad. | 111 | output.write(ctypes.c_uint16(0)) # Pad. |
113 | 112 | ||
113 | # Write the 0-tile, which denotes "no tile", at index 0. | ||
114 | zero_pixels = bytes(tileset_tile_width * tileset_tile_height * 4) | ||
115 | output_tile(output, tileset_tile_width, tileset_tile_height, zero_pixels) | ||
116 | |||
114 | # A tileset made up of multiple images contains various 'tile' children, | 117 | # A tileset made up of multiple images contains various 'tile' children, |
115 | # each with their own 'image': | 118 | # each with their own 'image': |
116 | # | 119 | # |
@@ -174,8 +177,7 @@ def convert_tsx(input_filepath, output_filepath): | |||
174 | output_tile(output, tile_width, tile_height, image_bytes) | 177 | output_tile(output, tile_width, tile_height, image_bytes) |
175 | 178 | ||
176 | # Write the pixel data. | 179 | # Write the pixel data. |
177 | for bytes in pixels: | 180 | output.write(pixels) |
178 | output.write(bytes) | ||
179 | 181 | ||
180 | 182 | ||
181 | def convert_tmx(input_filepath, output_filepath): | 183 | def convert_tmx(input_filepath, output_filepath): |
@@ -187,8 +189,10 @@ def convert_tmx(input_filepath, output_filepath): | |||
187 | map_height = int(root.attrib["height"]) | 189 | map_height = int(root.attrib["height"]) |
188 | base_tile_width = int(root.attrib["tilewidth"]) | 190 | base_tile_width = int(root.attrib["tilewidth"]) |
189 | base_tile_height = int(root.attrib["tileheight"]) | 191 | base_tile_height = int(root.attrib["tileheight"]) |
190 | num_layers = 1 | ||
191 | flags = Orientation.Isometric if (root.attrib["orientation"] == "isometric") else Orientation.Orthogonal | 192 | flags = Orientation.Isometric if (root.attrib["orientation"] == "isometric") else Orientation.Orthogonal |
193 | firstgid = 1 | ||
194 | layers = [] | ||
195 | tileset_path = "" | ||
192 | 196 | ||
193 | print(f"Map width: {map_width}") | 197 | print(f"Map width: {map_width}") |
194 | print(f"Map height: {map_height}") | 198 | print(f"Map height: {map_height}") |
@@ -196,8 +200,6 @@ def convert_tmx(input_filepath, output_filepath): | |||
196 | print(f"Tile height: {base_tile_height}") | 200 | print(f"Tile height: {base_tile_height}") |
197 | print(f"Orientation: {flags}") | 201 | print(f"Orientation: {flags}") |
198 | 202 | ||
199 | tileset_path = None | ||
200 | |||
201 | with open(output_filepath, 'bw') as output: | 203 | with open(output_filepath, 'bw') as output: |
202 | for child in root: | 204 | for child in root: |
203 | if child.tag == "tileset": | 205 | if child.tag == "tileset": |
@@ -205,19 +207,12 @@ def convert_tmx(input_filepath, output_filepath): | |||
205 | 207 | ||
206 | tileset = child | 208 | tileset = child |
207 | tileset_path = tileset.attrib["source"] | 209 | tileset_path = tileset.attrib["source"] |
210 | firstgid = int(tileset.attrib["firstgid"]) | ||
208 | 211 | ||
209 | print(f"Tile set: {tileset_path}") | 212 | print(f"Tile set: {tileset_path}") |
210 | 213 | ||
211 | tileset_path = tileset_path.replace("tsx", "ts") | 214 | tileset_path = tileset_path.replace("tsx", "ts") |
212 | 215 | ||
213 | # Write the header. | ||
214 | output.write(to_char_array(tileset_path, MAX_PATH_LENGTH)) | ||
215 | output.write(ctypes.c_uint16(map_width)) | ||
216 | output.write(ctypes.c_uint16(map_height)) | ||
217 | output.write(ctypes.c_uint16(base_tile_width)) | ||
218 | output.write(ctypes.c_uint16(base_tile_height)) | ||
219 | output.write(ctypes.c_uint16(num_layers)) | ||
220 | output.write(ctypes.c_uint16(flags)) | ||
221 | elif child.tag == "layer": | 216 | elif child.tag == "layer": |
222 | layer = child | 217 | layer = child |
223 | layer_id = int(layer.attrib["id"]) | 218 | layer_id = int(layer.attrib["id"]) |
@@ -238,12 +233,27 @@ def convert_tmx(input_filepath, output_filepath): | |||
238 | 233 | ||
239 | csv = data.text.strip() | 234 | csv = data.text.strip() |
240 | rows = csv.split('\n') | 235 | rows = csv.split('\n') |
236 | tiles = bytearray() | ||
241 | for row in rows: | 237 | for row in rows: |
242 | tile_ids = [x.strip() for x in row.split(',') if x] | 238 | tile_ids = [x.strip() for x in row.split(',') if x] |
243 | for tile_id in tile_ids: | 239 | for tile_id in tile_ids: |
244 | # TODO: We need to handle 'firsgid' in TMX files. | 240 | # Subtract firstgid and then add 1 to make tiles 1-based. |
245 | # For now, assume it's 1 and do -1 to make the tiles 0-based. | 241 | tile_id = int(tile_id) - firstgid + 1 |
246 | output.write(ctypes.c_uint16(int(tile_id) - 1)) | 242 | tiles.extend(struct.pack("=h", tile_id)) |
243 | layers.append(tiles) | ||
244 | |||
245 | # Write the header. | ||
246 | output.write(to_char_array(tileset_path, MAX_PATH_LENGTH)) | ||
247 | output.write(ctypes.c_uint16(map_width)) | ||
248 | output.write(ctypes.c_uint16(map_height)) | ||
249 | output.write(ctypes.c_uint16(base_tile_width)) | ||
250 | output.write(ctypes.c_uint16(base_tile_height)) | ||
251 | output.write(ctypes.c_uint16(len(layers))) | ||
252 | output.write(ctypes.c_uint16(flags)) | ||
253 | |||
254 | # Write the layers. | ||
255 | for layer in layers: | ||
256 | output.write(layer) | ||
247 | 257 | ||
248 | 258 | ||
249 | def get_num_cols(image, sprite_width): | 259 | def get_num_cols(image, sprite_width): |