Exemplo n.º 1
0
def fix_pal(filename):
    with open(filename, 'rb') as file:
        width, height, data = png.Reader(file).asRGBA8()[:3]
        data = list(data)
    b_and_w = {(0, 0, 0), (31, 31, 31)}
    colors = set(c for row in data for c in rgb5_pixels(row)) - b_and_w
    if not colors:
        colors = {(21, 21, 21), (10, 10, 10)}
    elif len(colors) == 1:
        c = colors.pop()
        colors = {c, invert(c)}
    elif len(colors) != 2:
        return False
    palette = tuple(sorted(colors | b_and_w, key=luminance, reverse=True))
    assert len(palette) == 4
    data = [list(map(palette.index, rgb5_pixels(row))) for row in data]
    if palette == ((31, 31, 31), (21, 21, 21), (10, 10, 10), (0, 0, 0)):
        data = [[3 - c for c in row] for row in data]
        writer = png.Writer(width,
                            height,
                            greyscale=True,
                            bitdepth=2,
                            compression=9)
    else:
        palette = tuple(map(rgb5_to_rgb8, palette))
        writer = png.Writer(width,
                            height,
                            palette=palette,
                            bitdepth=8,
                            compression=9)
    with open(filename, 'wb') as file:
        writer.write(file, data)
    return True
def main():
    mapfile = sys.argv[1] if len(sys.argv) >= 2 else 'pokegold-spaceworld.map'
    filename = sys.argv[2] if len(sys.argv) >= 3 else 'coverage.png'

    num_banks = 0x40
    bank_mask = 0x3FFF
    bank_size = 0x4000  # bytes

    bpp = 8  # bytes per pixel
    height = 256  # pixels
    assert bank_size % bpp == 0 and (bank_size // bpp) % height == 0

    pixels_per_bank = bank_size // bpp  # 2048 pixels
    bank_width = pixels_per_bank // height  # 8 pixels
    width = bank_width * num_banks  # 1024 pixels

    r = MapReader()
    with open(mapfile, 'r', encoding='utf-8') as f:
        l = f.readlines()
    r.read_map_data(l)

    hit_data = []
    default_bank_data = {'sections': [], 'used': 0, 'slack': bank_size}
    for bank in range(num_banks):
        hits = [0] * pixels_per_bank
        data = r.bank_data['rom bank'].get(bank, default_bank_data)
        for s in data['sections']:
            if s['beg'] > s['end']:
                continue
            if s['beg'] == 0x0000 and s['end'] > 0xFFFF:
                # https://github.com/gbdev/rgbds/issues/515
                continue
            beg = s['beg'] & bank_mask
            end = s['end'] & bank_mask
            for i in range(beg, end + 1):
                hits[i // bpp] += 1
        hit_data.append(hits)

    pixels = [[(0xFF, 0xFF, 0xFF)] * width for _ in range(height)]
    for bank, hits in enumerate(hit_data):
        hue = 0 if not bank else 210 if bank % 2 else 270
        for i, h in enumerate(hits):
            y = i // bank_width
            x = i % bank_width + bank * bank_width
            hls = (hue / 360.0, 1.0 - (h / bpp * (100 - 15)) / 100.0, 1.0)
            rgb = tuple(int(c * 255) for c in hls_to_rgb(*hls))
            pixels[y][x] = rgb

    png_data = [tuple(c for pixel in row for c in pixel) for row in pixels]
    with open(filename, 'wb') as f:
        w = png.Writer(width, height)
        w.write(f, png_data)