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'))
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)
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'))