Пример #1
0
 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
Пример #2
0
 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
Пример #3
0
 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
Пример #4
0
 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
Пример #5
0
    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)
Пример #6
0
 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)
Пример #7
0
 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)
Пример #8
0
 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
Пример #9
0
 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
Пример #10
0
 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)
Пример #11
0
 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())
Пример #12
0
 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
Пример #13
0
 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)
Пример #14
0
 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
Пример #15
0
 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())
Пример #16
0
    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
Пример #17
0
 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
Пример #18
0
 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)]
Пример #19
0
 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
Пример #20
0
 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))
Пример #21
0
 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
Пример #22
0
    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
Пример #23
0
 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
Пример #24
0
    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
Пример #25
0
 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
Пример #26
0
 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
Пример #27
0
 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
Пример #28
0
 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
Пример #29
0
    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
Пример #30
0
 def save(self):
     """Save existing blob"""
     return BinaryIO(self.data)