def load(self): self.map = {} with self.game.open('arm9.dec.bin') as handle: reader = BinaryIO.reader(handle) reader.seek(self.game.type_icon_table[1]) Editable.load(self, BinaryIO.reader(reader)) return self
def load(self): self.map = {} with self.game.open( 'overlays_dez', 'overlay_{0:04}.bin'.format( self.game.overworld_sprite_table[0])) as handle: reader = BinaryIO.reader(handle) reader.seek(self.game.overworld_sprite_table[1]) Editable.load(self, BinaryIO.reader(reader)) for sprite in self.table: self.map[sprite.sprite_id] = sprite return self
def save_entries(entries, base_offset, prefix): entry_names = [] offsets = [] text_writer = BinaryIO() for entry in entries: if entry[:-1] == prefix: entry_names.append(entry[-1]) for i in range(len(entry_names)): text_writer.writeUInt32(0) for entry in entry_names: offsets.append(text_writer.tell() + base_offset) text_writer.writeString(entry) with text_writer.seek(0): text_writer.write(array.array('I', offsets).tostring()) return len(entry_names), text_writer
def load(self, reader): reader = BinaryIO.reader(reader) start = reader.tell() Editable.load(self, reader) self.records = {} for record_ofs, record_name in zip(self.record_offsets, self.record_names): if not record_ofs: continue reader.seek(start + record_ofs) num = reader.readUInt32() if record_name == 'SEQARC': offsets = [] for i in range(num): offsets.append((reader.readUInt32(), reader.readUInt32())) entries = [] for i, (offset, sub_offset) in enumerate(offsets): reader.seek(start + offset) name = reader.readString() reader.seek(start + sub_offset) prefix = (record_name, name) entries += self.load_entries(reader, start, prefix, num) else: entries = self.load_entries(reader, start, (record_name, ), num) self.records[record_name] = entries
def load(self, reader): reader = BinaryIO.reader(reader) Editable.load(self, reader) self.name = reader.read(self.namelen) """land_data_block = Editable() land_data_block.array('entries', land_data_block.uint16, length=self.width*self.height) land_data_block.freeze() self.land_data_maps = land_data_block.load(reader) print(len(reader.read()))""" with self.simulate(): if self.has_map_definition_ids: self.map_definitions = Collection2d(self.uint16, self.width, self.height) self.map_definitions.load(reader) else: self.map_definitions = None if self.has_mystery_zone: self.mystery_details = Collection2d(self.uint8, self.width, self.height) self.mystery_details.load(reader) else: self.mystery_details = None self.land_data_maps = Collection2d(self.uint16, self.width, self.height) self.land_data_maps.load(reader)
def load(self, reader): reader = BinaryIO.reader(reader) Editable.load(self, reader) if self.game.is_hgss(): self.block1 = reader.read(self.ublock1_size) """entry_size = Permission(self.game).get_size() # self.permissions = [Permission(self.game, reader=reader) # for i in range(self.permission_size/entry_size)] self.permissions = Editable() self.permissions.array('entries', Permission(self.game).base_struct, length=self.permission_size/entry_size) self.permissions.freeze() self.permissions.load(reader) entry_size = MapObject(self.game).get_size() self.objects = [MapObject(self.game, reader=reader) for i in range(self.objects_size/entry_size)]""" entry = Permission(self.game) # TODO: non-fixed w/h self.permissions = Collection2d(entry.base_struct, 0x20, 0x20) self.permissions.load(reader) entry = MapObject(self.game) self.objects = SizedCollection( entry.base_struct, self.objects_size/entry.get_size()) self.objects.load(reader) self.bmd = reader.read(self.bmd_size) # TODO later self.bdhc = reader.read(self.bdhc_size)
def save(self): with self.game.open('overlays_dez', 'overlay_{0:04}.bin'.format( self.game.overworld_sprite_table[0]), mode='r+') as handle: writer = BinaryIO.writer(handle) writer.seek(self.game.overworld_sprite_table[1]) Editable.save(self, writer)
def save(self, writer=None): writer = BinaryIO.writer(writer) start = writer.tell() writer = Editable.save(self, writer) writer = self.scrn.save(writer) size = writer.tell() - start with writer.seek(start + self.get_offset('size_')): writer.writeUInt32(size) return writer
def load(self, reader): reader = BinaryIO.reader(reader) start = reader.tell() self.name = reader.read(12).rstrip('\x00') self.code = reader.read(4) with reader.seek(start + 0xA0): self.base_code = reader.read(4).rstrip('\x00') if not self.base_code: self.base_code = self.code
def load(self, reader): reader = BinaryIO.reader(reader) self.moves = [] while True: lvlmove = LevelMove(self.game, reader=reader) if lvlmove.is_end(): break else: self.moves.append(lvlmove)
def load(self): self.filenames = [] with self.game.open('arm9.dec.bin') as arm9: reader = BinaryIO.reader(arm9) reader.seek(self.game.file_system_table[1]) while True: offset = reader.readUInt32() if not offset: break with reader.seek(offset - 0x02000000): # TODO: BW ram ofs self.filenames.append(reader.readString())
def save(self, writer=None): writer = BinaryIO.writer(writer) start = writer.tell() self.mdldict.num = len(self.models) writer = Editable.save(self, writer) writer = self.mdldict.save(writer) for i in range(self.mdldict.num): writer = self.models[i].save(writer) size = writer.tell() - start with writer.seek(start + self.get_offset('size_')): writer.writeUInt32(size) return writer
def load(self): with self.game.open('overlays_dez', 'overlay_{0:04}.bin'.format( self.game.type_effectiveness_table[0])) as handle: reader = BinaryIO.reader(handle) reader.seek(self.game.type_effectiveness_table[1]) while True: effect = TypeEffectiveness(self.game) effect.load(reader=reader) if effect.source_type == 0xFE and effect.target_type == 0xFE: break self.effectives.append(effect) self.length = len(self.effectives)
def overlay_table(self): with self.open('header.bin') as header: reader = BinaryIO.adapter(header) reader.seek(0x24) entry = reader.readUInt32() ram_offset = reader.readUInt32() size = reader.readUInt32() reader.seek(0x54) overlay_count = reader.readUInt32() >> 5 # Size/sizeof(entry) with self.open('overarm9.dec.bin') as overarm: ovt = OverlayTable(overlay_count, reader=overarm) return ovt
def load(self, reader): reader = BinaryIO.reader(reader) start = reader.tell() Editable.load(self, reader) self.glyphs = [] # TODO: glyph reading self.glyphs = SizedCollection(Glyph().base_struct, length=self.num) self.glyphs.load(reader) self.widths = [] reader.seek(start + self.footer_offset) for i in range(self.num): self.widths.append(reader.readUInt8())
def load(self, reader): """Loads a reader into this model Parameters ---------- reader : BinaryIO, string, file, other readable """ reader = BinaryIO.reader(reader) amount = ctypes.sizeof(self._data) data = reader.read(amount) self._data = self._type.from_buffer_copy(data) return self
def save(self, writer=None): writer = BinaryIO.writer(writer) start = writer.tell() self.num = len(self.glyphs) base_glyph = Glyph() self.footer_offset = base_glyph.get_size() * self.num + self.headersize writer = Editable.save(self, writer) writer = self.glyphs.save(writer) self.widths = [0] * self.num for i, glyph in enumerate(self.glyphs): self.widths[i] = width = glyph.get_bbox()[0] writer.writeUInt8(width) return writer
def load(self, reader): reader = BinaryIO.reader(reader) self.num_furniture = reader.readUInt32() self.furniture = [Furniture(reader=reader) for i in range(self.num_furniture)] self.num_overworlds = reader.readUInt32() self.overworlds = [Overworld(reader=reader) for i in range(self.num_overworlds)] self.num_warps = reader.readUInt32() self.warps = [Warp(reader=reader) for i in range(self.num_warps)] self.num_triggers = reader.readUInt32() self.triggers = [Trigger(reader=reader) for i in range(self.num_triggers)]
def load(self, reader): reader = BinaryIO.reader(reader) start = reader.tell() Editable.load(self, reader) assert self.magic == 'BMD0', 'Expected BMD0 got '.format(self.magic) block_offsets = [] for i in range(self.numblocks): block_offsets.append(reader.readUInt32()) reader.seek(start + block_offsets[0]) self.mdl.load(reader) if self.numblocks > 1: reader.seek(start + block_offsets[1]) self.tex.load(reader) self.tex.loaded = True else: self.tex.loaded = False
def load(self, reader): reader = BinaryIO.reader(reader) start = reader.tell() Editable.load(self, reader) assert self.magic == 'SDAT' for block_ofs, block in zip( self.block_offsets, [self.symb, self.info, self.fat, self.file]): if not block_ofs.block_offset: continue reader.seek(start + block_ofs.block_offset) block.load(reader) self.file.files = [] for entry in self.fat.entries: reader.seek(start + entry.start) self.file.files.append(reader.read(entry.stop - entry.start))
def save(self, writer=None): writer = BinaryIO.writer(writer) start = writer.tell() writer = Editable.save(self, writer) if self.game.is_hgss(): writer.write(self.block1) self.ublock1_size = len(self.block1) writer = self.permissions.save(writer) self.permission_size = self.permissions.get_size() writer = self.objects.save(writer) self.objects_size = self.objects.get_size() writer.write(self.bmd) self.bmd_size = len(self.bmd) writer.write(self.bdhc) self.bdhc_size = len(self.bdhc) with writer.seek(start): Editable.save(self, writer) return writer
def save(self, writer=None): """Creates a writer for this model Parameters ---------- writer : BinaryIO, optional Destination to write into. If not specified, a new IO will be created. Returns ------- writer : BinaryIO A new or modified writer that has this data in it """ writer = writer if writer is not None else BinaryIO() amount = self.get_size() writer.write( ctypes.string_at(ctypes.addressof(self._data), size=amount)) return writer
def save(self, writer=None): writer = BinaryIO.writer(writer) self.num_furniture = len(self.furniture) self.num_overworlds = len(self.overworlds) self.num_warps = len(self.warps) self.num_triggers = len(self.triggers) writer.writeUInt32(self.num_furniture) for furniture in self.furniture: writer = furniture.save(writer) writer.writeUInt32(self.num_overworlds) for overworld in self.overworlds: writer = overworld.save(writer) writer.writeUInt32(self.num_warps) for warp in self.warps: writer = warp.save(writer) writer.writeUInt32(self.num_triggers) for trigger in self.triggers: writer = trigger.save(writer) return writer
def load(self, reader): reader = BinaryIO.reader(reader) start = reader.tell() Editable.load(self, reader) self.records = {} for i, record_ofs in enumerate(self.record_offsets): if not record_ofs: continue reader.seek(start + record_ofs) num = reader.readUInt32() offsets = SizedCollection(self.uint32, length=num) offsets.load(reader=reader) first_entry = expected = reader.tell() - start template_entry = self.record_classes[i]() entry_size = template_entry.get_size() for offset in offsets.entries: if offset != expected: break else: entries = SizedCollection(template_entry.base_struct, length=num) entries.load(reader=reader) self.records[SYMB.record_names[i]] = entries continue adjusted_num = (max(offsets.entries[:] + [first_entry]) - first_entry) / entry_size + 1 entries = SizedCollection(template_entry.base_struct, length=adjusted_num) entries.load(reader=reader) new_entries = SizedCollection(self.record_classes[i]().base_struct, length=num) for idx, offset in enumerate(offsets.entries): if not offset: # what are these entries even? new_entries[idx].file_id = 0 continue target = (offset - first_entry) / entry_size new_entries[idx] = entries.entries[target] self.records[SYMB.record_names[i]] = new_entries
def save(self, writer=None): for name, data in self.files.iteritems(): name = os.path.splitext(name)[0] name_parts = name.split('/') record_name = name_parts.pop(0) if name_parts not in self.symb.records[record_name]: self.symb.records[record_name].append(name_parts) # TODO: handle new info entries?! writer = BinaryIO.writer(writer) start = writer.tell() writer = Editable.save(self, writer) for block_ofs, block in zip( self.block_offsets, [self.symb, self.fat, self.info, self.file]): block_ofs.block_offset = writer.tell() - start writer = block.save(writer) writer.writeAlign(4) block_ofs.block_size = writer.tell( ) - start - block_ofs.block_offset with writer.seek(start): writer = Editable.save(self, writer) return writer
def save(self, writer=None): writer = BinaryIO.writer(writer) start = writer.tell() writer = Editable.save(self, writer) for record_idx, record_name in enumerate(self.record_names): self.record_offsets[record_idx] = writer.tell() - start if record_name == 'SEQARC': prefixes = set() offsets = [] for entry in self.records[record_name]: if entry[0] == record_name: prefixes.add(entry[1]) writer.writeUInt32(len(prefixes)) ofs_ofs = writer.tell() for i in range(len(prefixes) * 2): writer.writeUInt32(0) for name in prefixes: offsets.append(writer.tell() - start) writer.writeString(name) writer.writeAlign(8) offsets.append(writer.tell() - start) num, text_writer = self.save_entries( self.records[record_name], writer.tell() - start + 4, (record_name, name)) writer.writeUInt32(num) writer.write(text_writer.getvalue()) with writer.seek(ofs_ofs): writer.write(array.array('I', offsets).tostring()) else: num, text_writer = self.save_entries(self.records[record_name], writer.tell() - start + 4, (record_name, )) writer.writeUInt32(num) writer.write(text_writer.getvalue()) writer.writeAlign(8) self.size = writer.tell() - start with writer.seek(start): writer = Editable.save(self, writer) return writer
def save(self, writer): writer = BinaryIO.writer(writer) flag = self.flag writer.writeUInt16(flag) writer.writeInt16(self.rot_00_fx16) if not (self.flag & self.FLAG_NO_TRANSLATE): writer.writeInt32(self.trans_x_fx32) writer.writeInt32(self.trans_y_fx32) writer.writeInt32(self.trans_z_fx32) if not (self.flag & self.FLAG_NO_ROTATE): writer.writeInt16(self.rot_01_fx16) writer.writeInt16(self.rot_02_fx16) writer.writeInt16(self.rot_10_fx16) writer.writeInt16(self.rot_11_fx16) writer.writeInt16(self.rot_20_fx16) writer.writeInt16(self.rot_21_fx16) writer.writeInt16(self.rot_22_fx16) if not (self.flag & self.FLAG_NO_SCALE): try: self.inv_scale_x = 1 / self.scale_x except ZeroDivisionError: self.inv_scale_x = 0.0 try: self.inv_scale_y = 1 / self.scale_y except ZeroDivisionError: self.inv_scale_y = 0.0 try: self.inv_scale_z = 1 / self.scale_z except ZeroDivisionError: self.inv_scale_z = 0.0 writer.writeInt32(self.scale_x_fx32) writer.writeInt32(self.scale_y_fx32) writer.writeInt32(self.scale_z_fx32) writer.writeInt32(self.inv_scale_x_fx32) writer.writeInt32(self.inv_scale_y_fx32) writer.writeInt32(self.inv_scale_z_fx32) return writer
def save(self, writer=None): if self.tex.loaded: self.numblocks = 2 else: self.numblocks = 1 writer = BinaryIO.writer(writer) start = writer.tell() writer = Editable.save(self, writer) offset_offset = writer.tell() for i in range(self.numblocks): writer.writeUInt32(0) block_ofs = writer.tell() - start with writer.seek(offset_offset): writer.writeUInt32(block_ofs) writer = self.mdl.save(writer) if self.tex.loaded: block_ofs = writer.tell() - start with writer.seek(offset_offset + 4): writer.writeUInt32(block_ofs) writer = self.tex.save(writer) size = writer.tell() - start with writer.seek(start + self.get_offset('size_')): writer.writeUInt32(size) return writer
def from_bdf(self, handle): """Loads a BDF font file""" try: reader = BinaryIO.reader(handle) assert reader.readline().split(' ')[0] == 'STARTFONT' except: raise ValueError('Expected BDF handle to be loaded') table, rtable = load_table() startchar_re = re.compile('^STARTCHAR U?\+?([0-9A-F]+)') bbox_re = re.compile('^BBX ([0-9]+) ([0-9]+) (-?[0-9]+) (-?[0-9]+)') encoding_re = re.compile('^ENCODING (?:-1 )?([0-9]+)') bits_re = re.compile('^BITS_?PER_?PIXEL_? (1|2|4|8|16|32)') size_re = re.compile('^SIZE [0-9]+ [0-9]+ [0-9]+ ([0-9]+)') bpp = 1 while True: line = reader.readline() if line.startswith('CHARS'): num = int(line.strip('\n').split(' ')[1]) break match = size_re.match(line) if match: bpp = int(match.group(1)) continue entries = {} while num > 0: while True: line = reader.readline() match = startchar_re.match(line) if not match: continue ucode = int(match.group(1), 16) break entries[ucode] = entry = Glyph() ecode = None width = height = None x_ofs = 0 y_ofs = 0 while True: line = reader.readline() if line.startswith('ENDCHAR'): break if line.startswith('STARTCHAR'): # WARNING: Overflowed break match = encoding_re.match(line) if match: ecode = int(match.group(1)) continue match = bits_re.match(line) if match: bpp = int(match.group(1)) continue match = bbox_re.match(line) if match: width = int(match.group(1)) x_ofs = int(match.group(3)) height = int(match.group(2)) y_ofs = int(match.group(4)) if line.startswith('BITMAP'): if width is None: # WARNING: BBX not set continue if bpp != 2: # WARNING: not 2bpp continue if x_ofs != 0: # ??? pass for y in range(16 - height - y_ofs, 16): line = reader.readline() if line.startswith('ENDCHAR'): break entry.set_line(y, width, int(line, 16)) else: continue break num -= 1 num = len(entries) for ucode in entries: if ucode & 0xF000 == 0x8000: num = max(ucode - 0x7FFF, num) self.num = num self.glyphs = SizedCollection(Glyph().base_struct, length=num) for ucode in entries: if ucode & 0xF000 == 0x8000: glyph_id = ucode - 0x8000 else: glyph_id = rtable[unichr(ucode).encode('unicode-escape')] - 1 self.glyphs[glyph_id] = entries[ucode]._data
def save(self): """Save existing blob""" return BinaryIO(self.data)