예제 #1
0
 def open_new_constraint_dialog(self):
     address = self.cursor
     constraint = Constraint(self.rom_variant, self.address_resolver.to_local(
         address), None, None, 5, settings.get_username(), None, True)
     dialog = EditConstraintDialog(self.dock, constraint)
     dialog.constraint_changed.connect(self.add_new_constraint)
     dialog.show()
예제 #2
0
 def get_constraint(self) -> Constraint:
     return Constraint(RomVariant(self.ui.comboBoxVariantA.currentText()),
                       parse_address(self.ui.lineEditAddressA.text()),
                       RomVariant(self.ui.comboBoxVariantB.currentText()),
                       parse_address(self.ui.lineEditAddressB.text()),
                       self.ui.spinBoxCertainty.value(),
                       self.ui.lineEditAuthor.text(),
                       self.ui.plainTextEditNote.toPlainText().strip(),
                       self.ui.checkBoxEnabled.isChecked())
예제 #3
0
def test_first_constraint():
    # v  U D
    # 0  0 0
    # 1  x 1
    # 2  1-2
    # 3  2 3
    # 4  3
    manager = ConstraintManager({RomVariant.USA, RomVariant.DEMO})
    constraint = Constraint()
    constraint.romA = RomVariant.USA
    constraint.addressA = 1
    constraint.romB = RomVariant.DEMO
    constraint.addressB = 2
    manager.add_constraint(constraint)
    manager.rebuild_relations()
    assert_same_address(manager, RomVariant.USA, 0)
    assert_same_address(manager, RomVariant.DEMO, 0)
    assert_same_address(manager, RomVariant.DEMO, 1)
    assert_same_address(manager, RomVariant.DEMO, 2)
    assert_same_address(manager, RomVariant.DEMO, 3)
    assert_same_address(manager, RomVariant.DEMO, 0xffffff)
    assert_differing_address(manager, RomVariant.USA, 1, 2)
    assert_differing_address(manager, RomVariant.USA, 2, 3)
    assert_differing_address(manager, RomVariant.USA, 0xffffff, 0xffffff + 1)
    print('---')
    assert -1 == manager.to_local(RomVariant.USA, 1)
예제 #4
0
def test_many_small_differences():
    #  v  U  J  E  D
    #  0  0  0  0  0
    #  1  1  x
    #  2  2  x
    #  3  3--1     3
    #  4  4  2     x
    #  5  5  3  5--4-
    #  6  x  x  6
    #  7  x  4--7
    #  8  x  5  8
    #  9  6--6  x  8
    # 10  x  7  x  x
    # 11  7--8--9--9  # constraints from J to all
    # 12  8  9  x 10
    # 13  9 10 10-11
    # 14  x 11-11 x
    # 15 10-12 12 x
    # 16 11 13 13-12
    manager = ConstraintManager(
        {RomVariant.USA, RomVariant.JP, RomVariant.EU, RomVariant.DEMO})
    add_u_d_constraint(manager, 5, 4)
    add_u_j_constraint(manager, 10, 12)
    add_u_j_constraint(manager, 3, 1)
    manager.add_constraint(Constraint(RomVariant.JP, 8, RomVariant.DEMO, 9))
    add_j_e_constraint(manager, 4, 7)
    add_u_j_constraint(manager, 6, 6)
    add_j_e_constraint(manager, 8, 9)
    add_j_e_constraint(manager, 11, 11)
    add_e_d_constraint(manager, 13, 12)
    add_e_d_constraint(manager, 5, 4)
    add_u_j_constraint(manager, 7, 8)
    add_e_d_constraint(manager, 10, 11)
    manager.rebuild_relations()
    manager.print_relations()
    assert_u_j_e_d_address(manager, 0, 0, 0, 0, 0)
    assert_u_j_e_d_address(manager, 1, 1, -1, 1, 1)
    assert_u_j_e_d_address(manager, 2, 2, -1, 2, 2)
    assert_u_j_e_d_address(manager, 3, 3, 1, 3, 3)
    assert_u_j_e_d_address(manager, 4, 4, 2, 4, -1)
    assert_u_j_e_d_address(manager, 5, 5, 3, 5, 4)
    assert_u_j_e_d_address(manager, 6, -1, -1, 6, 5)
    assert_u_j_e_d_address(manager, 7, -1, 4, 7, 6)
    assert_u_j_e_d_address(manager, 8, -1, 5, 8, 7)
    assert_u_j_e_d_address(manager, 9, 6, 6, -1, 8)
    assert_u_j_e_d_address(manager, 10, -1, 7, -1, -1)
    assert_u_j_e_d_address(manager, 11, 7, 8, 9, 9)
    assert_u_j_e_d_address(manager, 12, 8, 9, -1, 10)
    assert_u_j_e_d_address(manager, 13, 9, 10, 10, 11)
    assert_u_j_e_d_address(manager, 14, -1, 11, 11, -1)
    assert_u_j_e_d_address(manager, 15, 10, 12, 12, -1)
    assert_u_j_e_d_address(manager, 16, 11, 13, 13, 12)
예제 #5
0
def add_u_d_constraint(manager: ConstraintManager, usa_address: int,
                       demo_address: int):
    constraint = Constraint()
    constraint.romA = RomVariant.USA
    constraint.addressA = usa_address
    constraint.romB = RomVariant.DEMO
    constraint.addressB = demo_address
    manager.add_constraint(constraint)
예제 #6
0
def add_e_d_constraint(manager: ConstraintManager, eu_address: int,
                       demo_address: int):
    constraint = Constraint()
    constraint.romA = RomVariant.EU
    constraint.addressA = eu_address
    constraint.romB = RomVariant.DEMO
    constraint.addressB = demo_address
    manager.add_constraint(constraint)
예제 #7
0
def add_u_e_constraint(manager: ConstraintManager, usa_address: int,
                       eu_address: int):
    constraint = Constraint()
    constraint.romA = RomVariant.USA
    constraint.addressA = usa_address
    constraint.romB = RomVariant.EU
    constraint.addressB = eu_address
    manager.add_constraint(constraint)
예제 #8
0
def add_u_j_constraint(manager: ConstraintManager, usa_address: int,
                       jp_address: int):
    constraint = Constraint()
    constraint.romA = RomVariant.USA
    constraint.addressA = usa_address
    constraint.romB = RomVariant.JP
    constraint.addressB = jp_address
    manager.add_constraint(constraint)
예제 #9
0
def add_j_e_constraint(manager: ConstraintManager, jp_address: int,
                       eu_address: int):
    constraint = Constraint()
    constraint.romA = RomVariant.JP
    constraint.addressA = jp_address
    constraint.romB = RomVariant.EU
    constraint.addressB = eu_address
    manager.add_constraint(constraint)
예제 #10
0
def add_j_d_constraint(manager: ConstraintManager, jp_address: int,
                       demo_address: int):
    constraint = Constraint()
    constraint.romA = RomVariant.JP
    constraint.addressA = jp_address
    constraint.romB = RomVariant.DEMO
    constraint.addressB = demo_address
    manager.add_constraint(constraint)
예제 #11
0
 def _read_constraints(self) -> List[Constraint]:
     constraints = []
     try:
         with open(get_file_in_database('constraints.csv'), 'r') as file:
             reader = DictReader(file)
             for row in reader:
                 constraints.append(
                     Constraint(RomVariant(row['romA']),
                                int(row['addressA'], 16),
                                RomVariant(row['romB']),
                                int(row['addressB'],
                                    16), row['certainty'], row['author'],
                                row['note'], row['enabled'] == 'True'))
     except OSError:
         # file cannot be read, just supply no constraints
         pass
     return constraints
예제 #12
0
    def mark_only_in_one(self, controller: HexViewerController, virtual_address: int, length: int) -> None:

        rom_variant = controller.rom_variant

        # TODO show dialog for inputs
        certainty = 1
        author = settings.get_username()
        note = 'Only in ' + rom_variant
        enabled = True

        # Get the end of the section only in this variant + 1
        local_address = self.constraint_manager.to_local(
            rom_variant, virtual_address + length)

        new_constraints = []
        for variant in self.linked_variants:
            if variant != rom_variant:
                # Link it to the start of the selection in all other variants
                la = self.constraint_manager.to_local(variant, virtual_address)
                constraint = Constraint(
                    rom_variant, local_address, variant, la, certainty, author, note, enabled)
                new_constraints.append(constraint)

        # Check whether the new constraint is invalid
        constraint_manager = ConstraintManager({RomVariant.USA, RomVariant.DEMO, RomVariant.EU, RomVariant.JP, RomVariant.DEMO_JP, RomVariant.CUSTOM, RomVariant.CUSTOM_EU, RomVariant.CUSTOM_JP, RomVariant.CUSTOM_DEMO_USA, RomVariant.CUSTOM_DEMO_JP})
        constraint_manager.add_all_constraints(
            get_constraint_database().get_constraints())
        try:
            constraint_manager.add_all_constraints(new_constraints)
        except InvalidConstraintError as e:
            raise e

        constraint_database = get_constraint_database()
        constraint_database.add_constraints(new_constraints)

        print(f'mark only in one {rom_variant} {virtual_address} {length}')
예제 #13
0
def test_longer_constraint():
    # v   E   J
    # 0   0   0
    # 1   x   1
    # ... ... ...
    # 100 1---100
    # 101 2   101
    manager = ConstraintManager({RomVariant.EU, RomVariant.JP})
    constraint = Constraint()
    constraint.romA = RomVariant.JP
    constraint.addressA = 100
    constraint.romB = RomVariant.EU
    constraint.addressB = 1
    manager.add_constraint(constraint)
    manager.rebuild_relations()
    assert_same_address(manager, RomVariant.EU, 0)
    assert_same_address(manager, RomVariant.JP, 0)
    assert_same_address(manager, RomVariant.JP, 100)
    assert_same_address(manager, RomVariant.JP, 5000)
    assert -1 == manager.to_local(RomVariant.EU, 1)
    assert_differing_address(manager, RomVariant.EU, 1, 100)
    assert_differing_address(manager, RomVariant.EU, 100, 199)
예제 #14
0
    def add_pointers_and_constraints(self, pointer: Pointer) -> bool:
        """
        Add a pointer that is the same for all variants and the resulting constraints.
        Returns true if the constraint changes the relations between the files.
        """
        # Found

        new_pointers = [pointer]
        new_constraints = []
        virtual_address = self.constraint_manager.to_virtual(
            pointer.rom_variant, pointer.address)

        for variant in self.linked_variants:
            if variant != pointer.rom_variant:
                address = self.constraint_manager.to_local(
                    variant, virtual_address)
                points_to = get_rom(variant).get_pointer(address)
                # Add a corresponding pointer for this variant
                new_pointers.append(Pointer(
                    variant, address, points_to, pointer.certainty, pointer.author, pointer.note))

                # Add a constraint for the places that these two pointers are pointing to, as the pointers should be the same
                # TODO check that it's actually a pointer into rom

                note = f'Pointer at {pointer.rom_variant} {hex(pointer.address)}'
                if pointer.note.strip() != '':
                    note += '\n' + pointer.note

                # TODO test that adding the added constraints are not invalid
                # TODO It might be that a constraint that is added with the new_constraints invalidates some other newly added
                # constraint which then would need to be enabled. Need to test for all new_constraints whether they are actually still valid after adding them to the constraint manager?
                enabled = self.constraint_manager.to_virtual(
                    pointer.rom_variant, pointer.points_to-ROM_OFFSET) != self.constraint_manager.to_virtual(variant, points_to-ROM_OFFSET)
                print(f'Add constraint {enabled}')
                new_constraints.append(Constraint(pointer.rom_variant, pointer.points_to-ROM_OFFSET,
                                       variant, points_to-ROM_OFFSET, pointer.certainty, pointer.author, note, enabled))

        # Show dialog if one constraint was new
        one_enabled = False
        for constraint in new_constraints:
            if constraint.enabled:
                one_enabled = True
                break

        if one_enabled:
            # TODO we cannot be sure yet that the one enabled constraint does not interfere with the disabled constraint,
            # so just enable all constraints again (and disable them later via the constraint cleaner plugin)
            for constraint in new_constraints:
                constraint.enabled = True

            # Check whether the new constraint is invalid
            constraint_manager = ConstraintManager({RomVariant.USA, RomVariant.DEMO, RomVariant.EU, RomVariant.JP, RomVariant.DEMO_JP, RomVariant.CUSTOM, RomVariant.CUSTOM_EU, RomVariant.CUSTOM_JP, RomVariant.CUSTOM_DEMO_USA, RomVariant.CUSTOM_DEMO_JP})
            constraint_manager.add_all_constraints(
                get_constraint_database().get_constraints())
            try:
                constraint_manager.add_all_constraints(new_constraints)
            except InvalidConstraintError as e:
                raise e



        print('Adding to database')
        pointer_database = get_pointer_database()
        pointer_database.add_pointers(new_pointers)
        constraint_database = get_constraint_database()
        constraint_database.add_constraints(new_constraints)

        return one_enabled