-- Escena 'logo' — splash JAILGAMES amb animacio. -- -- Tres fases: -- ENTRADA -> les 9 lletres entren des de direccions diferents -- (esquerra, dreta, dalt, baix), esglaonades, amb easings -- variats. Una vegada al lloc, queden quietes. -- ESTABLE -> 4 s totalment quiet, logo blanc ple. -- FADE_OUT -> rampa combinada char+paleta de 8 nivells: -- blanc -> groc -> rosa -> vermell -> magenta -> blau -- -> gris fosc -> negre, mentre el char passa de BLOCK -- -> SHADE_75 -> SHADE_50 -> SHADE_25 -> espai. -- -- Premer tecla durant ENTRADA o ESTABLE salta al fade. Quan acaba el -- fade, salta a 'titol'. -- -- Notes sobre el fade CGA: no recorrem els 16 indexs en ordre lineal. -- Triem una rampa tematica (warm -> cool -> dark) que es el patro -- classic d'apagada de monitor CRT, combinada amb difuminat del char -- per a mes pasos perceptuals (l'ull veu el conjunt com una rampa -- d'intensitat continua). local M = {} local logo = dofile("pepe_pintor_dx/data/logo.lua") local easing = dofile("pepe_pintor_dx/lib/easing.lua") -- Timings local T_PREVI = 1.0 -- pantalla negra abans que comencin a entrar local T_FALL = 0.65 -- durada de l'entrada d'una lletra local T_DELAY = 0.09 -- delay entre lletres consecutives local T_ESTABLE = 2.0 local T_FADE = 0.4 local T_POST = 1.0 -- pantalla negra despres del fade, abans de saltar local FASE_ENTRADA = 1 local FASE_ESTABLE = 2 local FASE_FADE_OUT = 3 local FASE_POST = 4 -- Lletres del logo com a rangs de columnes del bitmap 35-wide (1-based). local SEGMENTS = { { c0 = 1, c1 = 3, nom = "J" }, { c0 = 5, c1 = 7, nom = "A" }, { c0 = 9, c1 = 9, nom = "I" }, { c0 = 11, c1 = 13, nom = "L" }, { c0 = 15, c1 = 17, nom = "G" }, { c0 = 19, c1 = 21, nom = "A" }, { c0 = 23, c1 = 27, nom = "M" }, { c0 = 29, c1 = 31, nom = "E" }, { c0 = 33, c1 = 35, nom = "S" }, } -- Origen i easing per lletra. (dx, dy) son l'offset inicial respecte -- a la posicio final. fn es l'easing a aplicar al progres [0,1]. -- Esquerra del logo (1-3) ve de l'esquerra; centre (4-6) ve vertical; -- dreta (7-9) ve de la dreta. Simetric pero no monoton. local ORIGENS = {} local function inicialitza_origens() ORIGENS = { { dx = -32, dy = 0, fn = easing.outCubic }, -- J <- { dx = -28, dy = 0, fn = easing.outCubic }, -- A <- { dx = -24, dy = 0, fn = easing.outCubic }, -- I <- { dx = 0, dy = -18, fn = easing.outBounce }, -- L v { dx = 0, dy = 20, fn = easing.outBack }, -- G ^ { dx = 0, dy = -18, fn = easing.outBounce }, -- A v { dx = 24, dy = 0, fn = easing.outCubic }, -- M -> { dx = 28, dy = 0, fn = easing.outCubic }, -- E -> { dx = 32, dy = 0, fn = easing.outCubic }, -- S -> } end -- Rampa de fade: 8 nivells. Construida a entra() perque depen de -- glyphs.* (no disponibles al carregar el modul). local RAMPA local NIVELL_MAX = 7 local function inicialitza_rampa(glyphs) RAMPA = { [7] = { codi = glyphs.BLOCK, ink = COLOR_WHITE }, [6] = { codi = glyphs.BLOCK, ink = COLOR_YELLOW }, [5] = { codi = glyphs.SHADE_75, ink = COLOR_LIGHT_RED }, [4] = { codi = glyphs.SHADE_75, ink = COLOR_RED }, [3] = { codi = glyphs.SHADE_50, ink = COLOR_MAGENTA }, [2] = { codi = glyphs.SHADE_50, ink = COLOR_BLUE }, [1] = { codi = glyphs.SHADE_25, ink = COLOR_BLUE }, [0] = { codi = 32, ink = COLOR_BLACK }, } end local manager, input, glyphs local lletres = {} local fase = FASE_ENTRADA local temps = 0 local nivell_actual = NIVELL_MAX local total_entrada = 0 local function construeix_lletres() lletres = {} for i, seg in ipairs(SEGMENTS) do local px = {} for r = 1, logo.height do local fila = logo.files[r] for c = seg.c0, seg.c1 do if string.sub(fila, c, c) == "#" then px[#px + 1] = { rx = c - seg.c0, ry = r - 1 } end end end local origen = ORIGENS[i] lletres[i] = { base_x = logo.origen_x + (seg.c0 - 1), base_y = logo.origen_y, pixels = px, ox = origen.dx, oy = origen.dy, dx = origen.dx, dy = origen.dy, fn = origen.fn, delay = T_PREVI + (i - 1) * T_DELAY, arribada = false, -- una vegada true, ja no toquem dx/dy } end total_entrada = T_PREVI + (#SEGMENTS - 1) * T_DELAY + T_FALL end function M.entra(servicis, _args) manager = servicis.manager input = servicis.input glyphs = servicis.glyphs fase = FASE_ENTRADA temps = 0 nivell_actual = NIVELL_MAX inicialitza_origens() inicialitza_rampa(glyphs) construeix_lletres() color(COLOR_WHITE, COLOR_BLACK) cls() end local function salta_a_fade() fase = FASE_FADE_OUT temps = 0 -- forcem que totes les lletres estiguin a casa, no es mouen mes for _, l in ipairs(lletres) do l.dx = 0 l.dy = 0 l.arribada = true end end local function update_entrada() local totes_acabades = true for _, l in ipairs(lletres) do if not l.arribada then local tl = temps - l.delay if tl < 0 then l.dx, l.dy = l.ox, l.oy totes_acabades = false elseif tl < T_FALL then local p = tl / T_FALL local e = l.fn(p) l.dx = l.ox * (1 - e) l.dy = l.oy * (1 - e) totes_acabades = false else l.dx, l.dy = 0, 0 l.arribada = true end end end if totes_acabades then fase = FASE_ESTABLE temps = 0 end end local function update_estable() -- intencionadament buit — lletres quietes if temps >= T_ESTABLE then salta_a_fade() end end local function update_fade() local p = temps / T_FADE if p >= 1 then nivell_actual = 0 fase = FASE_POST temps = 0 return end -- Mapa el progres [0,1] al nivell [NIVELL_MAX..0] de la rampa. nivell_actual = math.floor(NIVELL_MAX * (1 - p) + 0.5) if nivell_actual < 0 then nivell_actual = 0 end end local function update_post() if temps >= T_POST then manager.canvia("titol") end end function M.update(dt) temps = temps + dt if (fase == FASE_ENTRADA or fase == FASE_ESTABLE) and input.qualsevol_tecla() then salta_a_fade() return end if fase == FASE_ENTRADA then update_entrada() elseif fase == FASE_ESTABLE then update_estable() elseif fase == FASE_FADE_OUT then update_fade() else update_post() end end function M.draw() color(COLOR_WHITE, COLOR_BLACK) cls() local nivell if fase == FASE_FADE_OUT or fase == FASE_POST then nivell = nivell_actual else nivell = NIVELL_MAX end if nivell <= 0 then return end local conf = RAMPA[nivell] color(conf.ink, COLOR_BLACK) for _, l in ipairs(lletres) do local ox = math.floor(l.dx + 0.5) local oy = math.floor(l.dy + 0.5) for _, p in ipairs(l.pixels) do local x = l.base_x + p.rx + ox local y = l.base_y + p.ry + oy if x >= 0 and x < 40 and y >= 0 and y < 30 then print(chr(conf.codi), x, y) end end end end return M