예제 #1
0
def rogueParseOffsetTable(bs, tableAddr):
    bs.seek(snesLoRomPtrToFileOffset(tableAddr), NOESEEK_ABS)
    offsets = []
    while not bs.checkEOF():
        addr = bs.readUInt24()
        if addr >= 0xFF0000:
            break
        offsets.append(snesLoRomPtrToFileOffset(addr))
    return offsets
예제 #2
0
def rogueReadTerminatedCompList(bs):
    offsets = []
    while not bs.checkEOF():
        addr = bs.readUInt24()
        if not addr:
            break
        offsets.append(snesLoRomPtrToFileOffset(addr))
    return offsets
예제 #3
0
 def __init__(self, bs):
     self.width = bs.readUShort()
     self.height = bs.readUShort()
     self.palOffset = snesLoRomPtrToFileOffset(bs.readUInt24())
     self.c0 = rogueReadTerminatedCompList(bs)
     self.c1 = rogueReadTerminatedCompList(bs)
     self.c2 = rogueReadTerminatedCompList(bs)
     self.c3 = rogueReadTerminatedCompList(bs)
     self.c4 = rogueReadTerminatedCompList(bs)
     self.c5 = rogueReadTerminatedCompList(bs)
예제 #4
0
def rogueTestDump(binName, binData):
    for addr in TEST_DUMP_LIST:
        offset = snesLoRomPtrToFileOffset(addr)
        decompData = rapi.callExtensionMethod("ftrogue_decomp",
                                              binData[offset:], None, None)
        if decompData:
            name = os.path.splitext(binName)[0] + ".dump_%08x.bin" % addr
            print("Writing", name)
            with open(name, "wb") as f:
                f.write(decompData)
    return 0
예제 #5
0
def rogueBgDump(binName, binData):
    bs = NoeBitStream(binData)

    bgOffsets = rogueParseOffsetTable(bs, BG_TABLE_ADDRESS)

    print("Found", len(bgOffsets), "background offsets.")
    for bgIndex in range(0, len(bgOffsets)):
        bs.seek(bgOffsets[bgIndex], NOESEEK_ABS)
        bg = BgEntry(bs)

        bs.seek(bg.palOffset, NOESEEK_ABS)
        palData = bs.readBytes(512)

        lTable = bytearray(0x20000)
        charData = rogueDecompList(bg.c0, binData, None, lTable)
        dTable = rogueDecompList(bg.c2, binData)
        mapData = rogueDecompList(bg.c1, binData, None, None, lTable, dTable)
        mapLutData = rogueDecompList(bg.c3, binData, mapData, bytearray())
        colData = rogueDecompList(bg.c4, binData)
        colIdxData = rogueDecompList(bg.c5, binData, None, bytearray())

        if DUMP_RAW_BINARIES:
            rogueRawDump(charData, binName, "bg%03i.chardata.bin" % bgIndex)
            rogueRawDump(mapData, binName, "bg%03i.mapdata.bin" % bgIndex)
            rogueRawDump(mapLutData, binName,
                         "bg%03i.maplutdata.bin" % bgIndex)
            rogueRawDump(colData, binName, "bg%03i.coldata.bin" % bgIndex)
            #the game converts the indices to word offsets into collision data on load, but we just leave it as-is
            rogueRawDump(colIdxData, binName,
                         "bg%03i.colidxdata.bin" % bgIndex)

        drawFlags = 2

        blockWidth = bg.width
        blockHeight = bg.height
        tileWidth = blockWidth * 4
        tileHeight = blockHeight * 4
        texWidth = tileWidth * 8
        texHeight = tileHeight * 8

        mapBs = NoeBitStream(mapData)
        mapLutBs = NoeBitStream(mapLutData)
        mapLutBs.seek(len(mapLutData) - 4)
        extraTileSize = mapLutBs.readInt()
        mapLutBs.seek(
            len(mapLutData) - extraTileSize - blockWidth * blockHeight * 2)
        extraTileBs = NoeBitStream(mapLutData[len(mapLutData) -
                                              extraTileSize:])

        rgba = bytearray(texWidth * texHeight * 4)
        for blockY in range(0, blockHeight):
            tileY = blockY * 4
            for blockX in range(0, blockWidth):
                tileX = blockX * 4
                blockOffset = mapLutBs.readUShort()
                if blockOffset & 0x8000:
                    extraTileBs.seek(blockOffset & 0x7FFF, NOESEEK_ABS)
                    useBs = extraTileBs
                else:
                    mapBs.seek(blockOffset, NOESEEK_ABS)
                    useBs = mapBs

                for subTileY in range(0, 4):
                    pixelY = (tileY + subTileY) * 8
                    for subTileX in range(0, 4):
                        pixelX = (tileX + subTileX) * 8
                        tileData = useBs.readUShort()
                        rapi.callExtensionMethod("snes_m1b0_drawtile_rgba",
                                                 rgba, texWidth, texHeight,
                                                 pixelX, pixelY, tileData,
                                                 charData, palData, drawFlags)

        name = os.path.splitext(binName)[0] + ".bg%03i.png" % bgIndex
        print("Writing", name)
        noesis.saveImageRGBA(
            name,
            NoeTexture(name, texWidth, texHeight, rgba,
                       noesis.NOESISTEX_RGBA32))

        if DRAW_COLLISION:
            rgba = bytearray(texWidth * texHeight * 4)
            rapi.callExtensionMethod(
                "ftrogue_drawcol", rgba, binData, colData, colIdxData,
                blockWidth, blockHeight,
                snesLoRomPtrToFileOffset(COLLISION_LUT_ADDRESS),
                snesLoRomPtrToFileOffset(COLLISION_TILES_ADDRESS), 0)
            name = os.path.splitext(binName)[0] + ".bg%03i.col.png" % bgIndex
            print("Writing", name)
            noesis.saveImageRGBA(
                name,
                NoeTexture(name, texWidth, texHeight, rgba,
                           noesis.NOESISTEX_RGBA32))

    return 0