def writeGFD(f, tileMode, swizzle_, SRGB, n, numImages): width, height, format_, fourcc, dataSize, compSel, numMips, data = dds.readDDS( f, SRGB) if 0 in [width, dataSize] and data == []: if n != (numImages - 1): print("Continuing in 5 seconds...") time.sleep(5) return b'' else: print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if format_ not in formats: print("") print("Unsupported DDS format!") print("") if n != (numImages - 1): print("") print("Continuing in 5 seconds...") time.sleep(5) return b'' else: print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if numMips > 13: print("") print("Invalid number of mipmaps for " + f) print("") if n != (numImages - 1): print("") print("Continuing in 5 seconds...") time.sleep(5) return b'' else: print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) imageData = data[:dataSize] mipData = data[dataSize:] numMips += 1 if format_ in BCn_formats: if format_ in [0x31, 0x431, 0x234, 0x34]: align = 0xEE4 mipAlign = 0xFC0 else: align = 0x1EE4 mipAlign = 0x1FC0 else: align = 0x6E4 mipAlign = 0x7C0 bpp = addrlib.surfaceGetBitsPerPixel(format_) >> 3 alignment = 512 * bpp surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, 0) pitch = surfOut.pitch if surfOut.depth != 1: print("") print("Unsupported depth!") print("") if n != (numImages - 1): print("Continuing in 5 seconds...") time.sleep(5) return b'' else: print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if tileMode in [1, 2, 3, 16]: s = 0 else: s = 0xd0000 s |= swizzle_ << 8 swizzled_data = [] imageSize = 0 mipSize = 0 mipOffsets = [] for i in range(numMips): if i == 0: data = imageData imageSize = surfOut.surfSize else: print( str(i) + ": " + str(max(1, width >> i)) + "x" + str(max(1, height >> i))) offset, dataSize = get_curr_mip_off_size(width, height, bpp, i, format_ in BCn_formats) data = mipData[offset:offset + dataSize] surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, i) padSize = surfOut.surfSize - dataSize data += padSize * b"\x00" if i != 0: offset += padSize if i == 1: mipOffsets.append(imageSize) else: mipOffsets.append(offset) mipSize += len(data) swizzled_data.append( addrlib.swizzle(max(1, width >> i), max(1, height >> i), surfOut.height, format_, surfOut.tileMode, s, surfOut.pitch, surfOut.bpp, data)) compSels = ["R", "G", "B", "A", "0", "1"] """print("") print("// ----- GX2Surface Info ----- ") print(" dim = 1") print(" width = " + str(width)) print(" height = " + str(height)) print(" depth = 1") print(" numMips = " + str(numMips)) print(" format = " + formats[format_]) print(" aa = 0") print(" use = 1") print(" imageSize = " + str(imageSize)) print(" mipSize = " + str(mipSize)) print(" tileMode = " + str(tileMode)) print(" swizzle = " + str(s) + ", " + hex(s)) print(" alignment = " + str(alignment)) print(" pitch = " + str(pitch)) print("") print(" GX2 Component Selector:") print(" Red Channel: " + str(compSels[compSel[0]])) print(" Green Channel: " + str(compSels[compSel[1]])) print(" Blue Channel: " + str(compSels[compSel[2]])) print(" Alpha Channel: " + str(compSels[compSel[3]])) print("") print(" bits per pixel = " + str(bpp << 3)) print(" bytes per pixel = " + str(bpp)) print(" realSize = " + str(len(imageData)))""" block_head_struct = GFDBlockHeader() gx2surf_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xb, 0x9c, 0, 0) gx2surf_struct = GX2Surface() gx2surf = gx2surf_struct.pack(1, width, height, 1, numMips, format_, 0, 1, imageSize, 0, mipSize, 0, tileMode, s, alignment, pitch) align_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 2, align, 0, 0) image_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xc, imageSize, 0, 0) mipAlign_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 2, mipAlign, 0, 0) mip_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xd, mipSize, 0, 0) output = gx2surf_blk_head + gx2surf if numMips > 1: i = 0 for offset in mipOffsets: output += offset.to_bytes(4, 'big') i += 1 for z in range(14 - i): output += 0.to_bytes(4, 'big') else: output += b"\x00" * 56 output += numMips.to_bytes(4, 'big') output += b"\x00" * 4 output += 1.to_bytes(4, 'big') for value in compSel: output += value.to_bytes(1, 'big') output += b"\x00" * 20 output += align_blk_head output += b"\x00" * align output += image_blk_head output += swizzled_data[0] if numMips > 1: output += mipAlign_blk_head output += b"\x00" * mipAlign output += mip_blk_head i = 0 for data in swizzled_data: if i != 0: output += data i += 1 return output
def writeGFD(f): tileMode = 4 width, height, format_, fourcc, dataSize, compSel, numMips, data = dds.readDDS(f) imageData = data[:dataSize] mipData = data[dataSize:] numMips += 1 if format_ == 0x33: align = 0x1EE4 mipAlign = 0x1FC0 else: align = 0x6E4 mipAlign = 0x7C0 bpp = addrlib.surfaceGetBitsPerPixel(format_) >> 3 alignment = 512 * bpp surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, 0) pitch = surfOut.pitch if format_ == 0x33: s = 0x40000 else: s = 0xd0000 swizzled_data = [] imageSize = 0 mipSize = 0 mipOffsets = [] for i in range(numMips): if i == 0: data = imageData imageSize = surfOut.surfSize else: offset, dataSize = get_curr_mip_off_size(width, height, bpp, i, format_ == 0x33) data = mipData[offset:offset + dataSize] surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, i) padSize = surfOut.surfSize - dataSize data += padSize * b"\x00" if i != 0: offset += padSize if i == 1: mipOffsets.append(imageSize) else: mipOffsets.append(offset) mipSize += len(data) swizzled_data.append(addrlib.swizzle(max(1, width >> i), max(1, height >> i), surfOut.height, format_, surfOut.tileMode, s, surfOut.pitch, surfOut.bpp, data)) block_head_struct = GFDBlockHeader() gx2surf_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xb, 0x9c, 0, 0) gx2surf_struct = GX2Surface() gx2surf = gx2surf_struct.pack(1, width, height, 1, numMips, format_, 0, 1, imageSize, 0, mipSize, 0, tileMode, s, alignment, pitch) align_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 2, align, 0, 0) image_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xc, imageSize, 0, 0) mipAlign_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 2, mipAlign, 0, 0) mip_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xd, mipSize, 0, 0) output = gx2surf_blk_head + gx2surf if numMips > 1: i = 0 for offset in mipOffsets: output += offset.to_bytes(4, 'big') i += 1 for z in range(14 - i): output += (0).to_bytes(4, 'big') else: output += b"\x00" * 56 output += numMips.to_bytes(4, 'big') output += b"\x00" * 4 output += (1).to_bytes(4, 'big') for value in compSel: output += value.to_bytes(1, 'big') output += b"\x00" * 20 output += align_blk_head output += b"\x00" * align output += image_blk_head output += swizzled_data[0] if numMips > 1: output += mipAlign_blk_head output += b"\x00" * mipAlign output += mip_blk_head i = 0 for data in swizzled_data: if i != 0: output += data i += 1 return output
def writeGX2Surface_Data(f, tileMode, swizzle_, SRGB): width, height, format_, fourcc, dataSize, compSel, numMips, data = dds.readDDS( f, SRGB) if 0 in [width, dataSize] and data == []: return False if format_ not in formats: print("Unsupported DDS format!") return b'', [] if numMips > 13: print("Invalid number of mipmaps!") return b'', [] imageData = data[:dataSize] mipData = data[dataSize:] numMips += 1 bpp = addrlib.surfaceGetBitsPerPixel(format_) >> 3 alignment = 512 * bpp surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, 0) pitch = surfOut.pitch if surfOut.depth != 1: print("Unsupported depth!") return b'', [] if tileMode in [1, 2, 3, 16]: s = 0 else: s = 0xd0000 s |= swizzle_ swizzled_data = [] imageSize = 0 mipSize = 0 mipOffsets = [] for i in range(numMips): if i == 0: data = imageData imageSize = surfOut.surfSize else: offset, dataSize = get_curr_mip_off_size(width, height, bpp, i, format_ in BCn_formats) data = mipData[offset:offset + dataSize] surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, i) padSize = surfOut.surfSize - dataSize data += padSize * b"\x00" if i != 0: if i == 1: mipOffsets.append(imageSize) else: mipOffsets.append(mipSize) mipSize += len(data) swizzled_data.append( addrlib.swizzle(max(1, width >> i), max(1, height >> i), surfOut.height, format_, surfOut.tileMode, s, surfOut.pitch, surfOut.bpp, data)) gx2surf_struct = GX2Surface() gx2surf = gx2surf_struct.pack(1, width, height, 1, numMips, format_, 0, 1, imageSize, 0, mipSize, 0, tileMode, s, alignment, pitch) if numMips > 1: i = 0 for offset in mipOffsets: gx2surf += offset.to_bytes(4, 'big') i += 1 for z in range(14 - i): gx2surf += 0.to_bytes(4, 'big') else: gx2surf += b"\x00" * 56 gx2surf += numMips.to_bytes(4, 'big') gx2surf += b"\x00" * 4 gx2surf += 1.to_bytes(4, 'big') for value in compSel: gx2surf += value.to_bytes(1, 'big') gx2surf += b"\x00" * 20 return gx2surf, swizzled_data
def writeGFD(width, height, depth, dim, format_, aa, tileMode, swizzle_, pitch, imageSize, f, f1, surfOut): if format_ in formats: if aa != 0: print("") print("Unsupported aa!") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if format_ == 0x00: print("") print("Invalid texture format!") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) else: if format_ not in BCn_formats: bpp = struct.unpack("<I", f1[0x14:0x18])[0] // width dataSize = bpp * width * height else: dataSize = struct.unpack("<I", f1[0x14:0x18])[0] if not dataSize < imageSize: data = f1[0x80:0x80 + imageSize] else: data = f1[0x80:0x80 + dataSize] data += b'\x00' * (imageSize - dataSize) else: print("") print("Unsupported texture format_: " + hex(format_)) print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if surfOut.depth != 1: print("") print("Unsupported depth!") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) swizzled_data = addrlib.swizzle(width, height, surfOut.height, format_, surfOut.tileMode, swizzle_, pitch, surfOut.bpp, data) dataSize = len(swizzled_data) pos = 0 header = GFDHeader() header.data(f, pos) pos += header.size while pos < len(f): # Loop through the entire file. block = GFDBlockHeader() block.data(f, pos) pos += block.size if block.type_ == 0x0B: offset = pos pos += block.dataSize elif block.type_ == 0x0C: head1 = f[:pos] # it works :P offset1 = pos pos += block.dataSize else: pos += block.dataSize head1 = bytearray(head1) head1[offset + 0x10:offset + 0x14] = bytes(bytearray.fromhex("00000001")) # numMips head1[offset + 0x78:offset + 0x7C] = bytes(bytearray.fromhex("00000001")) # numMips, again head1[offset + 0x28:offset + 0x2C] = bytes(bytearray.fromhex("00000000")) # mipSize head1[offset + 0x20:offset + 0x24] = int(dataSize).to_bytes(4, 'big') # imageSize head1[offset1 - 0x0C:offset1 - 0x08] = int(dataSize).to_bytes(4, 'big') # dataSize head2 = bytes(bytearray.fromhex("424C4B7B00000020000000010000000000000001000000000000000000000000")) return bytes(head1) + bytes(swizzled_data) + head2