summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/exporter.py130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/exporter.py b/src/exporter.py
new file mode 100644
index 0000000..fec2f86
--- /dev/null
+++ b/src/exporter.py
@@ -0,0 +1,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)
+
+