Exemple #1
0
def output_at_dungeon_tiles(fn: str, common_at: CommonAt, pal: Dpla):
    print("Outputting dungeon AT as image.")
    img_bin = common_at.decompress()
    tiles = list(iter_bytes(img_bin, int(8 * 8)))
    # create a dummy tile map containing all the tiles
    tilemap = []
    for i in range(0, len(tiles)):
        tilemap.append(TilemapEntry(i, False, False, 0, True))
    out_img = to_pil(tilemap,
                     tiles, [pal.get_palette_for_frame(0, 0)],
                     8,
                     int(len(tiles) * 8 / 3),
                     4 * 8,
                     tiling_width=1,
                     tiling_height=1,
                     bpp=8)
    # Alternate stategy:
    img_8bpp = img_bin  #bytes(x for x in iter_bytes_4bit_le(img_bin))
    mod = 16 * 4
    channels = 1
    mode = 'RGB' if channels == 3 else 'P'
    out_img = Image.frombuffer(mode,
                               (int(len(img_8bpp) / mod / channels), mod),
                               bytes(img_8bpp), 'raw', mode, 0, 1)
    if mode == 'P':
        out_img.putpalette(pal.get_palette_for_frame(0, 0))
    os.makedirs(os.path.join(output_dir, 'raw_img'), exist_ok=True)
    with open(os.path.join(output_dir, 'raw_img', fn), 'wb') as f:
        f.write(img_bin)

    out_img.save(os.path.join(output_dir, fn + '.png'))
Exemple #2
0
    def _process(self):
        len_seq, sequence = self._look_ahead_two_int_sequence()
        if DEBUG:
            cursor_before = self.cursor
            wr_before = self.bytes_written
            print(f"Read a sequence of length {len_seq}")
        if len_seq > NRL_MIN_SEQ_LEN:
            # CMD_COPY_BYTES
            if DEBUG:
                print(f"CMD_COPY_BYTES")
            self.cursor += len_seq * 4
            cmd_byte = CMD_COPY_BYTES + (len_seq - 1)
            self._write_cmd(cmd_byte)
            for b in iter_bytes(sequence, 4):
                self._write_pair24(b)
        else:
            current_int_pair = self._read()
            repeats = self._look_ahead_repeats(current_int_pair)
            if DEBUG:
                print(f"Read {repeats} repeats of {current_int_pair:08x}")
            self.cursor += repeats * 4
            if read_uintle(current_int_pair, 0, 4) == 0:
                if DEBUG:
                    print(f"CMD_ZERO_OUT")
                # CMD_ZERO_OUT
                cmd_byte = repeats
                self._write_cmd(cmd_byte)
            else:
                # CMD_FILL_OUT
                if DEBUG:
                    print(f"CMD_FILL_OUT")
                # To big for one cmd, just make it into two.
                if repeats > NRL_LOOKAHEAD_FILL_MAX_BYTES:
                    repeats_byte1 = repeats - NRL_LOOKAHEAD_FILL_MAX_BYTES
                    cmd_byte1 = CMD_FILL_OUT + (repeats_byte1 - 1)
                    cmd_byte2 = CMD_FILL_OUT + (repeats - repeats_byte1)
                    self._write_cmd(cmd_byte1)
                    self._write_pair24(current_int_pair)
                    self._write_cmd(cmd_byte2)
                    self._write_pair24(current_int_pair)
                else:
                    cmd_byte = CMD_FILL_OUT + repeats
                    self._write_cmd(cmd_byte)
                    self._write_pair24(current_int_pair)

        if DEBUG:
            print(
                f"-- cursor advancement: {self.cursor - cursor_before} -- write advancement: {self.bytes_written - wr_before}"
            )
def corrupt341():
    """Corrupt 341: Dungeon tiles Beach cave 2? -- No? Tiles -> Chunk mappings or similar?"""
    img341 = dungeon_bin[341].decompress()
    img341new = bytearray(img341)

    # Decode XOR
    #XOR_ROW_LEN = 7200#18 * 7
    #rows_decoded = []
    #row_before = bytes(XOR_ROW_LEN)
    #for chunk in iter_bytes(img341, XOR_ROW_LEN):
    #    xored = bytearray(a ^ b for (a, b) in zip(chunk, row_before))
    #    row_before = xored
    #    rows_decoded.append(xored)

    dummy_map = [
        TilemapEntry(10, False, False, 0),
        TilemapEntry(10, True, False, 0),
        TilemapEntry(10, False, True, 0),
        TilemapEntry(5, False, False, 0),
        TilemapEntry(5, True, False, 0),
        TilemapEntry(5, False, True, 0),
        TilemapEntry(10, False, False, 6),
        TilemapEntry(10, True, False, 6),
        TilemapEntry(10, False, True, 6)
    ]

    for j in range(1, 300):
        for i, m in enumerate(dummy_map):
            write_u16(img341new, m.to_int(), (j * 18) + 2 * i)

    all_tilemaps = []
    for bytes2 in iter_bytes(img341new, 2):
        all_tilemaps.append(TilemapEntry.from_int(read_u16(bytes2, 0)))

    # Encode XOR
    #rows_encoded = []
    #row_before = bytes(XOR_ROW_LEN)
    #for row in rows_decoded:
    #    xored = bytes(a ^ b for (a, b) in zip(row, row_before))
    #    row_before = row
    #    rows_encoded.append(xored)
    #img341new = bytes(itertools.chain.from_iterable(rows_encoded))
    #assert img341 == img341new

    with open('/tmp/corrupt.bin', 'wb') as f:
        f.write(img341new)
    dungeon_bin[341] = FileType.COMMON_AT.compress(img341new)
Exemple #4
0
def output_at_water_tiles(fn: str, common_at: CommonAt, pal: Dpla):
    print("Outputting water AT as image.")
    img_bin = common_at.decompress()
    tiles = list(iter_bytes(img_bin, int(8 * 8 / 2)))
    # create a dummy tile map containing all the tiles
    tilemap = []
    for i in range(0, len(tiles)):
        tilemap.append(TilemapEntry(i, False, False, 0, True))
    out_img = to_pil(tilemap,
                     tiles, [pal.get_palette_for_frame(0, 0)],
                     8,
                     int(len(tiles) * 8 / 3),
                     4 * 8,
                     tiling_width=1,
                     tiling_height=1)
    os.makedirs(os.path.join(output_dir, 'raw_img'), exist_ok=True)
    with open(os.path.join(output_dir, 'raw_img', fn), 'wb') as f:
        f.write(img_bin)

    out_img.save(os.path.join(output_dir, fn + '.png'))