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
Beispiel #2
0
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
Beispiel #4
0
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