Exemplo n.º 1
0
 def read(self, br: BinaryReader):
     br.seek(0, io.SEEK_SET)
     self.magic = br.read(4)
     if self.magic != b"smdl":
         raise ValueError("SMDHeader does not start with magic value")
     br.read_uint32()  # 0
     self.file_length = br.read_uint32()
     self.version = br.read_uint16()
     self.unk1 = br.read_uint8()
     self.unk2 = br.read_uint8()
     # 8 bytes of 0
     br.read_uint32()
     br.read_uint32()
     self.year = br.read_uint16()
     self.month = br.read_uint8()
     self.day = br.read_uint8()
     self.hour = br.read_uint8()
     self.minute = br.read_uint8()
     self.second = br.read_uint8()
     self.centisecond = br.read_uint8()
     self.file_name = br.read_string(16, encoding=None, pad=b"\xFF")
     br.read_uint32()  # 0x1
     br.read_uint32()  # 0x1
     br.read_uint32()  # 0xFFFFFFFF
     br.read_uint32()  # 0xFFFFFFFF
Exemplo n.º 2
0
 def read(self, br: BinaryReader):
     br.seek(0)
     self.magic = br.read(4)
     if self.magic != b"swdl":
         raise ValueError("SWDHeader does not start with magic value")
     br.read_uint32()  # 0
     self.file_length = br.read_uint32()
     self.version = br.read_uint16()
     if self.version != 0x415:
         raise ValueError("SMDHeader does not have correct version")
     self.is_sample_bank = br.read_bool()
     self.group = br.read_uint8()
     # 8 bytes of 0
     br.read_uint32()
     br.read_uint32()
     self.year = br.read_uint16()
     self.month = br.read_uint8()
     self.day = br.read_uint8()
     self.hour = br.read_uint8()
     self.minute = br.read_uint8()
     self.second = br.read_uint8()
     self.centisecond = br.read_uint8()
     self.file_name = br.read_string(16, encoding=None, pad=b"\xAA")
     self.unk10 = br.read_uint32()
     # 8 bytes of 0
     br.read_uint32()
     br.read_uint32()
     self.unk13 = br.read_uint32()
     self.pcmdlen = br.read_uint32()
     self.unk14 = br.read_uint32()
     self.wavi_slot_count = br.read_uint16()
     self.prgi_slot_count = br.read_uint16()
     self.unk17 = br.read_uint16()
     self.wavi_len = br.read_uint32()
Exemplo n.º 3
0
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)
        with open("test.bin", "wb+") as f:
            f.write(rdr.read())
        rdr.seek(0)

        palette_lenght = rdr.read_uint32()
        for color_i in range(palette_lenght):
            self.palette[color_i] = ndspy.color.unpack255(rdr.read_uint16())
            if color_i:
                self.palette[color_i, 3] = 255

        n_tiles = rdr.read_uint32()
        tiles = np.frombuffer(rdr.read(n_tiles * 0x40), np.uint8).reshape((n_tiles, 8, 8))

        map_w = rdr.read_uint16()
        map_h = rdr.read_uint16()

        img_w = map_w * 8
        img_h = map_h * 8

        self.image = np.zeros((img_h, img_w), np.uint8)

        for map_y in range(map_h):
            for map_x in range(map_w):
                img_y = map_y * 8
                img_x = map_x * 8

                self.image[img_y:img_y + 8, img_x:img_x + 8] = tiles[rdr.read_uint16()]
Exemplo n.º 4
0
 def read(self, rdr: BinaryReader):
     self.chunk_id = rdr.read(4)
     self.chunk_size = rdr.read_uint32()
     self.audio_format = rdr.read_uint16()
     self.num_channels = rdr.read_uint16()
     self.sample_rate = rdr.read_uint32()
     self.byte_rate = rdr.read_uint32()
     self.block_align = rdr.read_uint16()
     self.bits_per_sample = rdr.read_uint16()
Exemplo n.º 5
0
 def read(self, rdr: BinaryReader):
     self.magic_value = rdr.read(4)[::-1]
     if self.magic_value != b"NFTR":
         raise ValueError("NFTRHeader does not start with magic value")
     self.byte_order = rdr.read_uint16()
     self.version = rdr.read_uint16()
     self.decompressed_resource_size = rdr.read_uint32()
     self.offset_to_fnif = rdr.read_uint16()
     self.following_chunk_count = rdr.read_uint16()
Exemplo n.º 6
0
    def load(self, rdr):
        if not isinstance(rdr, BinaryReader):
            rdr = BinaryReader(rdr)
        rdr: BinaryReader

        self.original = rdr.read()
        rdr.seek(0)

        self.number = rdr.read_uint16()
        rdr.read_uint16()  # 112
        self.title = rdr.read_string(encoding=self.encoding)
        rdr.seek(0x34)
        self.tutorial_id = rdr.read_uint8()
        for i in range(3):
            self.picarat_decay[i] = rdr.read_uint8()
        print(rdr.tell())
        self._flags = rdr.read_uint8()
        self.location_id = rdr.read_uint8()
        self.type = rdr.read_uint8()
        self.bg_btm_id = rdr.read_uint8()
        rdr.read_uint16()
        self.bg_top_id = rdr.read_uint8()
        self.reward_id = rdr.read_uint8()

        print(rdr.tell())
        puzzle_text_offset = 0x70 + rdr.read_uint32()
        puzzle_correct_answer_offset = 0x70 + rdr.read_uint32()
        puzzle_incorrect_answer_offset = 0x70 + rdr.read_uint32()
        puzzle_hint1_offset = 0x70 + rdr.read_uint32()
        puzzle_hint2_offset = 0x70 + rdr.read_uint32()
        puzzle_hint3_offset = 0x70 + rdr.read_uint32()
        rdr.seek(puzzle_text_offset)
        self.text = subs.replace_substitutions(
            rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_correct_answer_offset)
        self.correct_answer = subs.replace_substitutions(
            rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_incorrect_answer_offset)
        self.incorrect_answer = subs.replace_substitutions(
            rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_hint1_offset)
        self.hint1 = subs.replace_substitutions(
            rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_hint2_offset)
        self.hint2 = subs.replace_substitutions(
            rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_hint3_offset)
        self.hint3 = subs.replace_substitutions(
            rdr.read_string(encoding=self.encoding), True)
Exemplo n.º 7
0
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)

        n_entries = rdr.read_uint16()
        header_length = rdr.read_uint16()
        entry_length = rdr.read_uint16()
        rdr.seek(header_length)

        self._entries = []

        for i in range(n_entries):
            self._entries.append(rdr.read(entry_length))
Exemplo n.º 8
0
    def read(self, rdr: BinaryReader):
        self.chunk_id = rdr.read(4)[::-1]
        if self.chunk_id != b"CMAP":
            raise ValueError("CMAPChunk does not start with magic value")
        self.chunk_size = rdr.read_uint32()
        self.first_character = rdr.read_uint16()
        self.last_character = rdr.read_uint16()
        self.map_type = rdr.read_uint32()
        self.offset_to_next_cmap = rdr.read_uint32() - 8

        char_map = {}
        if self.map_type == 0:
            tile_no = rdr.read_uint16()
            i = self.first_character
            while i <= self.last_character:
                char_map[i] = tile_no
                i += 1
                tile_no += 1
        elif self.map_type == 1:
            i = self.first_character
            while i <= self.last_character:
                tile = rdr.read_uint16()
                if tile == 0xFFFF:
                    i += 1
                    continue
                char_map[i] = tile
                i += 1
        elif self.map_type == 2:
            groups = rdr.read_uint16()
            for i in range(groups):
                ch = rdr.read_uint16()
                tile = rdr.read_uint16()
                char_map[ch] = tile
        self.char_map = char_map
Exemplo n.º 9
0
    def read(self, rdr: BinaryReader):
        self.chunk_id = rdr.read(4)[::-1]
        if self.chunk_id != b"CGLP":
            raise ValueError("CGLPChunk does not start with magic value")
        self.chunk_size = rdr.read_uint32()
        self.tile_width = rdr.read_uint8()
        self.tile_height = rdr.read_uint8()
        self.tile_bytes = rdr.read_uint16()
        bitmap_items = self.tile_width * self.tile_height
        self.underline_location = rdr.read_uint8()
        self.max_proportional_width = rdr.read_uint8()
        self.tile_depth = rdr.read_uint8()
        self.tile_rotation = rdr.read_uint8()

        self.tile_bitmaps = []

        tile_bytes = self.tile_bytes
        tile_width = self.tile_width
        tile_height = self.tile_height
        tile_depth = self.tile_depth
        # To avoid byte boundaries efficiently
        # If bit depth is 2, we can read in blocks of 2
        # If bit depth is 1, we can only read in blocks of 1
        bit_steps = get_bit_steps(self.tile_depth)
        bit_mask = ((1 << bit_steps) - 1)

        for _ in range((self.chunk_size - 0x10) // tile_bytes):
            buffer = rdr.read(tile_bytes)
            bitmap = np.zeros(bitmap_items, dtype=np.uint8)

            current_bit = 0
            for i in range(bitmap_items):
                # Get value from bytes to bit depth
                v = 0
                for _ in range(tile_depth // bit_steps):
                    # Shift the value bit steps
                    v <<= bit_steps

                    # Get the bit index and the byte index
                    bit_i = current_bit % 8
                    byte_i = (current_bit - bit_i) // 8

                    # Read <bit steps> bits from byte (bit 7 is the MSB)
                    byte = buffer[byte_i]
                    bit = (byte >> (7 - bit_i)) & bit_mask

                    # Add the value and change the current bit
                    v += bit
                    current_bit += bit_steps

                bitmap[i] = v

            bitmap.shape = tile_height, tile_width
            self.tile_bitmaps.append(bitmap)
Exemplo n.º 10
0
    def read(self, rdr: BinaryReader, tile_count: int):
        self.chunk_id = rdr.read(4)[::-1]
        if self.chunk_id != b"CWDH":
            raise ValueError("CWDHChunk does not start with magic value")
        self.chunk_size = rdr.read_uint32()
        self.first_tile_no = rdr.read_uint16()
        self.last_tile_no = rdr.read_uint16()
        rdr.read(4)

        self.left_spacing = []
        self.width = []
        self.total_width = []
        for i in range(tile_count):
            left_spacing = rdr.read_uint8()
            width = rdr.read_uint8()
            total_width = rdr.read_uint8()

            self.left_spacing.append(left_spacing)
            self.width.append(width)
            self.total_width.append(total_width)
Exemplo n.º 11
0
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)

        self.commands = []
        self.params = []
        file_length = rdr.read_uint32()

        while rdr.c < file_length:
            datatype = rdr.read_uint16()
            if datatype == 0:
                break
            elif datatype == 1:
                self.params.append(rdr.read_uint32())
            elif datatype == 2:
                self.params.append(rdr.read_float())
            elif datatype == 3:
                self.params.append(rdr.read_string(rdr.read_uint16()))
            elif datatype == 0xc:
                return
        while rdr.c < file_length or True:
            self.commands.append(command := GDSCommand(rdr.read_uint16()))
            if command.command == 0xc:
                self.commands = self.commands[:-1]
                return
            while rdr.c < file_length:
                datatype = rdr.read_uint16()
                if datatype == 0:
                    break
                if datatype == 1:
                    command.params.append(rdr.read_uint32())
                elif datatype == 2:
                    command.params.append(rdr.read_float())
                elif datatype == 3:
                    command.params.append(rdr.read_string(rdr.read_uint16()))
                elif datatype == 0xc:
                    return
Exemplo n.º 12
0
 def read(self, br: BinaryReader):
     br.seek(0x40, io.SEEK_SET)
     self.label = br.read(4)
     if self.label != b"song":
         raise ValueError("SongChunk does not start with magic value")
     self.unk1 = br.read_uint32()
     br.read_uint32()  # 0xFF10
     br.read_uint32()  # 0xFFFFFFB0
     br.read_uint16()  # 0x1
     self.tpqn = br.read_uint16()
     br.read_uint16()  # 0xFF10
     self.num_tracks = br.read_uint8()
     self.num_channels = br.read_uint8()
     br.read_uint32()  # 0x0F000000
     br.read_uint32()  # 0xFFFFFFFF
     br.read_uint32()  # 0x40000000
     br.read_uint32()  # 0x00404000
     br.read_uint16()  # 0x0200
     br.read_uint16()  # 0x0800
     br.read_uint32()  # 0xFFFFFF00
     br.read(16)  # 16 0xFF Padding
Exemplo n.º 13
0
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)

        n_images = rdr.read_uint16()
        self.colordepth = 4 if rdr.read_uint16() == 3 else 8

        # import the images
        self.images = []
        for img_i in range(n_images):
            img_w = rdr.read_uint16()
            img_h = rdr.read_uint16()
            n_parts = rdr.read_uint16()

            img = np.zeros((img_h, img_w), np.uint8)

            rdr.seek(2, SEEK_CUR)
            for part_i in range(n_parts):
                part_x = rdr.read_uint16()
                part_y = rdr.read_uint16()
                part_w = 2**(3 + rdr.read_uint16())
                part_h = 2**(3 + rdr.read_uint16())

                part: np.ndarray
                if self.colordepth == 8:
                    part = np.frombuffer(rdr.read(part_h * part_w), np.uint8)
                    part = part.reshape((part_h, part_w))
                else:
                    bufpart = np.frombuffer(rdr.read(part_h * part_w // 2),
                                            np.uint8)
                    part = np.zeros((part_w * part_h), np.uint8)
                    part[0::2] = bufpart & 0xf
                    part[1::2] = bufpart >> 4
                    part = part.reshape((part_h, part_w))

                if (part_x + part_w) > img_w:
                    part_w = img_w - part_x
                if (part_y + part_h) > img_h:
                    part_h = img_h - part_y
                img[part_y:part_y + part_h,
                    part_x:part_x + part_w] = part[:part_h, :part_w]

            self.images.append(img)

        self.palette = np.zeros((256, 4), np.uint8)
        palette_length = rdr.read_uint32()
        for color_i in range(palette_length):
            self.palette[color_i] = ndspy.color.unpack255(rdr.read_uint16())
            if color_i:
                self.palette[color_i, 3] = 255

        rdr.seek(0x1E, SEEK_CUR)
        n_animations = rdr.read_uint32()
        animation_names = rdr.read_string_array(n_animations, 0x1e)
        animation_frame_sets = []
        for i in range(n_animations):
            n_frames = rdr.read_uint32()
            frame_indexes = rdr.read_uint32_array(n_frames)
            frame_durations = rdr.read_uint32_array(n_frames)
            image_indexes = rdr.read_uint32_array(n_frames)
            animation_frame_sets.append([
                AnimationFrame(index=frame_indexes[i],
                               duration=frame_durations[i],
                               image_index=image_indexes[i])
                for i in range(n_frames)
            ])
        self.animations = [
            Animation(name=animation_names[i], frames=animation_frame_sets[i])
            for i in range(n_animations)
        ]

        if rdr.read_uint16() != 0x1234:
            return  # We hit end of stream

        variable_labels = rdr.read_string_array(16, 16)
        variable_data = [[] for _ in range(16)]
        for _ in range(8):
            for var_i in range(16):
                variable_data[var_i].append(rdr.read_int16())

        self.variables = {
            variable_labels[i]: variable_data[i]
            for i in range(16)
        }

        for anim in self.animations:
            anim.child_image_x = rdr.read_uint16()
        for anim in self.animations:
            anim.child_image_y = rdr.read_uint16()
        for anim in self.animations:
            anim.child_image_animation_index = rdr.read_uint8()

        self.child_image = rdr.read_string(128)