"""Of the elements whose guessed rest pose has scale 0%, how many actually paint? ⚠️ The premise this was first written with was WRONG. blit() did not draw a zero-scale element as a 1-pixel sliver: it coerced `scale == 0` to **100 %**, so a fully-collapsed element rendered at FULL SIZE. The `.max(1)` further down never saw a zero. Read the code before describing what it does -- the guard was two lines above the arithmetic I had read. That coercion is now removed (scale 0 draws nothing); this script is what sized the change. It counts elements whose guessed rest pose is zero-scale and whose alpha is non-zero, i.e. the ones the old code actually painted. """ import struct, zlib, glob, os, collections from disc import disc_root DECL_AT, DECL_ENTRY, KEYFRAME = 0x20, 60, 40 def entries(base): stub=open(base+".pak","rb").read() if stub[:4]!=b"IPFB": return n=struct.unpack_from(">I",stub,4)[0] segs=sorted(glob.glob(base+".p[0-9][0-9]")) if not segs: return blob=b"".join(open(s,"rb").read() for s in segs) for i in range(n): h,off,sz=struct.unpack_from(">III",stub,0x10+12*i) st=blob[off:off+sz] if len(st)<10: continue try: yield i,h,(zlib.decompress(st[10:]) if st[:2]==b"Z1" else st) except Exception: continue def elements_t(d): if d[:4]!=b"RATC": return [] count=struct.unpack_from(">I",d,0x14)[0] if not (0len(d): return [] names.append(d[o:o+28].split(b"\0")[0].decode("ascii","replace")) out,pos=[],DECL_AT+count*DECL_ENTRY for _ in range(count): if pos+8>len(d): break idx,frames=struct.unpack_from(">II",d,pos) if idx>=count or frames==0 or frames>4096: break first=pos+12; end=first+frames*KEYFRAME-4 poses,times=[],[] for k in range(frames): blk=first+k*KEYFRAME if blk+36>len(d) or blk+36>end: break poses.append(struct.unpack_from(">I",d,blk)+struct.unpack_from(">II",d,blk+16)+struct.unpack_from(">ii",d,blk+28)) times.append(struct.unpack_from(">i",d,blk+36)[0] if blk+40<=end else None) if poses: out.append((idx,names[idx],times,poses)) pos=end return out has_plateau=lambda p: any(p[i]==p[i+1] for i in range(len(p)-1)) def dwell_pick(t,p): best=(0,-1) for k in range(len(t)-1): if t[k] is None or t[k+1] is None: continue d=t[k+1]-t[k] if d>=best[1]: best=(k,d) return best[0] alpha=lambda p:(p[0]>>24)&0xff n=paint=0; where=collections.Counter(); ex=[] for pak in sorted(glob.glob(disc_root() + "/dat/GP_*.pak")): for i,h,d in entries(pak[:-4]): for idx,name,t,p in elements_t(d): if has_plateau(p): continue r=p[dwell_pick(t,p)] if r[1]==0 or r[2]==0: n+=1 if alpha(r)>0: paint+=1; where[os.path.basename(pak)]+=1 if len(ex)<10: ex.append((os.path.basename(pak),i,idx,name,r[1],r[2],alpha(r))) print(f"rest poses with scale 0%%: {n}") print(f" ... of which alpha > 0, so blit paints a 1-pixel sliver: {paint}") print(f" ... alpha == 0, harmless: {n-paint}") if paint: print("\nby archive:"); [print(f" {c:4d} {k}") for k,c in where.most_common()] print("\nexamples (pak, entry, element idx, name, sx, sy, alpha):") [print(" ",e) for e in ex]