• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

32blit / 32blit-tools / 11014211359

24 Sep 2024 12:54PM UTC coverage: 86.139% (+0.04%) from 86.102%
11014211359

Pull #105

github

web-flow
Merge 17865e311 into bce129050
Pull Request #105: Tilemap layer names

1274 of 1479 relevant lines covered (86.14%)

0.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.08
src/ttblit/asset/builders/map.py
1
import logging
1✔
2
import struct
1✔
3

4
import click
1✔
5

6
from ..builder import AssetBuilder, AssetTool
1✔
7
from .raw import csv_to_list
1✔
8

9
map_typemap = {
1✔
10
    'tiled': {
11
        '.tmx': True,
12
        '.raw': False,
13
    },
14
}
15

16

17
def tiled_to_binary(data, empty_tile, output_struct):
1✔
18
    from xml.etree import ElementTree as ET
1✔
19
    root = ET.fromstring(data)
1✔
20
    layers = root.findall('layer')
1✔
21
    layer_data = []
1✔
22
    transform_data = []
1✔
23
    layer_names = []
1✔
24
    # Sort layers by ID (since .tmx files can have them in arbitrary orders)
25
    layers.sort(key=lambda l: int(l.get('id')))
1✔
26

27
    use_16bits = False
1✔
28

29
    for layer_csv in layers:
1✔
30
        raw_layer = csv_to_list(layer_csv.find('data').text, 10)
1✔
31
        # Shift 1-indexed tiles to 0-indexed, and remap empty tile (0) to specified index
32
        # The highest three bits store the transform
33
        layer = [empty_tile if i == 0 else (i & 0x1FFFFFFF) - 1 for i in raw_layer]
1✔
34

35
        # This matches the flags used by the TileMap class, but doesn't match SpriteTransform...
36
        layer_transforms = [i >> 29 for i in raw_layer]
1✔
37

38
        if max(layer) > 255 and not use_16bits:
1✔
39
            # Let's assume it's got 2-byte tile indices
40
            logging.info('Found a tile index > 255, using 16bit tile sizes!')
1✔
41
            use_16bits = True
1✔
42

43
        # Always build up a 1d array of layer data
44
        layer_data += layer
1✔
45
        transform_data += layer_transforms
1✔
46

47
        layer_names.append(layer_csv.attrib['name'])
1✔
48

49
    if use_16bits:
1✔
50
        layer_data = struct.pack(f'<{len(layer_data)}H', *layer_data)
1✔
51
    else:
52
        layer_data = struct.pack(f'<{len(layer_data)}B', *layer_data)
1✔
53

54
    if output_struct:  # Fancy struct
1✔
55
        layer_count = len(layers)
1✔
56
        width = int(root.get("width"))
1✔
57
        height = int(root.get("height"))
1✔
58

59
        flags = 0
1✔
60

61
        have_transforms = any(v != 0 for v in transform_data)
1✔
62

63
        if use_16bits:
1✔
64
            flags |= (1 << 0)
1✔
65

66
        if have_transforms:
1✔
67
            flags |= (1 << 1)
×
68
        else:
69
            transform_data = []
1✔
70

71
        # append layer names at the very end
72
        name_data = b'\0'.join([x.encode() for x in layer_names]) + b'\0'
1✔
73
        flags |= (1 << 2) # have names
1✔
74

75
        return struct.pack(
1✔
76
            '<4sHHHHHH',
77
            bytes('MTMX', encoding='utf-8'),
78
            16,
79
            flags,
80
            empty_tile,
81
            width,
82
            height,
83
            layer_count
84
        ) + layer_data + bytes(transform_data) + name_data
85

86
    else:
87
        # Just return the raw layer data
88
        return layer_data + bytes(transform_data)
1✔
89

90

91
@AssetBuilder(typemap=map_typemap)
1✔
92
def map(data, subtype, empty_tile=0, output_struct=False):
1✔
93
    if subtype == 'tiled':
1✔
94
        return tiled_to_binary(data, empty_tile, output_struct)
1✔
95

96

97
@AssetTool(map, 'Convert popular tilemap formats for 32Blit')
1✔
98
@click.option('--empty-tile', type=int, default=0, help='Remap .tmx empty tiles')
1✔
99
@click.option('--output-struct', type=bool, default=False, help='Output .tmx as struct with level width/height, etc')
1✔
100
def map_cli(input_file, input_type, **kwargs):
1✔
101
    return map.from_file(input_file, input_type, **kwargs)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc