Files
YataiDONNijiiro/Scripts/background/bg_objects/bg_anim.lua
T
TaikoZhongandClaude Fable 5.1 4d3127d9ea Replay the cabinet's add-blended light effects as additive
The exported clips and backdrop movies were drawn source-over everywhere, but the
cabinet places a number of glow layers with its add blend mode: the lantern glows
of the lower backdrops (bg_nomal_a_01..05), the crown's radial burst, the score
rank plate's effect copy, and the full-combo / donderful letter glows.  Drawn
source-over, those textures show up as dark or grey patches.

- movie_export / clip_export record the placement's blend mode (`blend = 8` on a
  backdrop leaf, an 8th row value on a clip leaf; the root placement's mode is
  folded into its group), and bg_anim / clip_player / ending draw such leaves
  with blend = "additive".  Data re-exported; only the blend field changed.
- result_crown: the burst copies draw additively; the crown_loop shine sweep is a
  plain white polygon on the cabinet, so gleam frames 0..2 are white now instead
  of the atlas colour they were exported with.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 01:49:19 +08:00

98 lines
3.2 KiB
Lua

-- Generic replay of an exported cabinet backdrop movie (lower half of the screen).
--
-- Data: Scripts/background/bg_data/bg_anim/<name>.lua (generated by
-- scratchpad/lyric/movie_export.py): `shapes[c] = {w, h, ox, oy}` and `normal`, a
-- list of shape instances in depth order, each with the period of its own loop and
-- channels tx/ty/sx/sy/rot/a (one number when constant, else one value per frame;
-- a = 0 means not placed) plus an optional presence mask `on`/`on_period`.
-- `blend = 8` marks a leaf the cabinet draws with the add blend mode (lantern glows).
-- Textures: Graphics/background/bga_<name>/s<c>.png. The stage is 1920x540 and is
-- drawn at screen y 540; the same schema as the donbg band player.
local BGAnim = {}
BGAnim.__index = BGAnim
local FRAME_MS = 1000.0 / 60.0
local STAGE_Y = 540
local ONE = string.byte("1")
function BGAnim.available(name)
local ok, data = pcall(require, "background/bg_data/bg_anim/" .. name)
return ok and type(data) == "table" and data.normal ~= nil
end
function BGAnim.new(name, path)
local ok, data = pcall(require, "background/bg_data/bg_anim/" .. name)
if not ok or type(data) ~= "table" or not data.normal then return nil end
local self = setmetatable({}, BGAnim)
self.name = name
self.subset = "bga_" .. name
self.path = path or "background"
tex.load_folder(self.path, self.subset)
self.data = data
self.ids = {}
self.elapsed = 0
self.last_ms = nil
return self
end
function BGAnim:id_of(shape)
local id = self.ids[shape]
if id == nil then
id = tex.get_id(self.subset, "s" .. shape) or false
self.ids[shape] = id
end
return id or nil
end
function BGAnim:update(current_ms)
if self.last_ms then
local dt = current_ms - self.last_ms
if dt > 0 and dt < 500 then self.elapsed = self.elapsed + dt end
end
self.last_ms = current_ms
end
local function ch(v, i)
if type(v) == "number" then return v end
return v[i]
end
function BGAnim:draw(fade)
fade = fade or 1.0
if fade <= 0.002 then return end
local frame = math.floor(self.elapsed / FRAME_MS)
local list = self.data.normal
local shapes = self.data.shapes
for k = 1, #list do
local e = list[k]
local i = (frame % e.period) + 1
local a = ch(e.a, i)
if a > 0.002 and e.on then
if e.on:byte((frame % e.on_period) + 1) ~= ONE then a = 0 end
end
if a > 0.002 then
local s = shapes[e.shape]
local id = s and self:id_of(e.shape)
if id then
local sx, sy = ch(e.sx, i), ch(e.sy, i)
tex.draw_texture(id, {
x = ch(e.tx, i),
y = STAGE_Y + ch(e.ty, i),
x2 = s[1] * (sx - 1),
y2 = s[2] * (sy - 1),
origin = { s[3] * sx, s[4] * sy },
rotation = ch(e.rot, i),
fade = a * fade,
blend = (e.blend == 8) and "additive" or nil, -- cabinet add-blended glows
})
end
end
end
end
function BGAnim:destroy()
tex.unload_folder(self.path, self.subset)
end
return BGAnim