1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
from common import *
import array
import sys
class KPMapExporter:
class LayerExporter:
def __init__(self, layer):
self.layer = layer
def buildSectors(self, sectors, indices):
# we'll use the cache held by the layer: why reinvent the wheel?
layer.updateCache()
cache = layer.cache
# first off, get all the info and figure out the sector bounds
layerX, layerY = layer.cacheBasePos
layerWidth, layerHeight = layer.cacheSize
sectorLeft = layerX / 16
sectorTop = layerY / 16
sectorRight = (layerX + layerWidth) / 16
sectorBottom = (layerY + layerHeight) / 16
rawSectors = []
for i in xrange(sectorBottom - sectorTop + 1):
rawSectors.append([None for j in xrange(sectorRight - sectorLeft + 1)])
# copy every tile index over
for srcY in xrange(layerHeight):
srcRow = cache[srcY]
worldY = srcY + layerY
sectorY = worldY / 16
destY = worldY % 16
destRow = rawSectors[sectorY]
for srcX in xrange(layerX, layerX+layerWidth):
worldX = srcX + layerX
sectorX = worldX / 16
destX = worldX % 16
tile = srcRow[i]
if tile == -1: continue
destSector = destRow[sectorX]
if destSector is None:
destSector = [[-1 for j in xrange(16)] for i in xrange(16)]
destRow[sectorX] = destSector
destSector[destY][destX] = tile
# now add the created sectors to the data
sectorMap = [-1 for i in xrange(len(self.rawSectors))]
for srcRow, mapRow in zip(self.rawSectors, sectorMap):
for index, sector in enumerate(srcRow):
if sector is not None:
# see if it's a duplicate or not
sectorKey = '|'.join(map(lambda x: ','.join(map(str, x)), sector))
try:
mapRow[index] = sectorIndices[sectorKey]
except ValueError:
sectorIndices[sectorKey] = len(sectors)
mapRow[index] = len(sectors)
sectors.append(sector)
self.sectorBounds = (sectorLeft, sectorTop, sectorRight, sectorBottom)
self.sectorMap = sectorMap
def __init__(self, mapObj):
self.map = mapObj
self.layers = map(KPMapExporter.LayerExporter, self.map.layers)
self.archive = WiiArchiveU8()
def buildAndPack(self, handle=None):
# make the BG data
sectors = []
sectorIndices = {}
for layer in self.layers:
layer.buildSectors(sectors, sectorIndices)
# pack it into the arc
self.archive.resolvePath('/sectors.bin').data = self._packSectorData(sectors)
self.archive.resolvePath('/sectorMaps.bin').data = self._packSectorMaps()
return self.archive.pack(handle)
def _packSectorData(self, sectors):
rowStruct = struct.Struct('>16h')
output = []
for sector in sectors:
for row in sector:
output.append(rowStruct.pack(*row))
return ''.join(output)
def _packSectorMaps(self):
offsets = array.array('I')
assert offsets.itemsize == 4
currentOffset = len(self.layers) * 4
data = []
for index, layer in enumerate(self.layers):
offsets.append(currentOffset)
data.append(struct.pack('>hhhh', *layer.sectorBounds))
currentOffset += 8
first = layer.sectorMap[0]
rowStruct = struct.Struct('>%dh' % len(first))
for row in layer.sectorMap:
data.append(rowStruct.pack(*row))
currentOffset += (len(first) * len(layer.sectorMap) * 2)
if sys.byteorder == 'little': offsets.byteswap()
return offsets.tostring() + ''.join(data)
|