summaryrefslogtreecommitdiff
path: root/tools/mkasset.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mkasset.py')
-rw-r--r--tools/mkasset.py45
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 @@
13import argparse 13import argparse
14import ctypes 14import ctypes
15import sys 15import sys
16from enum import IntEnum
16from typing import Generator 17from typing import Generator
17from xml.etree import ElementTree 18from xml.etree import ElementTree
18 19
@@ -23,6 +24,12 @@ from PIL import Image
23MAX_PATH_LENGTH = 128 24MAX_PATH_LENGTH = 128
24 25
25 26
27class Orientation(IntEnum):
28 """Map orientation. Must match Tm_Orientation in asset.h"""
29 Orthogonal = 0
30 Isometric = 1
31
32
26def drop_extension(filepath): 33def 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.
71def convert_tsx(input_filepath, output_filepath): 76def 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))