#!/usr/bin/env python

import sys
import time
import math
import array

def color(a):
    g = 255 * ((a & 4) != 0)
    r = 255 * ((a & 2) != 0)
    b = 255 * ((a & 1) != 0)
    return [r,g,b]

def snapvideo(z80file):
    z80 = array.array('B', open(z80file).read()).tolist()
    mem = []
    comp = z80[30:]
    while True:
      if comp == [0, 0xed, 0xed, 0]:
        break
      if comp[0:2] == [0xed, 0xed]:
        mem += [comp[3]] * comp[2]
        comp = comp[4:]
      else:
        mem.append(comp.pop(0))
    assert len(mem) == 0xc000
    return array.array('B', mem)[0:2048 * 3 + 768]

import Image
def dumpvideo(pixels, attr):
    im = Image.new("1", (256, 192))
    for y in range(192):
        srcy = (y & 0xc0) | ((y & 7) << 3) | ((y >> 3) & 7)
        line = Image.fromstring("1", (256, 1), pixels[32 * srcy:32 * srcy + 32].tostring())
        im.paste(line, (0,y))

    im = im.convert("L")
    for y in range(192):
        for x in range(256):
            a = attrs[(y / 8) * 32 + (x / 8)]
            if im.getpixel((x,y)):
                p = a&7
            else:
                p = (a>>3)&7
            im.putpixel((x,y), p)

    im.putpalette(sum([color(a) for a in range(8)], []))
    im.save("out.png")
    open("video", "w").write(pixels.tostring() + attrs.tostring())

if 0:
    v = open("video", "r")
    pixels = array.array('B', v.read(3 * 2048))
    attrs = array.array('B', v.read(3 * 256))

#for y in range(192):
#    pix = pixels[32 * y: 32 * y + 32]
#    im.paste(Image.fromstring("1", (256,1), 

import gameduino
import gameduino.remote
import gameduino.compress
import gameduino.prep as gdprep

cd = gameduino.compress.Codec(8, 5)

gd = gameduino.remote.Gameduino(sys.argv[1], 115200)
gd.wr(gameduino.J1_RESET, 1)
for i in range(64):
    gd.wr16(gameduino.RAM_PAL + 8 * i, gameduino.RGB(0,0,0))
    gd.wr16(gameduino.RAM_PAL + 8 * i + 2, gameduino.RGB(0,255,0))
    gd.wr16(gameduino.RAM_PAL + 8 * i + 4, gameduino.RGB(0,255,0))
    gd.wr16(gameduino.RAM_PAL + 8 * i + 6, gameduino.RGB(255,255,255))
# gd.fill(gameduino.RAM_PAL, 0x20, 256);
# gd.fill(gameduino.RAM_PAL + 256, 0x1f, 256);

for i in range(64):
    ink = color(i & 7)
    paper = color((i >> 3) & 7)
    gd.wr16(0x7000 + 4 * i, gameduino.RGB(*paper))
    gd.wr16(0x7000 + 4 * i + 2, gameduino.RGB(*ink))

gd.fill(0, 0xff, 38 * 64)
gd.wr16(gameduino.RAM_PAL + 8 * 255, gameduino.TRANSPARENT)
for j in range(24):
    for i in range(32):
        gd.wr(64 * (j + 6) + (9 + i), (j & 1) * 32 + i)

gd.wrstr(0x7100, array.array('B', [
  0x00, 0x03, 0x0c, 0x0f,
  0x30, 0x33, 0x3c, 0x3f,
  0xc0, 0xc3, 0xcc, 0xcf,
  0xf0, 0xf3, 0xfc, 0xff]))

hh =  open("../../spectrum_data.h", "w")
gdprep.dump(hh, "spectrum_tables", cd.toarray(gd.rdstr(0x7000, 0x110)))

gd.microcode(open("../../j1firmware/spectrum.binle").read())
gd.wr16(gameduino.BG_COLOR, gameduino.RGB(128,0,0))
tot = 0
for z in ["mm1", "mm2", "aa0", "aa1", "fl1", "jp0", "jp1", "kl0", "kl1"]:
    v = snapvideo("%s.z80" % z)
    c = cd.toarray(v.tostring())
    gdprep.dump(hh, "screen_%s" % z, c)
    print z, len(v), len(c)
    tot += len(c)
    gd.wrstr(0x4000, v)
    time.sleep(0)
print tot

