def decompress_file(filein, fileout=None): image = bytearray(open(filein).read()) de = Decompressed(image) if fileout == None: fileout = os.path.splitext(filein)[0] to_file(fileout, de.output)
def decompress_from_address(address, filename='de.2bpp'): """ Write decompressed data from an address to a 2bpp file. """ rom = load_rom() image = Decompressed(rom, start=address) to_file(filename, image.output)
def decompress_fx_by_id(i, fxs=0xcfcf6): rom = load_rom() addr = fxs + i * 4 num_tiles = rom[addr] bank = rom[addr + 1] address = rom[addr + 3] * 0x100 + rom[addr + 2] offset = rom_offset(bank, address) fx = Decompressed(rom, start=offset) return fx
def decompress_unown_by_id(rom, letter, face='front', crystal=True): if crystal: bank_offset = 0x36 else: bank_offset = 0 address = unowns + (letter * 2 + {'front': 0, 'back': 1}.get(face, 0)) * 3 bank = rom[address] + bank_offset address = rom[address + 2] * 0x100 + rom[address + 1] address = (bank * 0x4000) + (address - (0x4000 * bool(bank))) unown = Decompressed(rom, start=address) return unown
def decompress_trainer_by_id(rom, i, crystal=True): rom = load_rom() if crystal: bank_offset = 0x36 else: bank_offset = 0 address = trainers_offset + i * 3 bank = rom[address] + bank_offset address = rom[address + 2] * 0x100 + rom[address + 1] address = rom_offset(bank, address) trainer = Decompressed(rom, start=address) return trainer
def decompress_monster_by_id(rom, mon=0, face='front', crystal=True): """ For Unown, use decompress_unown_by_id instead. """ if crystal: bank_offset = 0x36 else: bank_offset = 0 address = monsters + (mon * 2 + {'front': 0, 'back': 1}.get(face, 0)) * 3 bank = rom[address] + bank_offset address = rom[address + 2] * 0x100 + rom[address + 1] address = bank * 0x4000 + (address - (0x4000 * bool(bank))) monster = Decompressed(rom, start=address) return monster
def decompress(filenames=[]): for filename in filenames: name, extension = os.path.splitext(filename) lz_data = open(filename, 'rb').read() data = Decompressed(lz_data).output to_file(name, data)
def rip_compressed_gfx(rom, address, filename): gfx = Decompressed(rom, start=address) to_file(filename, gfx.compressed_data)
def dump_pic_animations(addresses={ 'bitmasks': 'BitmasksPointers', 'frames': 'FramesPointers' }, pokemon=pokemon_constants, rom=None): """ The code to dump pic animations from rom is mysteriously absent. Here it is again, but now it dumps images instead of text. Said text can then be derived from the images. """ if rom is None: rom = load_rom() # Labels can be passed in instead of raw addresses. for which, offset in addresses.items(): if type(offset) is str: for line in open('pokecrystal.sym').readlines(): if offset in line.split(): addresses[which] = rom_offset( *map(lambda x: int(x, 16), line[:7].split(':'))) break for i, name in pokemon.items(): if name.lower() == 'unown': continue i -= 1 directory = os.path.join('gfx', 'pics', name.lower()) size = sizes[i] if i > 151 - 1: bank = 0x36 else: bank = 0x35 address = addresses['frames'] + i * 2 address = rom_offset(bank, rom[address] + rom[address + 1] * 0x100) addrs = [] while address not in addrs: addr = rom[address] + rom[address + 1] * 0x100 addrs.append(rom_offset(bank, addr)) address += 2 num_frames = len(addrs) # To go any further, we need bitmasks. # Bitmasks need the number of frames, which we now have. bank = 0x34 address = addresses['bitmasks'] + i * 2 address = rom_offset(bank, rom[address] + rom[address + 1] * 0x100) length = size**2 num_bytes = (length + 7) / 8 bitmasks = [] for _ in xrange(num_frames): bitmask = [] bytes_ = rom[address:address + num_bytes] for byte in bytes_: bits = map(int, bin(byte)[2:].zfill(8)) bits.reverse() bitmask += bits bitmasks.append(bitmask) address += num_bytes # Back to frames: frames = [] for addr in addrs: bitmask = bitmasks[rom[addr]] num_tiles = len(filter(int, bitmask)) frame = (rom[addr], rom[addr + 1:addr + 1 + num_tiles]) frames.append(frame) tmap = range(length) * (len(frames) + 1) for i, frame in enumerate(frames): bitmask = bitmasks[frame[0]] tiles = (x for x in frame[1]) for j, bit in enumerate(bitmask): if bit: tmap[(i + 1) * length + j] = tiles.next() filename = os.path.join(directory, 'front.{0}x{0}.2bpp.lz'.format(size)) tiles = get_tiles(Decompressed(open(filename).read()).output) new_tiles = map(tiles.__getitem__, tmap) new_image = connect(new_tiles) filename = os.path.splitext(filename)[0] to_file(filename, new_image) export_2bpp_to_png(filename)