예제 #1
0
    def readFromRom(self, rom):
        self._bbgTbl.readFromRom(rom)
        pct = 50.0/(6+self._bbgTbl.height())
        self._bbgGfxPtrTbl.readFromRom(rom,
                EbModule.toRegAddr(EbModule.readAsmPointer(rom,
                    self._ASMPTRS_GFX[0])))
        updateProgress(pct)
        self._bbgArrPtrTbl.readFromRom(rom,
                EbModule.toRegAddr(EbModule.readAsmPointer(rom, 
                    self._ASMPTRS_ARR[0])))
        updateProgress(pct)
        self._bbgPalPtrTbl.readFromRom(rom,
                EbModule.toRegAddr(EbModule.readAsmPointer(rom, 
                    self._ASMPTRS_PAL[0])))
        updateProgress(pct)

        self._bbgGfxArrs = [ None for i in range(self._bbgGfxPtrTbl.height()) ]
        self._bbgPals = [ None for i in range(self._bbgPalPtrTbl.height()) ]
        updateProgress(pct)
        self._bbgScrollTbl.readFromRom(rom)
        updateProgress(pct)
        self._bbgDistorTbl.readFromRom(rom)
        updateProgress(pct)
        for i in range(self._bbgTbl.height()):
            gfxNum = self._bbgTbl[i,0].val()
            colorDepth = self._bbgTbl[i,2].val()
            if (self._bbgGfxArrs[gfxNum] == None):
                # Max size used in rom: 421 (2bpp) 442 (4bpp)
                tg = EbTileGraphics(512, 8, colorDepth)
                with EbCompressedData() as tgb:
                    tgb.readFromRom(rom, EbModule.toRegAddr(
                        self._bbgGfxPtrTbl[gfxNum,0].val()))
                    tg.readFromBlock(tgb)
                a = EbArrangement(32, 32)
                with EbCompressedData() as ab:
                    ab.readFromRom(rom, EbModule.toRegAddr(
                        self._bbgArrPtrTbl[gfxNum,0].val()))
                    a.readFromBlock(ab)
                
                self._bbgGfxArrs[gfxNum] = (tg, a)
            palNum = self._bbgTbl[i,1].val()
            if (self._bbgPals[palNum] == None):
                with DataBlock(32) as pb:
                    pb.readFromRom(rom,
                            EbModule.toRegAddr(self._bbgPalPtrTbl[palNum,0].val()))
                    p = EbPalettes(1, 16)
                    p.readFromBlock(pb)
                    self._bbgPals[palNum] = p
            updateProgress(pct)
예제 #2
0
class WindowGraphicsModule(EbModule.EbModule):
    _name = "Window Graphics"
    _ASMPTR_1 = 0x47c47
    _ASMPTR_2 = 0x47caa
    _ASMPTRS_NAMES = [0x1F70F, 0x1F72A, 0x1F745, 0x1F760, 0x1F77B]
    _PREVIEW_SUBPALS = [0, 0, 0, 0, 1, 1, 1, 4, 4, 4, 4, 6, 6, 6, 6, 6, 7, 7, 7,
            7, 7, 7, 7, 4, 4, 4, 4, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 0,
            1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 6, 6,
            6, 3, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 3, 6, 3, 3, 3,
            3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 1, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0,
            0, 0, 0, 1, 0, 0 ]
    def __init__(self):
        self._gfx1 = EbTileGraphics(416, 8, 2)
        self._gfx2 = EbTileGraphics(7, 8, 2)
        self._flavPals = [EbPalettes(8,4) for i in range(7)]
        self._flavNames = [(i,TextTableEntry(None, 25)) for i in self._ASMPTRS_NAMES]
    def freeRanges(self):
        return [(0x200000, 0x20079f)] # Graphics
    def readFromRom(self, rom):
        with EbCompressedData() as tgb1:
            tgb1.readFromRom(rom, EbModule.toRegAddr(
                EbModule.readAsmPointer(rom, self._ASMPTR_1)))
            self._gfx1.readFromBlock(tgb1)
        updateProgress(20)
        with EbCompressedData() as tgb2:
            tgb2.readFromRom(rom, EbModule.toRegAddr(
                EbModule.readAsmPointer(rom, self._ASMPTR_2)))
            self._gfx2.readFromBlock(tgb2)
        updateProgress(20)
        # Read palettes
        loc = 0x201fc8
        for pal in self._flavPals:
            pal.readFromBlock(rom, loc=loc)
            loc += 64
        updateProgress(5)
        # Read names
        for ptr, field in self._flavNames:
            field.readFromRom(rom, EbModule.toRegAddr(
                EbModule.readAsmPointer(rom, ptr)))
        updateProgress(5)
    def writeToRom(self, rom):
        with EbCompressedData(self._gfx1.sizeBlock()) as gb:
            self._gfx1.writeToBlock(gb)
            EbModule.writeAsmPointer(rom, self._ASMPTR_1,
                    EbModule.toSnesAddr(gb.writeToFree(rom)))
        updateProgress(20)
        with EbCompressedData(self._gfx2.sizeBlock()) as gb:
            self._gfx2.writeToBlock(gb)
            EbModule.writeAsmPointer(rom, self._ASMPTR_2,
                    EbModule.toSnesAddr(gb.writeToFree(rom)))
        updateProgress(20)
        # Write pals
        loc = 0x201fc8
        for pal in self._flavPals:
            pal.writeToBlock(rom, loc=loc)
            loc += 64
        updateProgress(5)
        # Write names
        for ptr, field in self._flavNames:
            loc = EbModule.toSnesAddr(field.writeToFree(rom))
            EbModule.writeAsmPointer(rom, ptr, loc)
        updateProgress(5)
    def writeToProject(self, resourceOpener):
        arr1 = EbArrangement(16, 26)
        for i in range(416):
            arr1[i%16,i/16] = (False, False, False, self._PREVIEW_SUBPALS[i], i)
        i = 0
        for pal in self._flavPals:
            with resourceOpener("WindowGraphics/Windows1_" + str(i),
                    "png") as imgFile:
                img1 = arr1.toImage(self._gfx1, pal)
                img1.save(imgFile, "png")
            with resourceOpener("WindowGraphics/Windows2_" + str(i),
                    "png") as imgFile:
                img2 = self._gfx2.dumpToImage(pal.getSubpal(7), width=7)
                img2.save(imgFile, "png")
            i += 1
        updateProgress(40)
        # Write names
        with resourceOpener("WindowGraphics/flavor_names", "txt") as f:
            for ptr, field in self._flavNames:
                print >>f, field.dump()
        updateProgress(10)
    def readFromProject(self, resourceOpener):
        # Read graphics. Just use the first of each image.
        with resourceOpener("WindowGraphics/Windows1_0", "png") as imgFile:
            img = Image.open(imgFile)
            if img.mode != 'P':
                raise RuntimeError("WindowGraphics/Windows1_0 is not an indexed PNG.")
            self._gfx1.loadFromImage(img)
        updateProgress(20)
        with resourceOpener("WindowGraphics/Windows2_0", "png") as imgFile:
            img = Image.open(imgFile)
            if img.mode != 'P':
                raise RuntimeError("WindowGraphics/Windows2_0 is not an indexed PNG.")
            self._gfx2.loadFromImage(img)
        updateProgress(20)
        # Read pals from Windows1 of each flavor.
        # Read subpal 7 from Windows2 of each flavor.
        i = 0
        for pal in self._flavPals:
            # Read all the palette data from Windows1
            with resourceOpener("WindowGraphics/Windows1_" + str(i),
                    "png") as imgFile:
                img = Image.open(imgFile)
                if img.mode != 'P':
                    raise RuntimeError("WindowGraphics/Windows1_" + str(i) + " is not an indexed PNG.")
                palData = img.getpalette()
                m=0
                for j in range(8):
                    for k in range(4):
                        pal[j,k] = (palData[m], palData[m+1], palData[m+2])
                        m += 3
            # Overwrite subpalette 7 from the palette of Windows2
            with resourceOpener("WindowGraphics/Windows2_" + str(i),
                    "png") as imgFile:
                img = Image.open(imgFile)
                if img.mode != 'P':
                    raise RuntimeError("WindowGraphics/Windows2_" + str(i) + " is not an indexed PNG.")
                palData = img.getpalette()
                m=0
                for k in range(4):
                    pal[7,k] = (palData[m], palData[m+1], palData[m+2])
                    m += 3
            i += 1
        updateProgress(5)
        # Read names
        with resourceOpener("WindowGraphics/flavor_names", "txt") as f:
            for ptr, field in self._flavNames:
                field.load(f.readline()[:-1])
        updateProgress(5)
예제 #3
0
class FontModule(EbModule.EbModule):
    _name = "Fonts"
    _CREDITS_PREVIEW_SUBPALS = [
            1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
            1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
    _ASMPTR_CREDITS_GFX = 0x4f1a7
    _ADDR_CREDITS_PAL = 0x21e914
    def __init__(self):
        self._fonts = [
                Font(0x210cda, 0x210c7a, 16, 16),
                Font(0x2013b9, 0x201359, 16, 16),
                Font(0x2122fa, 0x21229a, 16, 16),
                Font(0x21193a, 0x2118da, 8, 16),
                Font(0x211f9a, 0x211f3a, 8, 8)
                ]
        self._cfont = EbTileGraphics(192, 8, 2)
        self._cpal = EbPalettes(2, 4)
        self._pct = 50.0/(len(self._fonts)+1)
    def freeRanges(self):
        return [(0x21e528, 0x21e913)] # Credits font graphics
    def readCreditsFontFromRom(self, rom):
        self._cpal.readFromBlock(rom, loc=self._ADDR_CREDITS_PAL)
        with EbCompressedData() as cb:
            cb.readFromRom(rom,
                    EbModule.toRegAddr(
                        EbModule.readAsmPointer(
                            rom, self._ASMPTR_CREDITS_GFX)))
            self._cfont.readFromBlock(cb)
    def readFromRom(self, rom):
        for f in self._fonts:
            f.readFromRom(rom)
            updateProgress(self._pct)

        self.readCreditsFontFromRom(rom)
        updateProgress(self._pct)
    def writeToRom(self, rom):
        for f in self._fonts:
            f.writeToRom(rom)
            updateProgress(self._pct)

        self._cpal.writeToBlock(rom, loc=self._ADDR_CREDITS_PAL)
        with EbCompressedData(self._cfont.sizeBlock()) as cb:
            self._cfont.writeToBlock(cb)
            EbModule.writeAsmPointer(rom, self._ASMPTR_CREDITS_GFX,
                    EbModule.toSnesAddr(cb.writeToFree(rom)))
        updateProgress(self._pct)
    def writeCreditsFontToProject(self, resourceOpener):
        arr = EbArrangement(16, 12)
        for i in range(192):
            arr[i%16, i/16] = (False, False, False,
                    self._CREDITS_PREVIEW_SUBPALS[i], i)
        img = arr.toImage(self._cfont, self._cpal)
        with resourceOpener("Fonts/credits", "png") as imgFile:
            img.save(imgFile, "png")
            imgFile.close()
    def writeToProject(self, resourceOpener):
        out = dict()
        i=0
        for font in self._fonts:
            # Write the PNG
            img = font.toImage()
            with resourceOpener("Fonts/" + str(i), 'png') as imgFile:
                img.save(imgFile, 'png')

            # Write the widths
            out = font.dumpWidths()
            with resourceOpener("Fonts/" + str(i) + "_widths", "yml") as f:
                yaml.dump(out, f, default_flow_style=False,
                        Dumper=yaml.CSafeDumper)
            i += 1
            updateProgress(self._pct)

        self.writeCreditsFontToProject(resourceOpener)
        updateProgress(self._pct)
    def readFromProject(self, resourceOpener):
        i = 0
        for font in self._fonts:
            with resourceOpener("Fonts/" + str(i), "png") as imgFile:
                img = Image.open(imgFile)
                if img.mode != 'P':
                    raise RuntimeError("Fonts/" + str(i) + " is not an indexed PNG.")
                font.fromImage(img)
            with resourceOpener("Fonts/" + str(i) + "_widths", "yml") as f:
                input = yaml.load(f, Loader=yaml.CSafeLoader)
                font.loadWidths(input)
            i += 1
            updateProgress(self._pct)

        with resourceOpener("Fonts/credits", "png") as imgFile:
            img = Image.open(imgFile)
            if img.mode != 'P':
                    raise RuntimeError("Fonts/credits is not an indexed PNG.")
            self._cfont.loadFromImage(img)
            self._cpal.loadFromImage(img)
        updateProgress(self._pct)
    def upgradeProject(self, oldVersion, newVersion, rom, resourceOpenerR,
            resourceOpenerW):
        if oldVersion == newVersion:
            updateProgress(100)
            return
        elif oldVersion <= 2:
            self.readCreditsFontFromRom(rom)
            self.writeCreditsFontToProject(resourceOpenerW)
            self.upgradeProject(3, newVersion, rom, resourceOpenerR,
                                        resourceOpenerW)
        else:
            self.upgradeProject(oldVersion+1, newVersion, rom, resourceOpenerR,
                                        resourceOpenerW)
예제 #4
0
class Tileset:
    def __init__(self):
        self.tg = EbTileGraphics(896, 8, 4)
        self.tg._tiles = [ None ] * 896
        self.arr = [None for i in range(0,1024)]
        self.col = [None for i in range(0,1024)]
        self.pals = [ ]
    def readMinitilesFromRom(self, rom, addr):
        with EbCompressedData() as tgb:
            tgb.readFromRom(rom, addr)
            self.tg.readFromBlock(tgb)
    def writeMinitilesToFree(self, rom):
        with EbCompressedData(self.tg.sizeBlock()) as tgb:
            self.tg.writeToBlock(tgb)
            return tgb.writeToFree(rom)
    def readArrangementsFromRom(self, rom, addr):
        with EbCompressedData() as ab:
            ab.readFromRom(rom, addr)
            self.numArrs = len(ab)/32
            a = 0
            for i in range(self.numArrs):
                self.arr[i] = [ [0 for y in range(4)] for z in range(4) ]
                for j in range(4):
                    for k in range(4):
                        self.arr[i][k][j] = ab[a] + (ab[a+1]<<8)
                        a += 2
    def writeArrangementsToFree(self, rom):
        with EbCompressedData(1024*16*2) as ab:
            i=0
            for a in self.arr:
                for j in range(4):
                    for k in range(4):
                        ab[i] = a[k][j] & 0xff
                        ab[i+1] = a[k][j] >> 8
                        i += 2
            return ab.writeToFree(rom)
    def readCollisionsFromRom(self, rom, addr):
        for i in range(self.numArrs):
            tmp = rom.readMulti(addr + i*2, 2)
            self.col[i] = rom[0x180000+tmp:0x180000+tmp+16]
    def readPaletteFromRom(self, rom, mapTset, palNum, addr):
        pal = MapPalette()
        pal.readFromRom(rom, addr)
        self.pals.append((mapTset, palNum, pal))
    def getTileAsString(self, n):
        if n >= 896:
            return "0000000000000000000000000000000000000000000000000000000000000000"
        else:
            s = str()
            t = self.tg[n]
            for j in xrange(8):
                for i in xrange(8):
                    s += chars[t[i][j]]
            return s
    def setTileFromString(self, n, s):
        if n < 896:
            strVals = map(lambda x: int(x,32), s)
            k=0
            tile = [array('B', [0]*8) for i in xrange(8)]
            for j in xrange(8):
                for i in xrange(8):
                    tile[i][j] = strVals[k]
                    k += 1
            self.tg._tiles[n] = tile
    def getArrAsString(self, n):
        if n >= self.numArrs:
            return '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
        else:
            s = str()
            tmp = 0
            for j in xrange(4):
                for k in xrange(4):
                    s += hex(self.arr[n][k][j])[2:].zfill(4)
                    s += hex(self.col[n][j*4+k])[2:].zfill(2)
            return s
    def setArrFromString(self, n, s):
        i=0
        self.arr[n] = [ [0 for y in range(4)] for z in range(4) ]
        self.col[n] = array('B', [0]*16)
        for j in xrange(4):
            for k in xrange(4):
                self.arr[n][k][j] = int(s[i:i+4], 16)
                self.col[n][j*4+k] = int(s[i+4:i+6], 16)
                i += 6
    def writeToFTS(self, file):
        for i in range(512):
            print >>file, self.getTileAsString(i)
            print >>file, self.getTileAsString(i^512)
            print >>file
        print >>file

        for (mt,mp,pal) in self.pals:
            file.write(chars[mt])
            file.write(chars[mp])
            print >>file, pal.getAsString()
        print >>file
        print >>file

        for i in range(1024):
            print >>file, self.getArrAsString(i)
    def hasMapTileset(self, mt):
        for (mt2,mp,pal) in self.pals:
            if mt == mt2:
                return True
        return False
    def readFromFTS(self, file):
        for i in range(512):
            self.setTileFromString(i, file.readline()[:-1])
            self.setTileFromString(i^512, file.readline()[:-1])
            file.readline()
        file.readline()

        while True:
            line = file.readline()
            if line == "\n":
                break
            mt = int(line[0], 32)
            mp = int(line[1], 32)
            pal = MapPalette()
            pal.setFromString(line[2:-1])
            self.pals.append((mt,mp,pal))
        file.readline()

        for i in range(1024):
            self.setArrFromString(i, file.readline()[:-1])