def _read_supports_from_table(cls, reader: BinArchiveReader): reader.seek(reader.tell() + 2) # Don't care about the owner here. count = reader.read_u16() supports = [] for _ in range(0, count): support = cls._read_support(reader) supports.append(support) return supports
def read_count(self, archive) -> int: count_address = self.location_strategy.read_base_address(archive) reader = BinArchiveReader(archive, count_address) if self.width == 1: return reader.read_u8() elif self.width == 2: return reader.read_u16() else: return reader.read_u32()
def _add_support_to_table(self, character1, character2, support_type, tag): # Jump to the target support table. master_support_table_address = self._get_master_support_table_address() reader = BinArchiveReader(self.archive, master_support_table_address) target_support_id = character1["Support ID"].value reader.seek(reader.tell() + target_support_id * 4 + 4) reader.seek(reader.read_internal_pointer() + 2) # Skip the owner id. # Update the support count. writer = BinArchiveWriter(self.archive, reader.tell()) old_count = reader.read_u16() writer.write_u16(old_count + 1) # Create the new support. new_support_address = writer.tell() + old_count * 0xC self.archive.allocate(new_support_address, 0xC, False) writer.seek(new_support_address) writer.write_u16(character2["ID"].value) writer.write_u16(old_count) writer.write_u32(support_type) writer.write_u32(tag)
def read(self, archive): reader = BinArchiveReader(archive) self.title = reader.read_shift_jis_string() while reader.tell() < archive.size(): key = reader.read_mapped() value = reader.read_utf16_string() self._messages[key] = value
def _create_support_table(self, character): # First, increment master support table count. master_support_table_address = self._get_master_support_table_address() writer = BinArchiveWriter(self.archive, master_support_table_address) reader = BinArchiveReader(self.archive, master_support_table_address) old_count = reader.read_u32() writer.write_u32(old_count + 1) # Next, create a pointer to the new table. pointer_address = master_support_table_address + old_count * 4 + 4 self.archive.allocate(pointer_address, 4, False) destination = self.archive.size() self.archive.set_internal_pointer(pointer_address, destination) # Generate and assign a support ID for the character support_id = self._find_next_support_id() character["Support ID"].value = support_id # Allocate and format the new table. writer.seek(destination) self.archive.allocate_at_end(4) writer.write_u16(support_id)
def _read_support(reader: BinArchiveReader): characters_module = locator.get_scoped("Driver").modules["Characters"] characters = characters_module.entries character = characters[reader.read_u16()] reader.seek(reader.tell() + 2) # The ID is not needed when editing. raw_type = reader.read_u32() tag = reader.read_bytes(4) return Support(character, raw_type, tag)
def attach_to(self, archive): self.entries.clear() location = self.location_strategy.read_base_address(archive) count = self.count_strategy.read_count(archive) reader = BinArchiveReader(archive) for i in range(0, count): reader.seek(location + i * self.entry_size) base = reader.tell() elem = deepcopy(self.element_template) for (_, prop) in elem.items(): prop.offset = reader.tell() - base prop.read(reader) self.entries.append(elem) self.archive = archive
def _get_master_support_table_address(self): reader = BinArchiveReader(self.archive, 8) reader.seek(reader.read_internal_pointer() + 8) return reader.read_internal_pointer()
def _open_reader_at_table(self, table_number): addr = self._get_master_support_table_address() + table_number * 4 + 4 reader = BinArchiveReader(self.archive, addr) reader.seek(reader.read_internal_pointer()) return reader
def read_base_address(self, archive) -> int: reader = BinArchiveReader(archive) num_fields = reader.read_u32() reader.seek(num_fields * 0x14 + self.offset_to_pointer + 4) return reader.read_internal_pointer() + self.offset_to_pointer
def read_base_address(self, archive) -> int: reader = BinArchiveReader(archive) num_fields = reader.read_u32() return num_fields * 0x14 + self.offset + 4
def read_base_address(self, archive) -> int: reader = BinArchiveReader(archive, self.address) return reader.read_internal_pointer() + self.offset
def attach_to(self, archive): location = self.location_strategy.read_base_address(archive) reader = BinArchiveReader(archive, location) for prop in self.element.values(): prop.read(reader) self.archive = archive