Example #1
0
    def setStrings(self, strings, japanese=False):
        currentString = 0

        for scriptsOfEntity in self.enemyScripts:
            if scriptsOfEntity is None:
                continue

            for script in scriptsOfEntity:
                if script is None:
                    continue

                # Changing strings of MES instructions changes their size,
                # so we need to fixup jump targets. We do this by first
                # converting target offsets to target instruction indexes,
                # changing instructions, and then converting the indexes
                # back to offsets again.

                # Construct list of all instruction offsets
                instrOffsets = [instr.offset for instr in script]

                # Find the target instruction indexes of all jumps
                jumpMap = {
                }  # maps index of jump instruction to index of target

                for index in xrange(len(script)):
                    instr = script[index]

                    if instr.op in [Op.JMPZ, Op.JMPNE, Op.JMP]:
                        targetOffset = struct.unpack("<H", instr.code[1:])[0]
                        targetIndex = instrOffsets.index(targetOffset)
                        jumpMap[index] = targetIndex

                # Replace the strings in all MES instructions
                for index in xrange(len(script)):
                    if script[index].op == Op.MES:
                        rawString = ff7.encodeKernelText(
                            strings[currentString], japanese)
                        script[index].setArg(rawString)
                        currentString += 1

                # Recalculate all instruction offsets
                offset = 0
                for index in xrange(len(script)):
                    script[index].setOffset(offset)
                    offset += script[index].size

                # Fixup the target offsets of jumps
                for index in xrange(len(script)):
                    if script[index].op in [Op.JMPZ, Op.JMPNE, Op.JMP]:
                        targetIndex = jumpMap[index]
                        targetOffset = script[targetIndex].offset
                        script[index].setArg(struct.pack("<H", targetOffset))

        # Convert scripts back to binary data
        self.insertScripts(self.enemyScripts, self.aiDataOffset, 3,
                           len(self.data))
Example #2
0
    def setStrings(self, strings, japanese = False):
        currentString = 0

        for scriptsOfEntity in self.enemyScripts:
            if scriptsOfEntity is None:
                continue

            for script in scriptsOfEntity:
                if script is None:
                    continue

                # Changing strings of MES instructions changes their size,
                # so we need to fixup jump targets. We do this by first
                # converting target offsets to target instruction indexes,
                # changing instructions, and then converting the indexes
                # back to offsets again.

                # Construct list of all instruction offsets
                instrOffsets = [instr.offset for instr in script]

                # Find the target instruction indexes of all jumps
                jumpMap = {}  # maps index of jump instruction to index of target

                for index in xrange(len(script)):
                    instr = script[index]

                    if instr.op in [Op.JMPZ, Op.JMPNE, Op.JMP]:
                        targetOffset = struct.unpack("<H", instr.code[1:])[0]
                        targetIndex = instrOffsets.index(targetOffset)
                        jumpMap[index] = targetIndex

                # Replace the strings in all MES instructions
                for index in xrange(len(script)):
                    if script[index].op == Op.MES:
                        rawString = ff7.encodeKernelText(strings[currentString], japanese)
                        script[index].setArg(rawString)
                        currentString += 1

                # Recalculate all instruction offsets
                offset = 0
                for index in xrange(len(script)):
                    script[index].setOffset(offset)
                    offset += script[index].size

                # Fixup the target offsets of jumps
                for index in xrange(len(script)):
                    if script[index].op in [Op.JMPZ, Op.JMPNE, Op.JMP]:
                        targetIndex = jumpMap[index]
                        targetOffset = script[targetIndex].offset
                        script[index].setArg(struct.pack("<H", targetOffset))

        # Convert scripts back to binary data
        self.insertScripts(self.enemyScripts, self.aiDataOffset, 3, len(self.data))
Example #3
0
    def setAbilityNames(self, abilities, japanese = False):
        for i in xrange(32):
            rawString = ff7.encodeKernelText(abilities[i], japanese)
            rawStringSize = len(rawString)

            if rawStringSize > self.maxStringSize:
                raise EnvironmentError, "Ability name '%s' in scene %d is too long when encoded (%d > %d bytes)" % (abilities[i], self.index, rawStringSize, self.maxStringSize)

            if rawStringSize < self.maxStringSize:
                rawString += '\xff' * (self.maxStringSize - rawStringSize)  # pad with 0xff bytes

            offset = self.abilitiesOffset + i * self.maxStringSize
            self.data = self.data[:offset] + rawString + self.data[offset + self.maxStringSize:]
Example #4
0
    def setEnemyNames(self, enemies, japanese=False):
        for i in xrange(3):
            rawString = ff7.encodeKernelText(enemies[i], japanese)
            rawStringSize = len(rawString)

            if rawStringSize > self.maxStringSize:
                raise EnvironmentError, "Enemy name '%s' in scene %d is too long when encoded (%d > %d bytes)" % (
                    enemies[i], self.index, rawStringSize, self.maxStringSize)

            if rawStringSize < self.maxStringSize:
                rawString += '\xff' * (self.maxStringSize - rawStringSize
                                       )  # pad with 0xff bytes

            offset = self.enemyDataOffset + i * self.enemyDataSize
            self.data = self.data[:offset] + rawString + self.data[
                offset + self.maxStringSize:]