Example #1
0
def main(argv=None):
    argv = argv or sys.argv

    if len(argv) > 1 and argv[0] == '--help':
        print("usage: sav2sb53.py infile.sav outfile.pb53\n"
              "Packs a savtool background in PB53 format.")
        return
    if len(argv) != 3:
        print("sav2sb53.py: wrong number of arguments; try sav2sb53.py --help",
              file=sys.stderr)
        sys.exit(1)
    _, infilename, outfilename = argv
    with open(infilename, 'rb') as infp:
        data = infp.read(8192)
    namdata = data[6144:7168]
    num_tiles = 1 + max(namdata[:960])
    chrdata = data[0:16 * num_tiles]
    paldata = data[-256:-240]

    outdata = [
        bytearray([num_tiles & 0xFF]),
        pb53.pb53(chrdata)[0], pb53.pb53(namdata)[0],
        paldata
    ]
    with open(outfilename, 'wb') as outfp:
        outfp.writelines(outdata)
Example #2
0
def main(argv=None):
    argv = argv or sys.argv

    if len(argv) > 1 and argv[1] == '--help':
        print(
            "usage: sav2sb53.py infile.sav outfile.pb53\n"
            "Packs a savtool background: tile count, PB53 tile data, PB53 nametable,\n"
            "16-entry palette")
        return
    if len(argv) != 3:
        print("sav2sb53.py: wrong number of arguments; try sav2sb53.py --help",
              file=sys.stderr)
        sys.exit(1)
    _, infilename, outfilename = argv
    with open(infilename, 'rb') as infp:
        data = infp.read(8192)
    namdata = data[6144:7168]
    num_tiles = 1 + max(namdata[:960])
    chrdata = data[0:16 * num_tiles]
    paldata = data[-256:-240]

    outdata = [
        bytearray([num_tiles & 0xFF]),
        pb53.pb53(chrdata)[0],
        pb53.pb53(namdata)[0], paldata
    ]
    with open(outfilename, 'wb') as outfp:
        outfp.writelines(outdata)
Example #3
0
def main(argv=None):
    args = parse_argv(argv or sys.argv)
    blanktile = b"".join((b"\xff" if args.blank_color & b else b"\x00") * 8
                         for b in [0x01, 0x02])
    with open(args.savfile, "rb") as infp:
        tiledata = infp.read(4096)
        infp.read(2048)
        nt = infp.read(960)
        attrs = infp.read(64)
        infp.read(768)
        palette = infp.read(16)
    tiledata = [tiledata[16 * i:16 * i + 16] for i in nt]
    nt = None
    tiledata, r = crop_blank_tiles(tiledata, 32, blanktile)
    tiles_per_row = r[2] - r[0]
    tiledata, nt = uniq_on_grid(tiledata,
                                tiles_per_row,
                                args.x_grid,
                                args.y_grid,
                                blanktile=blanktile,
                                verbose=args.verbose)
    # Crop the leading blank tile
    assert tiledata[0] == blanktile
    del tiledata[0]

    # Now compress everything
    ctiles, _ = pb53.pb53(b''.join(tiledata))
    cnt = iu53_compress_nt(nt)
    start_tile = args.start_tile
    if start_tile is None:
        start_tile = len(args.x_grid) * len(args.y_grid)
        if args.verbose:
            print("starting tile number set to %d" % start_tile)
    if args.verbose:
        print("cropped to rect: (%d, %d)-(%d, %d)" % r)
        print("%s: %d bytes of pattern and %d bytes of map" %
              (args.savfile, len(ctiles), len(cnt)))
        out = iu53_decompress_nt(cnt, len(nt))
        print("Match" if nt == out else "Decompression mismatch")

    ntaddr = 0x2000 + r[1] * 32 + r[0]
    if args.with_attrs:
        ntaddr += 0x8000
    if args.with_palette:
        ntaddr += 0x4000

    out = bytearray([start_tile, len(tiledata)])
    out.extend(ctiles)
    out.extend(
        (ntaddr & 0xFF, (ntaddr >> 8) & 0xFF, tiles_per_row, r[3] - r[1]))
    out.extend(cnt)
    if args.with_attrs:
        cattrs, _ = pb53.pb53(attrs)
        out.extend(cattrs)
    if args.with_palette:
        out.extend(palette)
    if args.verbose:
        print(len(out), "total bytes")
    with open(args.iu53file, "wb") as outfp:
        outfp.write(out)
Example #4
0
def bmptowidesb53(infilename, palette, outfilename):
    im = Image.open(infilename)
    if im.size[0] != 512:
        raise ValueError("Image width is %d pixels (expected 512)" %
                         im.size[0])
    if im.size[1] != 240:
        raise ValueError("Image height is %d pixels (expected 240)" %
                         im.size[0])

    # Quantize picture to palette
    palette = b''.join(palette[0:1] + palette[i + 1:i + 4]
                       for i in range(0, 16, 4))
    palettes = [[tuple(savtool.bisqpal[r]) for r in palette[i:i + 4]]
                for i in range(0, 16, 4)]
    imf, attrs = savtool.colorround(im, palettes)

    # Convert to unique tiles
    chrdata = pilbmp2nes.pilbmp2chr(imf, 8, 8)
    chrdata, linear_namdata = chnutils.dedupe_chr(chrdata)
    print("%d distinct tiles" % len(chrdata))

    # Split into separate 32x32 nametables
    nametables = [[
        linear_namdata[i:i + 32]
        for i in range(x, len(linear_namdata), im.size[0] // 8)
    ] for x in range(0, im.size[0] // 8, 32)]
    nametables = [bytes(b for row in nt for b in row) for nt in nametables]

    # Pack attributes into bytes
    if len(attrs) % 2:
        attrs.append([0] * len(attrs[0]))
    attrs = [[lc | (rc << 2) for lc, rc in zip(row[0::2], row[1::2])]
             for row in attrs]
    attrs = [[tc | (bc << 4) for (tc, bc) in zip(t, b)]
             for (t, b) in zip(attrs[0::2], attrs[1::2])]
    # Split into separate 32x32 nametables
    attrs = [
        bytes(b for row in attrs for b in row[i:i + 8])
        for i in range(0, len(attrs[0]), 8)
    ]
    print([len(x) for x in attrs])

    outdata = [
        bytearray([len(chrdata) & 0xFF]),
        pb53(b''.join(chrdata), copyprev=False)[0]
    ]
    outdata.extend(
        pb53(nt + at, copyprev=False)[0] for nt, at in zip(nametables, attrs))
    outdata.append(palette)
    with open(outfilename, 'wb') as outfp:
        outfp.writelines(outdata)
Example #5
0
def bmptowidesb53(infilename, palette, outfilename):
    im = Image.open(infilename)
    if im.size[0] != 512:
        raise ValueError("Image width is %d pixels (expected 512)"
                         % im.size[0])
    if im.size[1] != 240:
        raise ValueError("Image height is %d pixels (expected 240)"
                         % im.size[0])

    # Quantize picture to palette
    palette = b''.join(palette[0:1] + palette[i + 1:i + 4]
                       for i in range(0, 16, 4))
    palettes = [[tuple(savtool.bisqpal[r]) for r in palette[i:i + 4]]
                 for i in range(0, 16, 4)]
    imf, attrs = savtool.colorround(im, palettes)

    # Convert to unique tiles    
    chrdata = pilbmp2nes.pilbmp2chr(imf, 8, 8)
    chrdata, linear_namdata = chnutils.dedupe_chr(chrdata)
    print("%d distinct tiles" % len(chrdata))

    # Split into separate 32x32 nametables
    nametables = [[linear_namdata[i:i + 32]
                   for i in range(x, len(linear_namdata), im.size[0] // 8)]
                  for x in range(0, im.size[0] // 8, 32)]
    nametables = [bytes(b for row in nt for b in row) for nt in nametables]

    # Pack attributes into bytes
    if len(attrs) % 2:
        attrs.append([0] * len(attrs[0]))
    attrs = [[lc | (rc << 2) for lc, rc in zip(row[0::2], row[1::2])]
             for row in attrs]
    attrs = [[tc | (bc << 4) for (tc, bc) in zip(t, b)]
             for (t, b) in zip(attrs[0::2], attrs[1::2])]
    # Split into separate 32x32 nametables
    attrs = [bytes(b for row in attrs for b in row[i:i + 8])
             for i in range(0, len(attrs[0]), 8)]
    print([len(x) for x in attrs])

    outdata = [
        bytearray([len(chrdata) & 0xFF]),
        pb53(b''.join(chrdata), copyprev=False)[0]
    ]
    outdata.extend(pb53(nt + at, copyprev=False)[0]
                   for nt, at in zip(nametables, attrs))
    outdata.append(palette)
    with open(outfilename, 'wb') as outfp:
        outfp.writelines(outdata)
Example #6
0
def main(argv=None):
    argv = argv or sys.argv
    specfilename = argv[1]
    imname = argv[2]
    outfilename = argv[3]
    lines = load_spec_file(specfilename)
    coords = []
    for line in lines:
        coord = [x.strip() for x in line.split(',')]
        if len(coord) != 2 or not all(x.isdigit() for x in coord):
            print("%s is not coords" % line, sys.stderr)
            continue
        coords.append(tuple(int(x) for x in coord))

    im = Image.open(imname)
    if im.mode != 'P':
        print("mkspritemap.py: %s must be indexed" % imname,
              file=sys.stderr))
        sys.exit(1)

    overdraw = [0]*im.size[1]
    alltiles = []
    out = array.array('B', [len(coords)])
    for left, top in coords:
        out.extend((left, top))
        for y in xrange(top, top + 8):
            overdraw[y] += 1
        tdata = pilbmp2chr(im.crop((left, top, left+8, top+8)))
        alltiles.extend(tdata)
    compressed = pb53.pb53(''.join(alltiles))[0]
    out.fromstring(compressed)
    print("Num tiles: %d; max overdraw: %d; data size: %d bytes"
          % (len(alltiles), max(overdraw), len(compressed)))