diff options
Diffstat (limited to '')
| -rw-r--r-- | src/exporter.py | 130 | 
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) + + | 
