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()
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())
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)
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)
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)
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)
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)
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)
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)
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)
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
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}')
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)
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