summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xKoopuzzle/Koopuzzle.py92
-rw-r--r--src/exporter.py26
2 files changed, 78 insertions, 40 deletions
diff --git a/Koopuzzle/Koopuzzle.py b/Koopuzzle/Koopuzzle.py
index 8672d57..cb63412 100755
--- a/Koopuzzle/Koopuzzle.py
+++ b/Koopuzzle/Koopuzzle.py
@@ -838,7 +838,7 @@ class PiecesModel(QtCore.QAbstractListModel):
################## Python-based RGB5a3 Decoding code from my BRFNT program ##################
-def RGB4A3Decode(tex):
+def RGB5A3Decode(tex):
dest = QtGui.QImage(896,448,QtGui.QImage.Format_ARGB32)
dest.fill(QtCore.Qt.transparent)
@@ -856,19 +856,16 @@ def RGB4A3Decode(tex):
# newpixel = (int(tex[i]) << 8) | int(tex[i+1])
- # if(newpixel >= 0x8000): # Check if it's RGB555
- # red = ((newpixel >> 10) & 0x1F) * 255 / 0x1F
- # green = ((newpixel >> 5) & 0x1F) * 255 / 0x1F
- # blue = (newpixel & 0x1F) * 255 / 0x1F
- # alpha = 0xFF
-
- # else: # If not, it's RGB4A3
-
- # IT'S ALWAYS FUCKING RGB4A3 - who makes a tileset without alpha?!
- alpha = ((newpixel & 0x7000) >> 12) * 255 / 0x7
- red = ((newpixel & 0xF00) >> 8) * 255 / 0xF
- green = ((newpixel & 0xF0) >> 4) * 255 / 0xF
- blue = (newpixel & 0xF) * 255 / 0xF
+ if(newpixel >= 0x8000): # Check if it's RGB555
+ red = ((newpixel >> 10) & 0x1F) * 255 / 0x1F
+ green = ((newpixel >> 5) & 0x1F) * 255 / 0x1F
+ blue = (newpixel & 0x1F) * 255 / 0x1F
+ alpha = 0xFF
+ else: # If not, it's RGB4A3
+ alpha = ((newpixel & 0x7000) >> 12) * 255 / 0x7
+ red = ((newpixel & 0xF00) >> 8) * 255 / 0xF
+ green = ((newpixel & 0xF0) >> 4) * 255 / 0xF
+ blue = (newpixel & 0xF) * 255 / 0xF
argb = (blue) | (green << 8) | (red << 16) | (alpha << 24)
dest.setPixel(xpixel, ypixel, argb)
@@ -876,7 +873,7 @@ def RGB4A3Decode(tex):
return dest
-def RGB4A3Encode(tex):
+def RGB5A3Encode(tex, force4A3=True):
destBuffer = create_string_buffer(896*tex.height()*2)
shortstruct = struct.Struct('>H')
@@ -894,29 +891,45 @@ def RGB4A3Encode(tex):
g = (pixel >> 8) & 0xFF
b = pixel & 0xFF
- # if a < 245: #RGB4A3
-
- # IT'S ALWAYS FUCKING RGB4A3 - who makes a tileset without alpha?!
- alpha = a/32
- red = r/16
- green = g/16
- blue = b/16
+ if a < 245 or force4A3: #RGB4A3
+ alpha = a/32
+ red = r/16
+ green = g/16
+ blue = b/16
+ rgbDAT = (blue) | (green << 4) | (red << 8) | (alpha << 12)
+ else: # RGB555
+ red = r/8
+ green = g/8
+ blue = b/8
+ rgbDAT = (blue) | (green << 5) | (red << 10) | (0x8000) # 0rrrrrgggggbbbbb
- rgbDAT = (blue) | (green << 4) | (red << 8) | (alpha << 12)
-
- # else: # RGB555
- # red = r/8
- # green = g/8
- # blue = b/8
-
- # rgbDAT = (blue) | (green << 5) | (red << 10) | (0x8000) # 0rrrrrgggggbbbbb
-
shortstruct.pack_into(destBuffer, offset, rgbDAT)
offset += 2
return destBuffer.raw
+def RGBA8Encode(tex):
+ destBuffer = create_string_buffer(896*tex.height()*4)
+
+ shortstruct = struct.Struct('>H')
+ offset = 0
+
+ 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):
+
+ pixel = tex.pixel(xpixel, ypixel)
+
+ shortstruct.pack_into(destBuffer, offset, pixel>>16)
+ shortstruct.pack_into(destBuffer, offset+32, pixel&0xFFFF)
+ offset += 2
+ offset += 32
+
+ return destBuffer.raw
+
+
#############################################################################################
############ Main Window Class. Takes care of menu functions and widget creation ############
@@ -1023,7 +1036,7 @@ class MainWindow(QtGui.QMainWindow):
QtGui.QMessageBox.warning(None, 'Error', 'Error - the necessary files were not found.\n\nNot a valid Koopatlas tileset, sadly.')
return
- dest = RGB4A3Decode(Image)
+ dest = RGB5A3Decode(Image)
self.tileImage = QtGui.QPixmap.fromImage(dest)
@@ -1167,6 +1180,8 @@ class MainWindow(QtGui.QMainWindow):
# Prepare tiles, objects, object metadata, and textures and stuff into buffers.
+ self.usesRGBA8 = ('RGBA8' in name)
+
textureBuffer = self.PackTexture()
optTextureBuffer, optMappings = self.PackOptimisedTexture()
objectBuffers = self.PackObjects()
@@ -1209,11 +1224,11 @@ class MainWindow(QtGui.QMainWindow):
mapping[i] = len(sortedTiles)
sortedTiles.append(img)
- tex = self.PackTexture(sortedTiles)
+ tex = self.PackTexture(sortedTiles, 'rgba8' if self.usesRGBA8 else 'real_rgb5a3')
maps = ','.join(map(str, mapping))
return tex, maps
- def PackTexture(self, imageList=None):
+ def PackTexture(self, imageList=None, mode='standard'):
if imageList is None:
imageList = map(lambda x: x.image, Tileset.tiles)
usesPixmap = isinstance(imageList[0], QtGui.QPixmap)
@@ -1297,9 +1312,12 @@ class MainWindow(QtGui.QMainWindow):
painter.end()
tex.save('beef.png')
- dest = RGB4A3Encode(tex)
-
- return dest
+ if mode == 'rgba8':
+ return RGBA8Encode(tex)
+ elif mode == 'real_rgb5a3':
+ return RGB5A3Encode(tex, False)
+ else:
+ return RGB5A3Encode(tex)
diff --git a/src/exporter.py b/src/exporter.py
index f6798c7..b1afaaa 100644
--- a/src/exporter.py
+++ b/src/exporter.py
@@ -421,7 +421,11 @@ class KPMapExporter:
except ValueError:
convertedWorldID = ord(world.worldID) - ord('A') + 10
- data += struct.pack('>BBBB BBBB BBBB BBBB BBBB BBBB hbb BBB B',
+ parseCrap = world.titleScreenID.split('-')
+ tsW = int(parseCrap[0])
+ tsL = int(parseCrap[1])
+
+ data += struct.pack('>BBBB BBBB BBBB BBBB BBBB BBBB hbb BBB BB BBB',
fst1[0],fst1[1],fst1[2],fst1[3],
fst2[0],fst2[1],fst2[2],fst2[3],
fsh1[0],fsh1[1],fsh1[2],fsh1[3],
@@ -431,7 +435,8 @@ class KPMapExporter:
htf[0],htf[1],htf[2],
world.uniqueKey, world.musicTrackID,
convertedWorldID,
- 0
+ tsW - 1, tsL - 1,
+ 0, 0, 0
)
# now that we're almost done... pack the strings
@@ -468,7 +473,10 @@ class KPMapExporter:
struct.pack_into('>ii', data, tsInfoOffsetInHeader, len(tilesets), len(data))
for setname in tilesets:
offsets[('tileset', setname)] = len(data)
- data += self._buildGXTexObjRGB5A3(896, 448, offsets[setname])
+ if 'RGBA8' in setname:
+ data += self._buildGXTexObjRGBA8(896, 448, offsets[setname])
+ else:
+ data += self._buildGXTexObjRGB5A3(896, 448, offsets[setname])
for tex in textures:
offsets[tex] = len(data)
@@ -550,6 +558,18 @@ class KPMapExporter:
0x0202
)
+ def _buildGXTexObjRGBA8(self, width, height, imgOffset):
+ # Format: RGBA8 (6)
+ # Wrap: CLAMP (0)
+ return struct.pack('>IIIIIIIHH',
+ 0x90, 0,
+ (0x600000 | ((height - 1) << 10) | (width - 1)),
+ 0x10000000 + imgOffset, # (imgptr >> 5)
+ 0, 0, 0,
+ (((width + 3) / 4) * ((height + 3) / 4)) & 0x7FFF,
+ 0x0202
+ )
+
def _packSectorData(self, sectors):
rowStruct = struct.Struct('>16h')