Zombi Ubisoft (1986) PHP

par espritm · Remakes
pas encore noté
▶ Jouer 💬 Avis 1 Sources 🕘 Versions Éditer GitHub
games/zombi-ubisoft-1986-php / tools / extract / sources / export-sprites.py · commit 5c56e28
"""Decode the original object pointer table with upstream CPC graphics decoding."""from pathlib import Pathimport json,sysfrom PIL import Image,ImageChopssys.path.insert(0,'/workspace/dsk2jumphp/tools')from cpc import Dump,graphicsroot=Path('/workspace/analysis'); out=root/'extracted/objects';out.mkdir(exist_ok=True)d=Dump(root/'runs/direction-3/dump-08900.bin')def entry_for(obj):    # Literal mapping from #90BE–#90F0 (many IDs share one graphic).    if obj<4: n=1    elif obj<14: n=obj-2    elif obj<17: n=12    elif obj<29: n=obj-4    elif obj<33: n=25    elif obj<58: n=obj-7    else: n=obj-9    return n-1manifest=[]for obj in range(1,76):    p=0x7a0a+4*entry_for(obj)    address=int.from_bytes(d.mem[p:p+2],'little');w=d.mem[p+2]*4;h=d.mem[p+3]*16    if not w or not h or w>32 or h>64:        raise RuntimeError((obj,hex(p),address,w,h))    img=graphics(d.mem,address,w,h,1,mode=1,rgb=d.rgb,gap=0).convert('RGBA')    masked=27<=obj<56 or obj==73    if masked:        pixels=img.load(); transparent=d.rgb(0)        for y in range(img.height):            for x in range(img.width):                if pixels[x,y][:3]==transparent: pixels[x,y]=(0,0,0,0)    img.save(out/f'object-{obj:02d}.png')    manifest.append({'id':obj,'source_address':hex(address),'table_address':hex(p),        'width':img.width,'height':h,'transparent_pen0':masked,'file':f'object-{obj:02d}.png'})(out/'objects.json').write_text(json.dumps(manifest,indent=2))# Validate an observed room: original #901B draws at #C282, row stride #A0,# i.e. screen (8,64) in 16-pixel cells, relative to crop origin (8,48).world=json.loads((root/'extracted/world.json').read_text())room=next(r for r in world['rooms'] if r['id']==38)canvas=Image.open(root/'extracted/rooms/background-38.png').convert('RGBA')drawn=set()for row,cells in enumerate(room['objects_grid']):    for col,obj in enumerate(cells):        if obj not in (0,255) and (obj not in drawn or obj==48):            sprite=Image.open(out/f'object-{obj:02d}.png')            canvas.alpha_composite(sprite,(col*16,16+row*16))            drawn.add(obj)canvas.convert('RGB').save(out/'room-38-rebuilt.png')diff=ImageChops.difference(canvas.convert('RGB'),Image.open(root/'extracted/rooms/room-38.png'))print('Room 38 reconstructed diff bounding box:',diff.getbbox())if diff.getbbox() is not None:    raise RuntimeError('Sprite composition does not match original')print('Exported',len(manifest),'object IDs')