diff options
Diffstat (limited to 'tools/mkasset.py')
-rw-r--r-- | tools/mkasset.py | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/tools/mkasset.py b/tools/mkasset.py index 9b9dc76..a402e3c 100644 --- a/tools/mkasset.py +++ b/tools/mkasset.py | |||
@@ -13,6 +13,7 @@ | |||
13 | import argparse | 13 | import argparse |
14 | import ctypes | 14 | import ctypes |
15 | import sys | 15 | import sys |
16 | from enum import IntEnum | ||
16 | from typing import Generator | 17 | from typing import Generator |
17 | from xml.etree import ElementTree | 18 | from xml.etree import ElementTree |
18 | 19 | ||
@@ -23,6 +24,12 @@ from PIL import Image | |||
23 | MAX_PATH_LENGTH = 128 | 24 | MAX_PATH_LENGTH = 128 |
24 | 25 | ||
25 | 26 | ||
27 | class Orientation(IntEnum): | ||
28 | """Map orientation. Must match Tm_Orientation in asset.h""" | ||
29 | Orthogonal = 0 | ||
30 | Isometric = 1 | ||
31 | |||
32 | |||
26 | def drop_extension(filepath): | 33 | def drop_extension(filepath): |
27 | return filepath[:filepath.rfind('.')] | 34 | return filepath[:filepath.rfind('.')] |
28 | 35 | ||
@@ -51,23 +58,21 @@ def carve_image(rgba_bytes, tile_width, tile_height, columns) -> Generator[bytea | |||
51 | image_width = columns * tile_width | 58 | image_width = columns * tile_width |
52 | image_height = len(rgba_bytes) // image_width // 4 | 59 | image_height = len(rgba_bytes) // image_width // 4 |
53 | 60 | ||
54 | tiles_x = image_width // tile_width | ||
55 | tiles_y = image_height // tile_height | ||
56 | |||
57 | tile_bytes = bytearray(tile_width * tile_height * 4) | 61 | tile_bytes = bytearray(tile_width * tile_height * 4) |
58 | for i in range(tiles_y): | 62 | for image_y0 in range(0, image_height, tile_height): # y-origin of tile inside image |
59 | image_y0 = i * tile_height # y-origin of tile inside image | 63 | for image_x0 in range(0, image_width, tile_width): # x-origin of tile inside image |
60 | for j in range(tiles_x): | ||
61 | image_x0 = j * tile_width # x-origin of tile inside image | ||
62 | for y in range(tile_height): | 64 | for y in range(tile_height): |
63 | image_y = image_y0 + y # y of current pixel inside image | 65 | image_y = image_y0 + y # y of current pixel inside image |
64 | for x in range(tile_width): | 66 | for x in range(tile_width): |
65 | image_x = image_x0 + x # x of current pixel inside image | 67 | image_x = image_x0 + x # x of current pixel inside image |
66 | tile_bytes[(y * tile_width + x) * 4] = ( | 68 | for c in range(4): |
67 | rgba_bytes)[(image_y * image_width + image_x) * 4] | 69 | tile_bytes[((y * tile_width + x) * 4) + c] = ( |
70 | rgba_bytes)[((image_y * image_width + image_x) * 4) + c] | ||
68 | yield tile_bytes.copy() | 71 | yield tile_bytes.copy() |
69 | 72 | ||
70 | 73 | ||
74 | # TODO: Palettize it like we do for sprites. Use 2-byte indices to allow up to | ||
75 | # 65k colours. | ||
71 | def convert_tsx(input_filepath, output_filepath): | 76 | def convert_tsx(input_filepath, output_filepath): |
72 | """Converts a Tiled .tsx tileset file to a .TS tile set file.""" | 77 | """Converts a Tiled .tsx tileset file to a .TS tile set file.""" |
73 | xml = ElementTree.parse(input_filepath) | 78 | xml = ElementTree.parse(input_filepath) |
@@ -183,11 +188,13 @@ def convert_tmx(input_filepath, output_filepath): | |||
183 | base_tile_width = int(root.attrib["tilewidth"]) | 188 | base_tile_width = int(root.attrib["tilewidth"]) |
184 | base_tile_height = int(root.attrib["tileheight"]) | 189 | base_tile_height = int(root.attrib["tileheight"]) |
185 | num_layers = 1 | 190 | num_layers = 1 |
191 | flags = Orientation.Isometric if (root.attrib["orientation"] == "isometric") else Orientation.Orthogonal | ||
186 | 192 | ||
187 | print(f"Map width: {map_width}") | 193 | print(f"Map width: {map_width}") |
188 | print(f"Map height: {map_height}") | 194 | print(f"Map height: {map_height}") |
189 | print(f"Tile width: {base_tile_width}") | 195 | print(f"Tile width: {base_tile_width}") |
190 | print(f"Tile height: {base_tile_height}") | 196 | print(f"Tile height: {base_tile_height}") |
197 | print(f"Orientation: {flags}") | ||
191 | 198 | ||
192 | tileset_path = None | 199 | tileset_path = None |
193 | 200 | ||
@@ -210,6 +217,7 @@ def convert_tmx(input_filepath, output_filepath): | |||
210 | output.write(ctypes.c_uint16(base_tile_width)) | 217 | output.write(ctypes.c_uint16(base_tile_width)) |
211 | output.write(ctypes.c_uint16(base_tile_height)) | 218 | output.write(ctypes.c_uint16(base_tile_height)) |
212 | output.write(ctypes.c_uint16(num_layers)) | 219 | output.write(ctypes.c_uint16(num_layers)) |
220 | output.write(ctypes.c_uint16(flags)) | ||
213 | elif child.tag == "layer": | 221 | elif child.tag == "layer": |
214 | layer = child | 222 | layer = child |
215 | layer_id = int(layer.attrib["id"]) | 223 | layer_id = int(layer.attrib["id"]) |
@@ -349,25 +357,16 @@ def convert_sprite_sheet(input_file_paths, sprite_width, sprite_height, | |||
349 | # that. getcolors() returns the number of unique colors. | 357 | # that. getcolors() returns the number of unique colors. |
350 | # getpalette() also returns a flattened list, which is why we must *4. | 358 | # getpalette() also returns a flattened list, which is why we must *4. |
351 | num_colours = len(im.getcolors()) | 359 | num_colours = len(im.getcolors()) |
352 | colours = im.getpalette(rawmode="RGBA")[:4 * num_colours] | 360 | palette = bytearray(im.getpalette(rawmode="RGBA")[:4 * num_colours]) |
353 | # TODO: This palette list does not seem really necessary. | 361 | assert (num_colours == (len(palette) // 4)) |
354 | # Define palette = bytearray(im.getpalette(...)) | ||
355 | palette = [] | ||
356 | for i in range(0, 4 * num_colours, 4): | ||
357 | palette.append((colours[i], colours[i + 1], colours[i + 2], | ||
358 | colours[i + 3])) | ||
359 | 362 | ||
360 | output.write(ctypes.c_uint16(len(palette))) | 363 | output.write(ctypes.c_uint16(num_colours)) |
361 | output.write(bytearray(colours)) | 364 | output.write(palette) |
362 | 365 | ||
363 | print(f"Sprite width: {sprite_width}") | 366 | print(f"Sprite width: {sprite_width}") |
364 | print(f"Sprite height: {sprite_height}") | 367 | print(f"Sprite height: {sprite_height}") |
365 | print(f"Rows: {len(rows)}") | 368 | print(f"Rows: {len(rows)}") |
366 | print(f"Colours: {len(palette)}") | 369 | print(f"Colours: {num_colours}") |
367 | |||
368 | # print("Palette") | ||
369 | # for i, colour in enumerate(palette): | ||
370 | # print(f"{i}: {colour}") | ||
371 | 370 | ||
372 | for row, num_columns in enumerate(rows): | 371 | for row, num_columns in enumerate(rows): |
373 | output.write(ctypes.c_uint16(num_columns)) | 372 | output.write(ctypes.c_uint16(num_columns)) |