v0.53.0: Kaleidostrobe, the 2002 iTunes visualizer, as the fourth style
Reverse-engineered from its PowerPC binary and checked against the original running under emulation: textures byte for byte and every triangle, over 3,600 frames. 25 fps like the plugin; its colour maps and wave images are extracted from its own code; tests/kaleidostrobe_golden.npz was recorded from the original.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""Golden data for tests/test_round84.py, produced by the ORIGINAL plugin
|
||||
running under emulation (see compare.py / coverage.py)."""
|
||||
import sys, hashlib, random
|
||||
sys.path.insert(0, __file__.rsplit('/', 1)[0]); sys.path.insert(0, str(__import__('pathlib').Path(__file__).resolve().parents[2]))
|
||||
import numpy as np
|
||||
from plugin import Plugin
|
||||
import compare
|
||||
from lintunes.kaleidostrobe import engine as E
|
||||
|
||||
def digest(a): return hashlib.sha256(np.ascontiguousarray(a).tobytes()).hexdigest()[:16]
|
||||
|
||||
def pattern(seed):
|
||||
y, x = np.mgrid[0:128, 0:128]
|
||||
return ((x * (7 + seed) + y * (13 + 2 * seed)) ^ (x * y + seed)).astype(np.uint8)
|
||||
|
||||
out = {}
|
||||
# 1. end to end: 120 frames at 640x480, seed ticks 1000
|
||||
p = Plugin(rect=(0, 0, 480, 640), ticks=1000)
|
||||
rnd = random.Random(11)
|
||||
F = 120
|
||||
spectra = np.zeros((F, 2, 512), np.uint8); ticks = np.zeros(F, np.int64)
|
||||
tex_d = []; geo = []; counts = []
|
||||
t0 = p.k.micro
|
||||
for f in range(F):
|
||||
spec = compare.spectra(f, rnd); spectra[f] = spec
|
||||
start = len(p.k.gl)
|
||||
p.k.micro += 40001
|
||||
tk = 1000 + (p.k.micro - t0) * 60 // 1_000_000; ticks[f] = tk
|
||||
calls = p.frame(None, spec, dt_us=0, dticks=tk - p.k.ticks)
|
||||
idx = [i for i in range(start, len(p.k.gl)) if p.k.gl[i][0] == '_glTexImage2D']
|
||||
tex_d.append([digest(np.frombuffer(p.k.textures[i], np.uint8)) for i in idx])
|
||||
tris = compare.gl_triangles(calls)
|
||||
counts.append(len(tris))
|
||||
geo.append(np.array([[(*v[0], *v[1]) for v in t[2]] for t in tris], np.float32))
|
||||
out['spectra'] = spectra; out['ticks'] = ticks
|
||||
out['tex_digest'] = np.array(tex_d)
|
||||
out['tri_counts'] = np.array(counts)
|
||||
out['tris'] = np.concatenate(geo) # (sum, 3, 5): s, t, x, y, z (eye space)
|
||||
# 2. every warp, 3 iterations from zeroed counters, layer 1
|
||||
TEXIDX, CURTEX, CURFRAME = 0x457f8, 0x13dbc, 0x13dc0
|
||||
k = p.k
|
||||
dd = []
|
||||
for n in E.DELTA_TABLE:
|
||||
k.u.mem_write(0x13b2c, b'\0' * (0x13be4 - 0x13b2c))
|
||||
row = []
|
||||
for it in range(3):
|
||||
src = pattern(n * 3 + it)
|
||||
k.u.mem_write(TEXIDX + 0x8000, src.tobytes())
|
||||
k.w32(CURTEX, 1); k.w32(CURFRAME + 4, 1)
|
||||
k.call(f'_calcDelta{n:03d}')
|
||||
row.append(digest(np.frombuffer(k.mem(TEXIDX + 0x8000 + 0x4000, 0x4000), np.uint8)))
|
||||
dd.append(row)
|
||||
out['delta_digest'] = np.array(dd)
|
||||
# 3. every wave-table entry, rand seeded 4321
|
||||
wd = []
|
||||
for idx in range(len(E.WAVE_TABLE)):
|
||||
k.rng.srand(4321)
|
||||
k.w32(CURTEX, 0); k.w32(CURFRAME, 0)
|
||||
k.call(f'_initWaveShape{E.WAVE_TABLE[idx]:03d}')
|
||||
wd.append(digest(np.frombuffer(k.mem(TEXIDX, 0x4000), np.uint8)))
|
||||
out['wave_digest'] = np.array(wd)
|
||||
np.savez_compressed(sys.argv[1], **out)
|
||||
print('frames', F, 'triangles', sum(counts), 'beats seen', None)
|
||||
Reference in New Issue
Block a user