diff options
-rwxr-xr-x | Koopuzzle/Koopuzzle.py | 146 | ||||
-rwxr-xr-x | Koopuzzle/archive.py | 2 | ||||
-rw-r--r-- | src/exporter.py | 7 | ||||
-rw-r--r-- | src/main.py | 1 | ||||
-rw-r--r-- | src/tileset.py | 40 |
5 files changed, 116 insertions, 80 deletions
diff --git a/Koopuzzle/Koopuzzle.py b/Koopuzzle/Koopuzzle.py index 9c136d3..8672d57 100755 --- a/Koopuzzle/Koopuzzle.py +++ b/Koopuzzle/Koopuzzle.py @@ -839,16 +839,17 @@ class PiecesModel(QtCore.QAbstractListModel): def RGB4A3Decode(tex): - dest = QtGui.QImage(1024,512,QtGui.QImage.Format_ARGB32) + dest = QtGui.QImage(896,448,QtGui.QImage.Format_ARGB32) dest.fill(QtCore.Qt.transparent) i = 0 - for ytile in xrange(0, 512, 4): - for xtile in xrange(0, 1024, 4): + height = min(len(tex) / 1792, 448) + for ytile in xrange(0, 448, 4): + for xtile in xrange(0, 896, 4): for ypixel in xrange(ytile, ytile + 4): for xpixel in xrange(xtile, xtile + 4): - if(xpixel >= 1024 or ypixel >= 512): + if(xpixel >= 896 or ypixel >= height): continue newpixel = struct.unpack_from('>H', tex, i)[0] @@ -876,19 +877,16 @@ def RGB4A3Decode(tex): def RGB4A3Encode(tex): - destBuffer = create_string_buffer(1024*512*2) + destBuffer = create_string_buffer(896*tex.height()*2) shortstruct = struct.Struct('>H') offset = 0 - for ytile in xrange(0, 512, 4): - for xtile in xrange(0, 1024, 4): + for ytile in xrange(0, tex.height(), 4): + for xtile in xrange(0, 896, 4): for ypixel in xrange(ytile, ytile + 4): for xpixel in xrange(xtile, xtile + 4): - if(xpixel >= 1024 or ypixel >= 512): - continue - pixel = tex.pixel(xpixel, ypixel) a = pixel >> 24 @@ -1010,12 +1008,13 @@ class MainWindow(QtGui.QMainWindow): for key, value in arc.files: if value == None: pass - if key.startswith('BG_tex/') and key.endswith('_tex.bin'): + print key + if (key.startswith('BG_tex/') and key.endswith('_tex.bin')) or key == '/texture.bin': Image = arc[key] - if key.startswith('BG_grp/') and key.endswith('_grp.bin'): + if (key.startswith('BG_grp/') and key.endswith('_grp.bin')) or key == '/groups.bin': group = arc[key] - if key.startswith('BG_unt/'): - if key.endswith('_hd.bin'): + if key.startswith('BG_unt/') or key.startswith('/objects'): + if key.endswith('_hd.bin') or key.endswith('Meta.bin'): metadata = arc[key] elif key.endswith('.bin'): objstrings = arc[key] @@ -1029,14 +1028,14 @@ class MainWindow(QtGui.QMainWindow): self.tileImage = QtGui.QPixmap.fromImage(dest) # Makes us some nice Tile Classes! - Xoffset = 4 - Yoffset = 4 + Xoffset = 2 + Yoffset = 2 for i in range(512): Tileset.addTile(self.tileImage.copy(Xoffset,Yoffset,24,24)) - Xoffset += 32 - if Xoffset >= 1024: - Xoffset = 4 - Yoffset += 32 + Xoffset += 28 + if Xoffset >= 896: + Xoffset = 2 + Yoffset += 28 # Load Objects @@ -1169,6 +1168,7 @@ class MainWindow(QtGui.QMainWindow): # Prepare tiles, objects, object metadata, and textures and stuff into buffers. textureBuffer = self.PackTexture() + optTextureBuffer, optMappings = self.PackOptimisedTexture() objectBuffers = self.PackObjects() objectBuffer = objectBuffers[0] objectMetaBuffer = objectBuffers[1] @@ -1177,93 +1177,125 @@ class MainWindow(QtGui.QMainWindow): # Make an arc and pack up the files! arc = archive.U8() - arc['BG_tex'] = None - arc['BG_tex/{0}_tex.bin'.format(name)] = textureBuffer + arc['texture.bin'.format(name)] = textureBuffer + arc['optimisedTexture.bin'.format(name)] = optTextureBuffer + arc['optimisedTileMappings.txt'] = optMappings - arc['BG_unt'] = None - arc['BG_unt/{0}.bin'.format(name)] = objectBuffer - arc['BG_unt/{0}_hd.bin'.format(name)] = objectMetaBuffer + arc['objects.bin'] = objectBuffer + arc['objectsMeta.bin'] = objectMetaBuffer - arc['BG_grp'] = None - arc['BG_grp/{0}_grp.bin'.format(name)] = groupBuffer + arc['groups.bin'] = groupBuffer return arc._dump() + def PackOptimisedTexture(self): + sortedTiles = [] + mapping = [-1 for x in xrange(512)] + + first_fuckin_image = Tileset.tiles[0].image.toImage() + transparent = QtGui.QImage(32, 32, first_fuckin_image.format()) + transparent.fill(QtCore.Qt.transparent) - def PackTexture(self): + for i, tile in enumerate(Tileset.tiles): + img = tile.image.toImage() + if tile == transparent: + continue + + for j, otherImg in enumerate(sortedTiles): + if img == otherImg: + mapping[i] = j + break + else: + mapping[i] = len(sortedTiles) + sortedTiles.append(img) - tex = QtGui.QImage(1024, 512, QtGui.QImage.Format_ARGB32) + tex = self.PackTexture(sortedTiles) + maps = ','.join(map(str, mapping)) + return tex, maps + + def PackTexture(self, imageList=None): + if imageList is None: + imageList = map(lambda x: x.image, Tileset.tiles) + usesPixmap = isinstance(imageList[0], QtGui.QPixmap) + + from math import ceil + height = int(ceil(len(imageList) / 32.0)) + tex = QtGui.QImage(896, height*28, QtGui.QImage.Format_ARGB32) tex.fill(QtCore.Qt.transparent) painter = QtGui.QPainter(tex) Xoffset = 0 Yoffset = 0 - for tile in Tileset.tiles: - minitex = QtGui.QImage(32, 32, QtGui.QImage.Format_ARGB32) + for img in imageList: + minitex = QtGui.QImage(28, 28, QtGui.QImage.Format_ARGB32) minitex.fill(QtCore.Qt.transparent) minipainter = QtGui.QPainter(minitex) - minipainter.drawPixmap(4, 4, tile.image) + if usesPixmap: + minipainter.drawPixmap(2, 2, img) + else: + minipainter.drawImage(2, 2, img) minipainter.end() # Read colours and DESTROY THEM (or copy them to the edges, w/e) - for i in xrange(4,28): + for i in xrange(2,26): # Top Clamp - colour = minitex.pixel(i, 4) - for p in xrange(0,4): + colour = minitex.pixel(i, 2) + for p in xrange(0,2): minitex.setPixel(i, p, colour) # Left Clamp - colour = minitex.pixel(4, i) - for p in xrange(0,4): + colour = minitex.pixel(2, i) + for p in xrange(0,2): minitex.setPixel(p, i, colour) # Right Clamp - colour = minitex.pixel(i, 27) - for p in xrange(27,31): + colour = minitex.pixel(i, 25) + for p in xrange(26,28): minitex.setPixel(i, p, colour) # Bottom Clamp - colour = minitex.pixel(27, i) - for p in xrange(27,31): + colour = minitex.pixel(25, i) + for p in xrange(26,28): minitex.setPixel(p, i, colour) # UpperLeft Corner Clamp - colour = minitex.pixel(4, 4) - for x in xrange(0,4): - for y in xrange(0,4): + colour = minitex.pixel(2, 2) + for x in xrange(0,2): + for y in xrange(0,2): minitex.setPixel(x, y, colour) # UpperRight Corner Clamp - colour = minitex.pixel(27, 4) - for x in xrange(27,31): - for y in xrange(0,4): + colour = minitex.pixel(25, 2) + for x in xrange(26,28): + for y in xrange(0,2): minitex.setPixel(x, y, colour) # LowerLeft Corner Clamp - colour = minitex.pixel(4, 27) - for x in xrange(0,4): - for y in xrange(27,31): + colour = minitex.pixel(2, 25) + for x in xrange(0,2): + for y in xrange(26,28): minitex.setPixel(x, y, colour) # LowerRight Corner Clamp - colour = minitex.pixel(27, 27) - for x in xrange(27,31): - for y in xrange(27,31): + colour = minitex.pixel(25, 25) + for x in xrange(26,28): + for y in xrange(26,28): minitex.setPixel(x, y, colour) painter.drawImage(Xoffset, Yoffset, minitex) - Xoffset += 32 + Xoffset += 28 - if Xoffset >= 1024: + if Xoffset >= 896: Xoffset = 0 - Yoffset += 32 + Yoffset += 28 painter.end() + tex.save('beef.png') dest = RGB4A3Encode(tex) @@ -1485,4 +1517,4 @@ if __name__ == '__main__': window = MainWindow() window.show() sys.exit(app.exec_()) - app.deleteLater()
\ No newline at end of file + app.deleteLater() diff --git a/Koopuzzle/archive.py b/Koopuzzle/archive.py index b0495f5..f623d16 100755 --- a/Koopuzzle/archive.py +++ b/Koopuzzle/archive.py @@ -171,7 +171,7 @@ class U8(WiiArchive): if(sz != counter + 1):
recursion.append(sz)
else:
- recursiondir.pop()
+ if recursiondir: recursiondir.pop()
def __str__(self):
ret = ''
for key, value in self.files:
diff --git a/src/exporter.py b/src/exporter.py index 0ddc98a..ed377c3 100644 --- a/src/exporter.py +++ b/src/exporter.py @@ -82,6 +82,9 @@ class KPMapExporter: for i in xrange(sectorBottom - sectorTop + 1): rawSectors.append([None for j in xrange(sectorRight - sectorLeft + 1)]) + tileset = KP.tileset(layer.tileset) + optMappings = tileset.optMappings + # copy every tile index over for srcY in xrange(layerHeight): srcRow = cache[srcY] @@ -98,6 +101,8 @@ class KPMapExporter: tile = srcRow[srcX] if tile == -1: continue + tile = optMappings[tile] + if tile == -1: continue destSector = destRow[sectorX - sectorLeft] if destSector is None: @@ -398,7 +403,7 @@ class KPMapExporter: struct.pack_into('>ii', data, 8, len(tilesets), len(data)) for setname in tilesets: offsets[('tileset', setname)] = len(data) - data += self._buildGXTexObjRGB5A3(1024, 512, offsets[setname]) + data += self._buildGXTexObjRGB5A3(896, 448, offsets[setname]) for tex in textures: offsets[tex] = len(data) diff --git a/src/main.py b/src/main.py index 8d8d494..f417d94 100644 --- a/src/main.py +++ b/src/main.py @@ -76,6 +76,7 @@ class KP: tsInfo['hash'] = newHash from tileset import KPTileset + print "Loading set: %s" % name cls.loadedTilesets[name] = KPTileset.loadFromArc(data) diff --git a/src/tileset.py b/src/tileset.py index ab77223..cc36d18 100644 --- a/src/tileset.py +++ b/src/tileset.py @@ -341,22 +341,18 @@ class KPTileset(object): def loadFromArc(cls, handleOrPath): arc = WiiArchiveU8(handleOrPath) - img = arc.resolvePath('/BG_tex').children[0].data - grp = arc.resolvePath('/BG_grp').children[0].data + img = arc.resolvePath('/texture.bin').data + grp = arc.resolvePath('/groups.bin').data - untDir = arc.resolvePath('/BG_unt') - obj, meta = None, None + obj = arc.resolvePath('/objects.bin').data + meta = arc.resolvePath('/objectsMeta.bin').data - for child in untDir.children: - if child.name.endswith('_hd.bin'): - meta = child.data - else: - obj = child.data + tmaps = arc.resolvePath('/optimisedTileMappings.txt').data - return cls(img, obj, meta, grp) + return cls(img, obj, meta, grp, tmaps) - def __init__(self, imageBuffer, objectBuffer, objectMetadata, groupBuffer): + def __init__(self, imageBuffer, objectBuffer, objectMetadata, groupBuffer, optMapBuffer): '''A Koopatlas Tileset class. To initialize, pass it image data, object data, and group data as read from a Koopatlas tileset file. @@ -402,6 +398,8 @@ class KPTileset(object): self.groupItem.calculateIndices(0) self.groupModel = KPGroupModel(self.groupItem) + self.optMappings = map(int, optMapBuffer.split(',')) + def processImage(self, imageBuffer): '''Takes an imageBuffer from a Koopatlas Tileset and converts it into 24x24 @@ -412,14 +410,14 @@ class KPTileset(object): self.tileImage = QtGui.QPixmap.fromImage(dest) # Makes us some nice Tiles! - Xoffset = 4 - Yoffset = 4 + Xoffset = 2 + Yoffset = 2 for i in range(512): self.tiles.append(self.tileImage.copy(Xoffset,Yoffset,24,24)) - Xoffset += 32 - if Xoffset >= 1024: - Xoffset = 4 - Yoffset += 32 + Xoffset += 28 + if Xoffset >= 896: + Xoffset = 2 + Yoffset += 28 @@ -428,8 +426,8 @@ class KPTileset(object): import time b = time.clock() - out = bytearray(1024*512*4) - dest = QtGui.QImage(1024,512,QtGui.QImage.Format_ARGB32) + out = bytearray(896*448*4) + dest = QtGui.QImage(896,448,QtGui.QImage.Format_ARGB32) dest.fill(Qt.transparent) # Some fairly ugly code, in an attempt to make it run faster @@ -440,8 +438,8 @@ class KPTileset(object): i = 0 - xtile_range = _xrange(0, 1024, 4) - ytile_range = _xrange(0, 512, 4) + xtile_range = _xrange(0, 896, 4) + ytile_range = _xrange(0, 448, 4) for ytile in ytile_range: ypixel_range = _xrange(ytile, ytile + 4) |