from PIL import Image # Taken from NSE2 bookmarks OFFSETS = [ ("Type1", 0x41f1c8, 0x471dec, 5, 4), ("Type2", 0x470b0c, 0x471e0c, 5, 4), ("Style0", 0x470D6c, 0x47190c, 3, 3), ("Style1", 0x470e8c, 0x47192c, 3, 3), ("Style2", 0x47132c, 0x4719ac, 3, 3), ("Style3", 0x47144c, 0x4719cc, 3, 3), ("Style4", 0x47156c, 0x4719ec, 3, 3), ("Style5", 0x4716ac, 0x471a0c, 3, 3), ("Style6", 0x4717cc, 0x471a2c, 3, 3)] ROMPATH = "firered.gba" with open(ROMPATH, "rb") as rom_file: rom = rom_file.read() codec = LinearCodec(4, LinearCodec.REVERSE_ORDER) tilesize = codec.getTileSize() for title, img_offs, pal_offs, tiles_w, tiles_h in OFFSETS: palette_data = rom[pal_offs:pal_offs + gba.PALETTE_SIZE] palette_rgb = gba.decode_palette(palette_data, alpha=True) data_len = tiles_w * tiles_h * tilesize img_data = rom[img_offs:img_offs + data_len] img = gba.decode_image(img_data, codec, palette_rgb, tiles_w) img.save("export/textures/textbox_" + title + ".png")
arrow_addr = 0xE84588 arrow_palette_addr = 0xE845C8 ROMPATH = "firered.gba" GENDERNAMES = ["male", "female"] with open(ROMPATH, "rb") as romfile: rom = romfile.read() codec = LinearCodec(4, LinearCodec.REVERSE_ORDER) bag_male_data = lz77.decompress(rom[bag_male:]) bag_female_data = lz77.decompress(rom[bag_female:]) bag_palette_data = lz77.decompress(rom[bag_palette:]) bag_palette_pal = gba.decode_palette(bag_palette_data, alpha=True) bag_male_img = gba.decode_image(bag_male_data, codec, bag_palette_pal, 8) bag_male_img.save("export/textures/bag_male.png") bag_female_img = gba.decode_image(bag_female_data, codec, bag_palette_pal, 8) bag_female_img.save("export/textures/bag_female.png") arrow_data = lz77.decompress(rom[arrow_addr:]) arrow_palette_data = lz77.decompress(rom[arrow_palette_addr:]) arrow_palette = gba.decode_palette(arrow_palette_data, alpha=True) arrow_image = gba.decode_image(arrow_data, codec, arrow_palette, 2) arrow_image.save("export/textures/arrow.png") bkgr_data = lz77.decompress(rom[bkgr_addr:]) bkgr_tiles = list(gba.iter_decode_tiles(codec, bkgr_data)) bkgr_palettes = [None, None]
def decode_image_at(rom, codec, image_ptr, palette_ptr, image_len=None, width=16): image_offset = get_rom_addr(image_ptr) palette_offset = get_rom_addr(palette_ptr) bpp = codec.getBitsPerPixel() if check_valid(rom, image_offset, strict=True): print("Loading compressed image at", hex(image_ptr)) image_data = lz77.decompress(rom, image_offset) elif image_len is not None: print("Loading uncompressed image at", hex(image_ptr)) image_data = rom[image_offset : image_offset + image_len] else: return "MISSING_IMAGE_LENGTH" tile_size = codec.getTileSize() if len(image_data) % tile_size: # Fill remaining tile with padding bytes image_data += b"\x00" * (tile_size - len(image_data) % tile_size) pal_size = gba.get_palette_size(bpp) if check_valid(rom, palette_offset, strict=True): print("Loading compressed palette at", hex(palette_ptr)) decomp_data = lz77.decompress(rom, palette_offset) if len(decomp_data) < pal_size: return "PALETTE_TOO_SMALL" palette_data = decomp_data[:pal_size] else: print("Loading uncompressed palette at", hex(palette_ptr)) palette_data = rom[palette_offset : palette_offset + pal_size] try: palette = gba.decode_palette(palette_data, bpp=bpp) except: return "PALETTE_DECODE_FAILED" try: image = gba.decode_image(image_data, codec, palette, width) except: return "IMAGE_DECODE_FAILED" return image