from common import * class KPObjectDefinition(object): def __init__(self): self.rows = [] def render(self, size): buf = [] beforeRepeat = [] inRepeat = [] afterRepeat = [] foundRepeat = False for row in self.rows: if (row[0][0] & 2) != 0: inRepeat.append(row) foundRepeat = True else: if foundRepeat: afterRepeat.append(row) else: beforeRepeat.append(row) bC, iC, aC = len(beforeRepeat), len(inRepeat), len(afterRepeat) if iC == 0: for y in xrange(size[1]): buf.append(self._renderRow(beforeRepeat[y % bC], size[0])) else: middleUntil = size[1] - aC for y in xrange(size[1]): if y < bC: buf.append(self._renderRow(beforeRepeat[y], size[0])) elif y < middleUntil: buf.append(self._renderRow(inRepeat[(y - bC) % iC], size[0])) else: buf.append(self._renderRow(afterRepeat[y - bC - iC], size[0])) return buf def _renderRow(self, row, width): buf = [-1 for i in xrange(width)] beforeRepeat = [] inRepeat = [] afterRepeat = [] foundRepeat = False for tile in row: if (tile[0] & 1) != 0: inRepeat.append(tile[1]) foundRepeat = True else: if foundRepeat: afterRepeat.append(tile[1]) else: beforeRepeat.append(tile[1]) bC, iC, aC = len(beforeRepeat), len(inRepeat), len(afterRepeat) if iC == 0: for x in xrange(width): buf[x] = beforeRepeat[x % bC] else: middleUntil = width - aC for x in xrange(width): if x < bC: buf[x] = beforeRepeat[y] elif x < middleUntil: buf[x] = inRepeat[(y - bC) % iC] else: buf[x] = afterRepeat[y - bC - iC] return buf class KPTileset(object): def __init__(self, imageBuffer, objectBuffer, groupBuffer): '''A Koopatlas Tileset class. To initialize, pass it an image buffer, an object buffer, and a group buffer from a Koopatlas tileset file. tiles -> has a list of all 512 tiles. objects -> has a list of objects in the tileset groupModel -> has a model containing groups with items for all objects and groups in the tileset. Methods of Note: overrideTile(Tile Index, QPixmap) # Takes a 24x24 QPixmap and a tile index ''' self.tiles = [] self.objects = [] self.groupModel = QtGui.QTreeModel self.processImage(imageBuffer) self.processObjects(objectBuffer) self.processGroup(groupBuffer) def processImage(self, imageBuffer): '''Takes an imageBuffer from a Koopatlas Tileset and converts it into 24x24 tiles, which get put into KPTileset.tiles.''' dest = self.RGB4A3Decode(Image) self.tileImage = QtGui.QPixmap.fromImage(dest) # Makes us some nice Tiles! Xoffset = 4 Yoffset = 4 for i in range(512): self.tiles.append(self.tileImage.copy(Xoffset,Yoffset,24,24)) Xoffset += 32 if Xoffset >= 1024: Xoffset = 4 Yoffset += 32 def RGB4A3Decode(tex): dest = QtGui.QImage(1024,512,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): for ypixel in xrange(ytile, ytile + 4): for xpixel in xrange(xtile, xtile + 4): if(xpixel >= 1024 or ypixel >= 512): continue newpixel = struct.unpack_from('>H', tex, i)[0] # 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 alpha = ((newpixel & 0x7000) >> 12) * 255 / 0x7 blue = ((newpixel & 0xF00) >> 8) * 255 / 0xF green = ((newpixel & 0xF0) >> 4) * 255 / 0xF red = (newpixel & 0xF) * 255 / 0xF argb = (blue) | (green << 8) | (red << 16) | (alpha << 24) dest.setPixel(xpixel, ypixel, argb) i += 2 return dest def processObjects(self, objectBuffer): def processGroup(self, groupBuffer): grovyle = cPickle.loads(group) makeTree(grovyle, treecko) def makeTree(self, grovyle, treecko): for razorLeaf in grovyle: if (type(razorLeaf) is str) and (razorLeaf[:6] == "Object"): pix = QtGui.QPixmap(24, 24) pix.fill(QtCore.Qt.transparent) painter = QtGui.QPainter(pix) painter.drawPixmap(0, 0, pix) painter.end() a = QtGui.QTreeWidgetItem(treecko) a.setText(0, razorLeaf) a.setFlags(QtCore.Qt.ItemFlags(0x25)) a.setIcon(1, QtGui.QIcon(pix)) else: a = QtGui.QTreeWidgetItem(treecko) a.setText(0, razorLeaf[0]) a.setFlags(QtCore.Qt.ItemFlags(0x2F)) a.setChildIndicatorPolicy(QtGui.QTreeWidgetItem.ShowIndicator) a.setExpanded(True) makeTree(razorLeaf[1], a) def overrideTile(index, pixmap): '''Takes a 24x24 QPixmap and a tile index, and returns true if it succeeds.''' if index > 511: return false if not isInstance(pixmap, QtGui.QPixmap): return false if (QtGui.QPixmap.height() != 24) or (QtGui.QPixmap.width() != 24): return false self.tiles[index] = pixmap return true