Пример #1
0
class MapSpriteModule(EbModule.EbModule):
    _name = "Map Sprites"
    _PTR_LOC = 0x2261
    def __init__(self):
        self._ptrTbl = EbTable("SPRITE_PLACEMENT_PTR_TABLE")
        self._entries = [ ]
    def readFromRom(self, rom):
        ptr = EbModule.toRegAddr(rom.readMulti(self._PTR_LOC, 3))
        updateProgress(5)
        self._ptrTbl.readFromRom(rom, ptr)
        pct = 45.0/(40*32)
        for i in range(self._ptrTbl.height()):
            loc = self._ptrTbl[i,0].val()
            # Format: AA AA [BB BB YY XX]
            # AA = # of entries. BB = TPT. YY = y pos. XX = x pos.
            if loc != 0:
                loc |= 0x0F0000
                entry = [ ]
                size = rom.readMulti(loc, 2)
                loc += 2
                for i in range(size):
                    entry.append(SpritePlacement(
                        rom.readMulti(loc, 2),
                        rom[loc+3], rom[loc+2]))
                    loc += 4
                self._entries.append(entry)
            else:
                self._entries.append(None)
            updateProgress(pct)
    def writeToProject(self, resourceOpener):
        out = dict()
        x = y = 0
        rowOut = dict()
        pct = 45.0/(40*32)
        for entry in self._entries:
            if entry != None:
                rowOut[x%32] = map(
                        lambda sp: {
                            "NPC ID": sp.npcID,
                            "X": sp.x,
                            "Y": sp.y },
                        entry)
            else:
                rowOut[x%32] = None
            if (x % 32) == 31:
                # Start next row
                out[y] = rowOut
                x = 0
                y += 1
                rowOut = dict()
            else:
                x += 1
            updateProgress(pct)
        with resourceOpener("map_sprites", "yml") as f:
            yaml.dump(out, f, Dumper=yaml.CSafeDumper)
        updateProgress(5)
    def readFromProject(self, resourceOpener):
        self._entries = []
        pct = 45.0/(40*32)
        with resourceOpener("map_sprites", "yml") as f:
            input = yaml.load(f, Loader=yaml.CSafeLoader)
            updateProgress(5)
            for y in input:
                row = input[y]
                for x in row:
                    if row[x] == None:
                        self._entries.append(None)
                    else:
                        self._entries.append(map(lambda x: SpritePlacement(
                            x["NPC ID"], x["X"], x["Y"]),
                            row[x]))
                    updateProgress(pct)
    def writeToRom(self, rom):
        self._ptrTbl.clear(32*40)
        writeLoc = 0xf61e7
        writeRangeEnd = 0xf8984
        i = 0
        pct = 45.0/(40*32)
        for entry in self._entries:
            if (entry == None) or (not entry):
                self._ptrTbl[i,0].setVal(0)
            else:
                entryLen = len(entry)
                with DataBlock(2 + entryLen*4) as block:
                    block[0] = entryLen & 0xff
                    block[1] = entryLen >> 8
                    j = 2
                    for sprite in entry:
                        block[j] = sprite.npcID & 0xff
                        block[j+1] = sprite.npcID >> 8
                        block[j+2] = sprite.y
                        block[j+3] = sprite.x
                        j += 4
                    if writeLoc + len(block) > writeRangeEnd:
                        # TODO Error, not enough space
                        raise RuntimeError("Not enough map sprite space")
                    else:
                        block.writeToRom(rom, writeLoc)
                        self._ptrTbl[i,0].setVal(writeLoc & 0xffff)
                        writeLoc += len(block)
            updateProgress(pct)
            i += 1
        loc = self._ptrTbl.writeToFree(rom)
        rom.writeMulti(self._PTR_LOC, EbModule.toSnesAddr(loc), 3)
        # Mark any remaining space as free
        if writeLoc < writeRangeEnd:
            rom.addFreeRanges([(writeLoc, writeRangeEnd)])
        updateProgress(5)
Пример #2
0
class BattleBgModule(EbModule.EbModule):
    _name = "Battle Backgrounds"
    _ASMPTRS_GFX = [0x2d1ba, 0x2d4dc, 0x2d8c3, 0x4a3ba]
    _ASMPTRS_ARR = [0x2d2c1, 0x2d537, 0x2d91f, 0x4a416]
    _ASMPTRS_PAL = [0x2d3bb, 0x2d61b, 0x2d7e8, 0x2d9e8, 0x4a4d0]
    def __init__(self):
        self._bbgGfxPtrTbl = EbTable("BATTLEBG_GFX_POINTERS")
        self._bbgArrPtrTbl = EbTable("BATTLEBG_ARR_POINTERS")
        self._bbgPalPtrTbl = EbTable("BATTLEBG_PALETTE_POINTERS")
        self._bbgScrollTbl = EbTable("BG_SCROLLING_TABLE")
        self._bbgDistorTbl = EbTable("BG_DISTORTION_TABLE")
        self._bbgTbl = EbTable("BG_DATA_TABLE")
    def free(self):
        del(self._bbgGfxPtrTbl)
        del(self._bbgArrPtrTbl)
        del(self._bbgPalPtrTbl)
        del(self._bbgTbl)

        del(self._bbgGfxArrs)
        del(self._bbgPals)
    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)
    def writeToProject(self, resourceOpener):
        pct = 50.0/(3+self._bbgTbl.height())
        self._bbgTbl.writeToProject(resourceOpener, hiddenColumns=[0,1])
        updateProgress(pct)
        self._bbgScrollTbl.writeToProject(resourceOpener)
        updateProgress(pct)
        self._bbgDistorTbl.writeToProject(resourceOpener)
        updateProgress(pct)
        # Export BGs by table entry
        for i in range(self._bbgTbl.height()):
            (tg, a) = self._bbgGfxArrs[self._bbgTbl[i,0].val()]
            pal = self._bbgTbl[i,1].val()
            img = a.toImage(tg, self._bbgPals[pal])
            imgFile = resourceOpener('BattleBGs/' + str(i).zfill(3), 'png')
            img.save(imgFile, 'png')
            imgFile.close()
            del(img)
            updateProgress(pct)
    def readFromProject(self, resourceOpener):
        self._bbgTbl.readFromProject(resourceOpener)
        pct = 50.0/(2+self._bbgTbl.height())
        self._bbgScrollTbl.readFromProject(resourceOpener)
        updateProgress(pct)
        self._bbgDistorTbl.readFromProject(resourceOpener)
        updateProgress(pct)
        self._bbgGfxArrs = []
        self._bbgPals = []
        for i in range(self._bbgTbl.height()):
            img = Image.open(
                    resourceOpener('BattleBGs/' + str(i).zfill(3), 'png'))

            np = EbPalettes(1, 16)
            colorDepth = self._bbgTbl[i,2].val()
            # Max size used in rom: 421 (2bpp) 442 (4bpp)
            ntg = EbTileGraphics(512, 8, colorDepth)
            na = EbArrangement(32, 32)
            na.readFromImage(img, np, ntg)
            j=0
            for (tg, a) in self._bbgGfxArrs:
                if (tg == ntg) and (a == na):
                    self._bbgTbl[i,0].setVal(j)
                    break
                j += 1
            else:
                self._bbgGfxArrs.append((ntg, na))
                self._bbgTbl[i,0].setVal(j)
            j=0
            for p in self._bbgPals:
                if (p == np):
                    self._bbgTbl[i,1].setVal(j)
                    break
                j += 1
            else:
                self._bbgPals.append((np))
                self._bbgTbl[i,1].setVal(j)
            updateProgress(pct)
    def freeRanges(self):
        return [(0xa0000,0xadca0), (0xb0000, 0xbd899)]
    def writeToRom(self, rom):
        self._bbgGfxPtrTbl.clear(len(self._bbgGfxArrs))
        self._bbgArrPtrTbl.clear(len(self._bbgGfxArrs))
        self._bbgPalPtrTbl.clear(len(self._bbgPals))

        # Write gfx+arrs
        i = 0
        pct = (50.0/3)/len(self._bbgGfxArrs)
        for (tg, a) in self._bbgGfxArrs:
            with EbCompressedData(tg.sizeBlock()) as tgb:
                tg.writeToBlock(tgb)
                self._bbgGfxPtrTbl[i,0].setVal(EbModule.toSnesAddr(
                    tgb.writeToFree(rom)))
            with EbCompressedData(a.sizeBlock()) as ab:
                a.writeToBlock(ab)
                self._bbgArrPtrTbl[i,0].setVal(EbModule.toSnesAddr(
                    ab.writeToFree(rom)))
            i += 1
            updateProgress(pct)
        EbModule.writeAsmPointers(rom, self._ASMPTRS_GFX,
                EbModule.toSnesAddr(self._bbgGfxPtrTbl.writeToFree(rom)))
        EbModule.writeAsmPointers(rom, self._ASMPTRS_ARR,
                EbModule.toSnesAddr(self._bbgArrPtrTbl.writeToFree(rom)))

        # Write pals
        i = 0
        pct = (50.0/3)/len(self._bbgPals)
        for p in self._bbgPals:
            with DataBlock(32) as pb:
                p.writeToBlock(pb)
                self._bbgPalPtrTbl[i,0].setVal(EbModule.toSnesAddr(
                    pb.writeToFree(rom)))
            i += 1
            updateProgress(pct)
        EbModule.writeAsmPointers(rom, self._ASMPTRS_PAL,
                EbModule.toSnesAddr(self._bbgPalPtrTbl.writeToFree(rom)))

        # Write the data table
        pct = (50.0/3)/3
        self._bbgTbl.writeToRom(rom)
        updateProgress(pct)
        self._bbgScrollTbl.writeToRom(rom)
        updateProgress(pct)
        self._bbgDistorTbl.writeToRom(rom)
        updateProgress(pct)
Пример #3
0
class EnemyModule(EbModule.EbModule):
    _name = "Enemies"
    _ASMPTR_GFX = 0x2ee0b
    _REGPTR_GFX = [ 0x2ebe0, 0x2f014, 0x2f065 ]
    _ASMPTR_PAL = 0x2ef74
    def __init__(self):
        self._enemyCfgTable = EbTable(0xd59589)
        self._bsPtrTbl = EbTable(0xce62ee)
        self._bsPalsTable = EbTable(0xce6514)
        self._enemyGroupTbl = EbTable(0xD0C60D)
        self._enemyGroupBgTbl = EbTable(0xCBD89A)

        self._bsprites = [ ]
        self._bsPals = [ ]
        self._enemyGroups = [ ]
    def readFromRom(self, rom):
        self._bsPtrTbl.readFromRom(rom,
                EbModule.toRegAddr(EbModule.readAsmPointer(rom,
                    self._ASMPTR_GFX)))
        self._bsPalsTable.readFromRom(rom,
                EbModule.toRegAddr(EbModule.readAsmPointer(rom,
                    self._ASMPTR_PAL)))
        pct = 45.0/(self._bsPtrTbl.height()
                + self._bsPalsTable.height() + 1)
        self._enemyCfgTable.readFromRom(rom)
        updateProgress(pct)
        # Read the palettes
        for i in range(self._bsPalsTable.height()):
            pal = EbPalettes(1,16)
            pal.set(0, self._bsPalsTable[i,0].val())
            self._bsPals.append(pal)
            updateProgress(pct)
        # Read the sprites
        for i in range(self._bsPtrTbl.height()):
            with EbCompressedData() as bsb:
                bsb.readFromRom(rom,
                        EbModule.toRegAddr(self._bsPtrTbl[i,0].val()))
                bs = EbBattleSprite()
                bs.readFromBlock(bsb, self._bsPtrTbl[i,1].val())
                self._bsprites.append(bs)
            updateProgress(pct)

        # Read the group data
        self._enemyGroupTbl.readFromRom(rom)
        self._enemyGroupBgTbl.readFromRom(rom)
        self._enemyGroups = [ ]
        pct = 5.0/self._enemyGroupTbl.height()
        for i in range(self._enemyGroupTbl.height()):
            group = [ ]
            ptr = EbModule.toRegAddr(self._enemyGroupTbl[i,0].val())
            while(rom[ptr] != 0xff):
                group.append((rom.readMulti(ptr+1,2), rom[ptr]))
                ptr += 3
            self._enemyGroups.append(group)
            updateProgress(pct)
    def freeRanges(self):
        return [(0x0d0000, 0x0dffff), # Battle Sprites
                (0x0e0000, 0x0e6913), # Battle Sprites Cont'd & Btl Spr. Pals
                (0x10d52d, 0x10dfb3)] # Enemy Group Data
    def writeToRom(self, rom):
        pct = 40.0/(len(self._bsprites) + len(self._bsPals) + 3)
        # Write the main table
        self._enemyCfgTable.writeToRom(rom)
        updateProgress(pct)
        # Write the gfx ptr table
        self._bsPtrTbl.clear(len(self._bsprites))
        i = 0
        for bs in self._bsprites:
            with EbCompressedData(bs.sizeBlock()) as bsb:
                bs.writeToBlock(bsb)
                self._bsPtrTbl[i,0].setVal(EbModule.toSnesAddr(
                    bsb.writeToFree(rom)))
            self._bsPtrTbl[i,1].setVal(bs.size())
            i += 1
            updateProgress(pct)
        gfxAddr = EbModule.toSnesAddr(self._bsPtrTbl.writeToFree(rom))
        EbModule.writeAsmPointer(rom, self._ASMPTR_GFX, gfxAddr)
        updateProgress(pct)
        for p in self._REGPTR_GFX:
            rom.writeMulti(p, gfxAddr, 3)
        # Write the pal table
        self._bsPalsTable.clear(len(self._bsPals))
        i = 0
        for p in self._bsPals:
            self._bsPalsTable[i,0].setVal(p.getSubpal(0))
            i += 1
            updateProgress(pct)
        EbModule.writeAsmPointer(rom, self._ASMPTR_PAL,
                EbModule.toSnesAddr(self._bsPalsTable.writeToFree(rom)))
        updateProgress(pct)
        # Write the groups
        self._enemyGroupBgTbl.writeToRom(rom)
        updateProgress(5)
        i=0
        for group in self._enemyGroups:
            loc = rom.getFreeLoc(len(group)*3 + 1)
            self._enemyGroupTbl[i,0].setVal(EbModule.toSnesAddr(loc))
            i += 1
            for enemyID, amount in group:
                rom[loc] = amount
                rom[loc+1] = enemyID & 0xff
                rom[loc+2] = enemyID >> 8
                loc += 3
            rom[loc] = 0xff
        self._enemyGroupTbl.writeToRom(rom)
        updateProgress(5)
    def writeToProject(self, resourceOpener):
        pct = 40.0/(self._enemyCfgTable.height() + 1)
        # First, write the Enemy Configuration Table
        self._enemyCfgTable.writeToProject(resourceOpener, [4,14])
        updateProgress(pct)

        # Next, write the battle sprite images
        for i in range(self._enemyCfgTable.height()):
            if self._enemyCfgTable[i,4].val() > 0:
                self._bsprites[self._enemyCfgTable[i,4].val()-1].writeToProject(
                        resourceOpener, i,
                        self._bsPals[self._enemyCfgTable[i,14].val()].getSubpal(0))
            updateProgress(pct)

        # Now write the groups
        out = dict()
        i = 0
        pct = 5.0/len(self._enemyGroups)
        for group in self._enemyGroups:
            entry = dict()
            for j in range(1,4):
                field = self._enemyGroupTbl[i,j]
                entry[field.name] = field.dump()
            for j in range(2):
                field = self._enemyGroupBgTbl[i,j]
                entry[field.name] = field.dump()
            enemyList = dict()
            j = 0
            for enemyID, amount in group:
                enemyEntry = dict()
                enemyEntry["Enemy"] = enemyID
                enemyEntry["Amount"] = amount
                enemyList[j] = enemyEntry
                j += 1
            entry["Enemies"] = enemyList
            out[i] = entry
            i += 1
            updateProgress(pct)
        with resourceOpener("enemy_groups", "yml") as f:
            yaml.dump(out, f, Dumper=yaml.CSafeDumper)
        updateProgress(5)
    def readFromProject(self, resourceOpener):
        # First, read the Enemy Configuration Table
        self._enemyCfgTable.readFromProject(resourceOpener)
        pct = 40.0/(self._enemyCfgTable.height())

        # Second, read the Battle Sprites
        bsHashes = dict()
        bsNextNum = 1
        palNextNum = 0
        for i in range(self._enemyCfgTable.height()):
            bs = EbBattleSprite()
            pal = EbPalettes(1,16)
            try:
                bs.readFromProject(resourceOpener, i, pal)
                # Add the battle sprite
                try:
                    #self._enemyCfgTable[i,4].set(self._bsprites.index(bs))
                    bsNum = bsHashes[bs._sprite._spriteHash]
                    self._enemyCfgTable[i,4].setVal(bsNum)
                except KeyError:
                    self._bsprites.append(bs)
                    self._enemyCfgTable[i,4].setVal(bsNextNum)
                    bsHashes[bs._sprite._spriteHash] = bsNextNum
                    bsNextNum += 1
                # Add the palette
                # TODO should probably use hash table here too?
                #      then again, I don't think it's actually a bottleneck
                try:
                    self._enemyCfgTable[i,14].setVal(self._bsPals.index(pal))
                except ValueError:
                    self._bsPals.append(pal)
                    self._enemyCfgTable[i,14].setVal(palNextNum)
                    palNextNum += 1
            except IOError:
                # No battle sprite PNG
                self._enemyCfgTable[i,4].setVal(0)
                self._enemyCfgTable[i,14].setVal(0)
            updateProgress(pct)

        # Third, read the groups
        self._enemyGroupTbl.readFromProject(resourceOpener, "enemy_groups")
        updateProgress(2)
        self._enemyGroupBgTbl.readFromProject(resourceOpener, "enemy_groups")
        updateProgress(2)
        self._enemyGroups = [ ]
        pct = 4.0/484
        with resourceOpener("enemy_groups", "yml") as f:
            input = yaml.load(f, Loader=yaml.CSafeLoader)
            updateProgress(2)
            for group in input:
                tmp1 = input[group]["Enemies"]
                enemyList = [ ]
                i = 0
                for enemy in tmp1:
                    tmp2 = tmp1[i]
                    enemyList.append((tmp2["Enemy"], tmp2["Amount"]))
                    i += 1
                self._enemyGroups.append(enemyList)
                updateProgress(pct)
Пример #4
0
class TownMapIconModule(EbModule.EbModule):
    _name = "Town Map Icon Positions"
    _ASMPTR_PTR_TBL = 0x4d464
    def __init__(self):
        self._ptrTbl = EbTable(0xE1F491)
        self._entries = [ ]
        self._entryIdField = ValuedIntTableEntry(None, None,
                ["Onett", "Twoson", "Threed", "Fourside", "Scaraba", "Summers"])
        self._iconField = ValuedIntTableEntry(None, None,
                ["0", "Hamburger Shop", "Bakery", "Hotel",
                "Restaurant", "Hospital", "Shop", "Dept Store", "Bus Stop",
                "South to Twoson", "North to Onett", "South to Threed",
                "West to Twoson", "East to Desert", "West to Desert",
                "East to Toto", "Hint", "Ness", "Small Ness",
                "North", "South", "West", "East" ])
    def freeRanges(self):
        return [(0x21f491, 0x21f580)] # Pointer Table and Data
    def readFromRom(self, rom):
        self._ptrTbl.readFromRom(rom,
                EbModule.toRegAddr(EbModule.readAsmPointer(rom,
                    self._ASMPTR_PTR_TBL)))
        updateProgress(5)
        for i in range(self._ptrTbl.height()):
            loc = EbModule.toRegAddr(self._ptrTbl[i,0].val())
            entry = []
            while True:
                x = rom[loc]
                if x == 0xff:
                    break
                y = rom[loc+1]
                icon = rom[loc+2]
                flag = rom.readMulti(loc+3, 2)
                entry.append((x, y, icon, flag))
                loc += 5
            self._entries.append(entry)
            i += 1
        updateProgress(45)
    def writeToRom(self, rom):
        self._ptrTbl.clear(6)
        i = 0
        for entry in self._entries:
            writeLoc = rom.getFreeLoc(len(entry)*5 + 1)
            self._ptrTbl[i,0].setVal(
                    EbModule.toSnesAddr(writeLoc))
            for (x, y, icon, flag) in entry:
                rom[writeLoc] = x
                rom[writeLoc+1] = y
                rom[writeLoc+2] = icon
                rom.writeMulti(writeLoc+3, flag, 2)
                writeLoc += 5
            rom[writeLoc] = 0xff
            i += 1
        updateProgress(45)
        EbModule.writeAsmPointer(rom, self._ASMPTR_PTR_TBL,
                EbModule.toSnesAddr(
                    self._ptrTbl.writeToFree(rom)))
        updateProgress(5)
    def readFromProject(self, resourceOpener):
        self._entries = [None] * 6
        with resourceOpener("TownMaps/icon_positions", "yml") as f:
            data = yaml.load(f, Loader=yaml.CSafeLoader)
            for name in data:
                entry = []
                for subEntry in data[name]:
                    self._iconField.load(subEntry["Icon"])
                    entry.append((
                        subEntry["X"],
                        subEntry["Y"],
                        self._iconField.val(),
                        subEntry["Event Flag"]))
                self._entryIdField.load(name)
                self._entries[self._entryIdField.val()] = entry
        updateProgress(50)
    def writeToProject(self, resourceOpener):
        out = dict()
        i = 0
        for entry in self._entries:
            outEntry = []
            for (x, y, icon, flag) in entry:
                self._iconField.setVal(icon)
                outEntry.append({
                    "X": x,
                    "Y": y,
                    "Icon": self._iconField.dump(),
                    "Event Flag": flag })
            self._entryIdField.setVal(i)
            out[self._entryIdField.dump()] = outEntry
            i += 1
        updateProgress(25)
        with resourceOpener("TownMaps/icon_positions", "yml") as f:
            s = yaml.dump(out, default_flow_style=False,
                    Dumper=yaml.CSafeDumper)
            s = sub("Event Flag: (\d+)",
                    lambda i: "Event Flag: " + hex(int(i.group(0)[12:])), s)
            f.write(s)
        updateProgress(25)
    def upgradeProject(self, oldVersion, newVersion, rom, resourceOpenerR,
            resourceOpenerW):
        global updateProgress
        if oldVersion == newVersion:
            updateProgress(100)
            return
        elif oldVersion <= 2:
            tmp = updateProgress
            updateProgress = lambda x: None
            self.readFromRom(rom)
            self.writeToProject(resourceOpenerW)
            updateProgress = tmp
            self.upgradeProject(3, newVersion, rom, resourceOpenerR,
                    resourceOpenerW)
        else:
            self.upgradeProject(oldVersion+1, newVersion, rom, resourceOpenerR,
                    resourceOpenerW)
Пример #5
0
class MapMusicModule(EbModule.EbModule):
    _ASMPTR = 0x6939
    _name = "Map Music"
    def __init__(self):
        self._ptrTbl = EbTable(0xCF58EF)
        self._entries = []
    def readFromRom(self, rom):
        self._ptrTbl.readFromRom(rom,
                EbModule.toRegAddr(rom.readMulti(self._ASMPTR, 3)))
        updateProgress(25)
        for i in range(self._ptrTbl.height()):
            loc = 0xf0000 | self._ptrTbl[i,0].val()
            entry = [ ]
            flag = 1
            while flag != 0:
                flag = rom.readMulti(loc, 2)
                music = rom[loc+2]
                entry.append((flag, music))
                loc += 4
            self._entries.append(entry)
        updateProgress(25)
    def writeToRom(self, rom):
        self._ptrTbl.clear(165)
        writeLoc = 0xf58ef
        writeRangeEnd = 0xf61e5 # TODO Can re-use bank space from doors
        i=0
        for entry in self._entries:
            entryLen = len(entry)*4
            if writeLoc+entryLen > writeRangeEnd:
                raise RuntimeError("Not enough room for map music")
            self._ptrTbl[i,0].setVal(writeLoc & 0xffff)
            i += 1

            for (flag, music) in entry:
                rom.writeMulti(writeLoc, flag, 2)
                rom[writeLoc+2] = music
                rom[writeLoc+3] = 0
                writeLoc += 4
        updateProgress(25)
        rom.writeMulti(self._ASMPTR,
                EbModule.toSnesAddr(self._ptrTbl.writeToFree(rom)), 3)
        if writeLoc < writeRangeEnd:
            rom.addFreeRanges([(writeLoc, writeRangeEnd)])
        updateProgress(25)
    def writeToProject(self, resourceOpener):
        out = dict()
        i = 0
        for entry in self._entries:
            outEntry = []
            for (flag, music) in entry:
                outEntry.append({
                    "Event Flag": flag,
                    "Music": music })
            out[i] = outEntry
            i += 1
        updateProgress(25)
        with resourceOpener("map_music", "yml") as f:
            s = yaml.dump(out, default_flow_style=False,
                    Dumper=yaml.CSafeDumper)
            s = sub("Event Flag: (\d+)",
                    lambda i: "Event Flag: " + hex(int(i.group(0)[12:])), s)
            f.write(s)
        updateProgress(25)
    def readFromProject(self, resourceOpener):
        with resourceOpener("map_music", "yml") as f:
            input = yaml.load(f, Loader=yaml.CSafeLoader)
            for i in input:
                entry = []
                for subEntry in input[i]:
                    entry.append((subEntry["Event Flag"],
                        subEntry["Music"]))
                self._entries.append(entry)
        updateProgress(50)
Пример #6
0
class MapEventModule(EbModule.EbModule):
    _name = "Map Events"
    _PTR_LOC = 0x70d
    _PTR_BANK_LOC = 0x704
    def __init__(self):
        self._ptrTbl = EbTable(0xD01598)
        self._entries = [ ]
    def freeRanges(self):
        return [(0x101598, 0x10187f)]
    def readFromRom(self, rom):
        self._ptrTbl.readFromRom(rom,
                EbModule.toRegAddr(rom.readMulti(self._PTR_LOC, 3)))
        updateProgress(5)
        bank = (rom[self._PTR_BANK_LOC] - 0xc0) << 16
        pct = 45.0/20
        for i in range(20):
            addr = bank | self._ptrTbl[i,0].val()
            tsetEntry = []
            while (rom.readMulti(addr, 2) != 0):
                flag = rom.readMulti(addr, 2)
                num = rom.readMulti(addr+2, 2)
                addr += 4
                changes = []
                for j in range(num):
                    changes.append((rom.readMulti(addr, 2),
                            rom.readMulti(addr+2, 2)))
                    addr += 4
                tsetEntry.append((flag, changes))
            self._entries.append(tsetEntry)
            updateProgress(pct)
    def writeToProject(self, resourceOpener):
        out = dict()
        i = 0
        for entry in self._entries:
            entryOut = []
            for (flag, changes) in entry:
                changeOut = { "Event Flag": flag }
                changeOut["Changes"] = changes
                entryOut.append(changeOut)
            if entryOut == []:
                out[i] = None
            else:
                out[i] = entryOut
            i += 1
        updateProgress(25)
        with resourceOpener("map_changes", "yml") as f:
            s = yaml.dump(out, Dumper=yaml.CSafeDumper)
            s = sub("Event Flag: (\d+)",
                    lambda i: "Event Flag: " + hex(int(i.group(0)[12:])), s)
            f.write(s)
        updateProgress(25)
    def readFromProject(self, resourceOpener):
        with resourceOpener("map_changes", "yml") as f:
            input = yaml.load(f, Loader=yaml.CSafeLoader)
            for mtset in input:
                entry = []
                entryIn = input[mtset]
                if (entryIn != None):
                    for csetIn in entryIn:
                        entry.append((csetIn["Event Flag"],
                            csetIn["Changes"]))
                self._entries.append(entry)
                updateProgress(50.0/20)
    def writeToRom(self, rom):
        self._ptrTbl.clear(20)
        blockSize = 0
        for entry in self._entries:
            for (flag, set) in entry:
                blockSize += 4 + 4*len(set)
            blockSize += 2
        if blockSize > 0xffff:
            raise RuntimeError("Too many map changes")
        loc = rom.getFreeLoc(blockSize)
        rom[self._PTR_BANK_LOC] = (loc >> 16) + 0xc0
        i = 0
        for entry in self._entries:
            self._ptrTbl[i,0].setVal(loc & 0xffff)
            for (flag, set) in entry:
                rom.writeMulti(loc, flag, 2)
                rom.writeMulti(loc+2, len(set), 2)
                loc += 4
                for (before, after) in set:
                    rom.writeMulti(loc, before, 2)
                    rom.writeMulti(loc+2, after, 2)
                    loc += 4
            rom[loc] = 0
            rom[loc+1] = 0
            loc += 2
            i += 1
            updateProgress(45.0/20)
        ptrTblLoc = self._ptrTbl.writeToFree(rom)
        rom.writeMulti(self._PTR_LOC, EbModule.toSnesAddr(ptrTblLoc), 3)
        updateProgress(5)