summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2012-03-28 04:37:23 +0200
committerTreeki <treeki@gmail.com>2012-03-28 04:37:23 +0200
commit225b688b188d22fe00976b2febc03f78ca3b2d7e (patch)
treee24780d8caf8dba6ebeca04478e187c6356d2c28
parentad84fff6bcf29bfde86cce2d1edbd2c1061fea32 (diff)
downloadkoopatlas-225b688b188d22fe00976b2febc03f78ca3b2d7e.tar.gz
koopatlas-225b688b188d22fe00976b2febc03f78ca3b2d7e.zip
support for the new optimised tilesets
-rwxr-xr-xKoopuzzle/Koopuzzle.py146
-rwxr-xr-xKoopuzzle/archive.py2
-rw-r--r--src/exporter.py7
-rw-r--r--src/main.py1
-rw-r--r--src/tileset.py40
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)