Files
TaikoZhongandClaude Opus 5.5 2f7291d4ec background: pack the cabinet movies' per-frame channels into strings
The collab backdrops (and the default donbg band) replay exported movies
whose per-frame channels were Lua tables of numbers: 38 MB that Lua
compiled on every song start (0.7 s for the TOHO pack; game screen init
1.5-1.6 s -> 0.9-1.0 s in-game), plus ~19 MB of Lua memory per pack.

Each per-frame array is now {base, step, width, "digits"}: value = base +
step * n, n being the frame's width chars in base 92 (printable ASCII
without '"' and '\'). One string constant compiles in a fraction of the
time; bg_objects/packed_channel.lua decodes the frame being drawn.
Quantization: 0.05 px, 0.005 deg, 5e-5 scale, 1/1024 alpha and tint;
every value of all 77 files checked against the original within half a
step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 09:00:18 +08:00

30 lines
1.0 KiB
Lua

-- A channel of an exported cabinet movie (bg_data/bg_anim, bg_data/donbg_anim) at loop frame i
-- (1-based). A channel is a number (constant), a table with one value per frame, or a packed
-- table {base, step, width, digits}: value = base + step * n, n being frame i's `width` chars of
-- `digits` in base 92 (printable ASCII without '"' and '\'). The packed form compiles several
-- times faster than a table of numbers and takes a fraction of the memory.
-- Written by scratchpad/arcade_collab/pack_channels.py.
local byte = string.byte
local DIGIT = {}
do
local d = 0
for c = 33, 126 do
if c ~= 34 and c ~= 92 then
DIGIT[c] = d
d = d + 1
end
end
end
return function(v, i)
if type(v) == "number" then return v end
local s = v[4]
if type(s) ~= "string" then return v[i] end -- a plain table: one value per frame
local w = v[3]
local p = (i - 1) * w
local n = DIGIT[byte(s, p + 1)]
for k = p + 2, p + w do n = n * 92 + DIGIT[byte(s, k)] end
return v[1] + v[2] * n
end