RAINBOW ISLANDS

par davidnurdin · Remakes
pas encore noté
▶ Jouer Sources Éditer GitHub
games/rainbow-island / tools / extract / frameset.py · commit d529485
# Infer sizes of the 29 sprite frames of an island and draw them.import sys, os, struct, jsonsys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))from sprite import decodefrom cpc import HWdef roughness(rows):    h=len(rows); w=len(rows[0]); bad=0; n=0    for y in range(h-1):        for x in range(w):            n+=1; bad+= rows[y][x]!=rows[y+1][x]    return bad/max(1,n)KNOWN={0xed80:(6,24),0xee10:(6,24),0xeea0:(6,24),0xef30:(6,24),0xf580:(6,24),0xf610:(6,24),0xf6a0:(6,24),0xf730:(6,24),       0xf7c0:(4,16),0xc79e:(6,16),0xe5a0:(6,16),0xfd80:(6,16),0xfde0:(6,16)}def frames(mem):    p=[struct.unpack('<H',mem[0x4bfc+i*2:0x4bfe+i*2])[0] for i in range(29)]    out=[]    for i,a in enumerate(p):        if a==0: out.append(None); continue        if a in KNOWN: w,h=KNOWN[a]; out.append((a,w,h)); continue        nxt=[q for q in p if q>a]; ln=(min(nxt)-a) if nxt else None        best=None        if ln and ln%6==0 and 10<=ln//6<=32: out.append((a,6,ln//6)); continue        for w in (4,6,8,10,12,16):            for h in ([ln//w] if ln and ln%w==0 else range(8,33)):                if h<6 or h>48: continue                if ln is None and h not in (16,24,32): continue                r=roughness(decode(mem,a,w,h))                if best is None or r<best[0]: best=(r,w,h)        out.append((a,best[1],best[2]) if best else None)    return outif __name__=='__main__':    from PIL import Image    mem=open(sys.argv[1],'rb').read(); pal=list(mem[0x20000+17:0x20000+33])    fr=frames(mem); print([(hex(f[0]),f[1],f[2]) if f else None for f in fr])    W=sum((f[1]*2+3) for f in fr if f); H=max(f[2] for f in fr if f)    im=Image.new('RGB',(W,H),(255,0,255)); px=im.load(); x0=0    for f in fr:        if not f: continue        a,w,h=f        for y,row in enumerate(decode(mem,a,w,h)):            for x,p in enumerate(row): px[x0+x,y]=HW[pal[p]] if p else (0,0,0)        x0+=w*2+3    im.resize((im.width*4,im.height*4),Image.NEAREST).save(sys.argv[2])