Beispiel #1
0
    def write_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryWriter):
            wtr = stream
        else:
            wtr = BinaryWriter(stream)

        wtr.write_uint32(256)
        for color_i in range(256):
            self.palette[color_i]: np.ndarray
            wtr.write_uint16(ndspy.color.pack255(*self.palette[color_i]))

        img_h, img_w = self.image.shape
        map_h, map_w = img_h // 8, img_w // 8

        tiles = np.asarray([
            self.image[y * 8:y * 8 + 8, x * 8:x * 8 + 8] for x in range(map_w)
            for y in range(map_h)
        ])
        tiles: np.ndarray = np.unique(tiles, axis=0)
        wtr.write_uint32(len(tiles))
        wtr.write(tiles.tobytes())

        wtr.write_uint16(map_w)
        wtr.write_uint16(map_h)

        for y in range(map_h):
            for x in range(map_w):
                tile = self.image[y * 8:y * 8 + 8, x * 8:x * 8 + 8]

                tile_id = np.where(
                    np.all(tile.reshape((
                        64, )) == tiles.reshape(tiles.shape[0], 64),
                           axis=1) == True)
                wtr.write_uint16(tile_id[0][0])
Beispiel #2
0
def decompress(data: bytes):
    rdr = BinaryReader(data)
    wtr = BinaryWriter()
    type = rdr.read_uint8()
    if type != 0x30:
        raise Exception("Tried to decompress commands that isn't RLE")
    ds = rdr.read_uint24()
    if ds == 0:
        rdr.read_uint32()

    while True:
        flag = rdr.read_uint8()
        if flag is None:
            break  # we've hit the end
        compressed = (flag & 0x80) > 0
        lenght = flag & 0x7f
        lenght += 3 if compressed else 1
        if compressed:
            next = rdr.read_uint8()
            for i in range(lenght):
                wtr.write_uint8(next)
        else:
            wtr.write(rdr.read(lenght))

    return wtr.data
Beispiel #3
0
 def write(self, wtr: BinaryWriter):
     wtr.write(b"fmt\x20")
     wtr.write_uint32(0x10)
     wtr.write_uint16(WaveFormat.WAVE_FORMAT_PCM)
     wtr.write_uint16(self.num_channels)
     wtr.write_uint32(self.sample_rate)
     self.byte_rate = self.sample_rate * self.bits_per_sample * self.num_channels // 8
     wtr.write_uint32(self.byte_rate)
     self.block_align = self.num_channels * self.bits_per_sample // 8
     wtr.write_uint16(self.block_align)
     wtr.write_uint16(self.bits_per_sample)
Beispiel #4
0
    def write_stream(self, stream):
        if not isinstance(stream, BinaryWriter):
            wtr = BinaryWriter(stream)
        else:
            wtr = stream
        wtr.write(b"RIFF")
        self.chunk_size = 0x28 + self.data.get_sample_bytes(self.fmt)
        wtr.write_uint32(self.chunk_size)

        wtr.write(b"WAVE")
        self.fmt.write(wtr)
        self.data.write(wtr, self.fmt)
Beispiel #5
0
    def write_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryWriter):
            wtr = stream
        else:
            wtr = BinaryWriter(stream)

        wtr.write_uint16(len(self._entries))
        wtr.write_uint16(8)
        wtr.write_uint16(len(self._entries[0]))
        wtr.write_uint16(0)

        for entry in self._entries:
            wtr.write(entry)
Beispiel #6
0
 def write(self, bw: BinaryWriter):
     bw.seek(0x40, io.SEEK_SET)
     bw.write(self.label)
     bw.write_uint32(self.unk1)
     bw.write_uint32(0xFF10)
     bw.write_uint32(0xFFFFFFB0)
     bw.write_uint16(0x1)
     bw.write_uint16(self.tpqn)
     bw.write_uint16(0xFF01)
     bw.write_uint8(self.num_tracks)
     bw.write_uint8(self.num_channels)
     bw.write_uint32(0x0F000000)
     bw.write_uint32(0xFFFFFFFF)
     bw.write_uint32(0x40000000)
     bw.write_uint32(0x00404000)
     bw.write_uint16(0x0200)
     bw.write_uint16(0x0800)
     bw.write_uint32(0xFFFFFF00)
     bw.write(b"\xFF" * 16)
Beispiel #7
0
    def write_stream(self, stream):
        if not isinstance(stream, BinaryWriter):
            wtr = BinaryWriter(stream)
        else:
            wtr = stream

        wtr.write(self.original_header)
        wtr.seek(0)
        wtr.write(self.chunk_id)
        wtr.seek(0x31)
        wtr.write_uint8(self.loop_flag)
        wtr.write_uint8(self.channels)

        coding = self.coding
        if self.sample_rate == 32728:
            coding |= 4
        elif self.sample_rate == 16364:
            coding |= 2
        else:
            raise NotImplementedError()

        wtr.seek(0x100)
        buffer = self.buffer.copy()
        buffer = buffer.reshape((buffer.shape[0], buffer.shape[1] // 0x10, 0x10))
        buffer = buffer.swapaxes(0, 1)
        wtr.write(buffer.tobytes())

        size = wtr.tell()
        wtr.seek(0x40)
        wtr.write_uint32(size)
Beispiel #8
0
    def write_stream(self, stream: BinaryIO):
        # TODO: Fix image writing
        if isinstance(stream, BinaryWriter):
            wtr = stream
        else:
            wtr = BinaryWriter(stream)

        wtr.write_uint32(256)
        for color_i in range(256):
            self.palette[color_i]: np.ndarray
            wtr.write_uint16(ndspy.color.pack255(*self.palette[color_i]))

        img_h, img_w = self.image.shape
        map_h, map_w = img_h // 8, img_w // 8

        tiles: np.ndarray = np.unique(self.image.reshape((map_h * map_w, 8, 8)))
        wtr.write_uint32(len(tiles))
        wtr.write(tiles.tobytes())

        wtr.write_uint16(map_w)
        wtr.write_uint16(map_h)
        for tile in self.image.reshape((map_h * map_w, 8, 8)):
            wtr.write_uint16(np.where(tiles[tiles == tile])[0][0])
Beispiel #9
0
 def write(self, bw: BinaryWriter):
     bw.seek(0, io.SEEK_SET)
     bw.write(self.magic)
     bw.write_uint32(0)
     bw.write_uint32(self.file_length)
     bw.write_uint16(self.version)
     bw.write_uint8(self.unk1)
     bw.write_uint8(self.unk2)
     bw.write_uint32(0)
     bw.write_uint32(0)
     bw.write_uint16(self.year)
     bw.write_uint8(self.month)
     bw.write_uint8(self.day)
     bw.write_uint8(self.hour)
     bw.write_uint8(self.minute)
     bw.write_uint8(self.second)
     bw.write_uint8(self.centisecond)
     if self.file_name[-1] != 0:
         self.file_name += b"\0"
     bw.write_string(self.file_name, size=16, encoding=None, pad=b"\xFF")
     bw.write_uint32(0x1)
     bw.write_uint32(0x1)
     bw.write_uint32(0xFFFFFFFF)
     bw.write_uint32(0xFFFFFFFF)
Beispiel #10
0
    def export_data(self, wtr):
        if not isinstance(wtr, BinaryWriter):
            wtr = BinaryWriter(wtr)
        wtr: BinaryWriter

        puzzle_text_section = BinaryWriter()
        puzzle_text_section.write_string(self.text, encoding=self.encoding)
        puzzle_correct_offset = puzzle_text_section.tell()
        puzzle_text_section.write_string(self.correct_answer,
                                         encoding=self.encoding)
        puzzle_incorrect_offset = puzzle_text_section.tell()
        puzzle_text_section.write_string(self.incorrect_answer,
                                         encoding=self.encoding)
        puzzle_hint1_offset = puzzle_text_section.tell()
        puzzle_text_section.write_string(self.hint1, encoding=self.encoding)
        puzzle_hint2_offset = puzzle_text_section.tell()
        puzzle_text_section.write_string(self.hint2, encoding=self.encoding)
        puzzle_hint3_offset = puzzle_text_section.tell()
        puzzle_text_section.write_string(self.hint3, encoding=self.encoding)

        wtr.write_uint16(self.number)
        wtr.write_uint16(112)
        wtr.write_string(self.title, encoding=self.encoding, size=0x30)
        wtr.write_uint8(self.tutorial_id)
        for picarat in self.picarat_decay:
            wtr.write_uint8(picarat)
        wtr.write_uint8(self._flags)
        wtr.write_uint8(self.location_id)
        wtr.write_uint8(self.type)
        wtr.write_uint8(self.bg_btm_id)
        wtr.write(self.original[0x3c:0x3e])  # UnkSoundId
        wtr.write_uint8(self.bg_top_id)
        wtr.write_uint8(self.reward_id)

        wtr.write_uint32(0)
        wtr.write_uint32(puzzle_correct_offset)
        wtr.write_uint32(puzzle_incorrect_offset)
        wtr.write_uint32(puzzle_hint1_offset)
        wtr.write_uint32(puzzle_hint2_offset)
        wtr.write_uint32(puzzle_hint3_offset)
        wtr.write(b"\x00" * 4 * 6)
        wtr.write(puzzle_text_section.data)

        return wtr
Beispiel #11
0
 def write(self, wtr: BinaryWriter, fmt_chunk: FmtChunk):
     wtr.write(b"data")
     wtr.write_uint32(self.get_sample_bytes(fmt_chunk))
     wtr.write(self.data.swapaxes(0, 1).tobytes())
Beispiel #12
0
    def write_stream(self, stream):
        if isinstance(stream, BinaryWriter):
            wtr = stream
        else:
            wtr = BinaryWriter(stream)

        wtr.write_uint16(len(self.images))
        wtr.write_uint16(3 if self.colordepth == 4 else 4)

        for img in self.images:
            img_h, img_w = img.shape
            wtr.write_uint16(img_w)
            wtr.write_uint16(img_h)

            # number of parts
            wtr.write_uint16(
                calculate_power_of_2_steps(img_w) *
                calculate_power_of_2_steps(img_h))
            wtr.write_zeros(2)

            w_left, h_left = img_w, img_h
            part_x, part_y = 0, 0
            while h_left > 0:
                part_h = get_nearest_power_of_2(h_left)
                good_h = part_h
                h_left -= part_h
                w_left = img_w
                part_x = 0
                while w_left > 0:
                    part_w = get_nearest_power_of_2(w_left)
                    w_left -= part_w
                    part_h = good_h

                    wtr.write_uint16(part_x)
                    wtr.write_uint16(part_y)
                    wtr.write_uint16(int(log(part_w, 2)) - 3)
                    wtr.write_uint16(int(log(part_h, 2)) - 3)

                    part = np.zeros((part_h, part_w), np.uint8)

                    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

                    part[:part_h, :part_w] = img[part_y:part_y + part_h,
                                                 part_x:part_x + part_w]

                    if self.colordepth == 8:
                        wtr.write(part.tobytes())
                    else:
                        h, w = part.shape
                        bufpart = part.reshape((w * h))
                        part_4bit = np.zeros((h * w // 2), np.uint8)
                        part_4bit[:] = np.ndarray = bufpart[
                            0::2] & 0xf | bufpart[1::2] << 4
                        wtr.write(part_4bit.tobytes())

                    part_x += part_w
                part_y += part_h

        wtr.write_uint32(256 if self.colordepth == 8 else 16)
        for color_i in range(256 if self.colordepth == 8 else 16):
            self.palette[color_i]: np.ndarray
            wtr.write_uint16(ndspy.color.pack255(*self.palette[color_i]))

        wtr.write_zeros(0x1e)
        wtr.write_uint32(len(self.animations))

        for anim in self.animations:
            wtr.write_string(anim.name, 0x1e)
        for anim in self.animations:
            wtr.write_uint32(len(anim.frames))
            wtr.write_uint32_array([frame.index for frame in anim.frames])
            wtr.write_uint32_array([frame.duration for frame in anim.frames])
            wtr.write_uint32_array(
                [frame.image_index for frame in anim.frames])

        wtr.write_uint16(0x1234)  # magic number probably

        variable_labels = list(self.variables)
        assert len(variable_labels) == 16
        wtr.write_string_array(variable_labels, 16)
        for dat_i in range(8):
            for var_l in variable_labels:
                wtr.write_int16(self.variables[var_l][dat_i])

        for anim in self.animations:
            wtr.write_uint16(anim.child_image_x)
        for anim in self.animations:
            wtr.write_uint16(anim.child_image_y)
        for anim in self.animations:
            wtr.write_uint8(anim.child_image_animation_index)

        wtr.write_string(self.child_image, 128)

        return stream
Beispiel #13
0
 def write(self, bw: BinaryWriter):
     bw.write(self.label)
     bw.write_uint32(self.param1)
     bw.write_uint32(self.param2)
     bw.write_uint32(0)