Files
gen1recomp/src/import/LauncherThemeVideo.lua
T
bryanthaboi d8bce958ec spooky
2026-09-29 11:14:08 -04:00

79 lines
2.4 KiB
Lua

-- Quiet, black-keyed video layer behind the launcher UI.
local LauncherThemeVideo = {}
LauncherThemeVideo.__index = LauncherThemeVideo
local VIDEO_PATH = "assets/launcher/current_theme_vid.ogv"
function LauncherThemeVideo.new()
local self = setmetatable({}, LauncherThemeVideo)
local ok, err = pcall(function()
self.video = love.graphics.newVideo(VIDEO_PATH, { audio = false })
self.video:setFilter("linear", "linear")
local width, height = self.video:getDimensions()
self.canvas = love.graphics.newCanvas(width, height)
self.canvas:setFilter("linear", "linear")
self.shader = love.graphics.newShader([[
vec4 effect(vec4 color, Image texture, vec2 uv, vec2 screen) {
vec4 pixel = Texel(texture, uv);
float brightness = max(pixel.r, max(pixel.g, pixel.b));
float coverage = smoothstep(0.012, 0.10, brightness);
float gray = dot(pixel.rgb, vec3(0.299, 0.587, 0.114));
vec3 muted = mix(vec3(gray), pixel.rgb, 0.12);
return vec4(muted, pixel.a * coverage * 0.12) * color;
}
]])
self.video:play()
end)
if not ok then
self:release()
print("[launcher theme video] unavailable: " .. tostring(err))
return nil
end
return self
end
function LauncherThemeVideo:update()
-- LÖVE's Theora stream does not expose a reliable loop flag on every target.
-- Rewind after each pass so this stays portable across desktop and mobile.
if self.video and not self.video:isPlaying() then
self.video:rewind()
self.video:play()
end
end
function LauncherThemeVideo:draw()
local g = love.graphics
local width, height = g.getDimensions()
local vw, vh = self.video:getDimensions()
g.push("all")
g.origin()
g.setScissor()
g.setShader()
g.setBlendMode("alpha", "alphamultiply")
-- LÖVE Video exposes YUV planes; convert through RGB before black-keying.
local target = g.getCanvas()
g.setCanvas(self.canvas)
g.clear(0, 0, 0, 0)
g.setColor(1, 1, 1, 1)
g.draw(self.video, 0, 0)
g.setCanvas(target)
local scale = math.max(width / vw, height / vh)
g.setShader(self.shader)
g.draw(self.canvas, (width - vw * scale) / 2,
(height - vh * scale) / 2, 0, scale, scale)
g.pop()
end
function LauncherThemeVideo:release()
if self.video then self.video:pause() end
for _, key in ipairs({ "video", "canvas", "shader" }) do
local resource = self[key]
if resource then resource:release(); self[key] = nil end
end
end
return LauncherThemeVideo