forked from Yonokid/YataiDONNijiiro
279 lines
10 KiB
Lua
279 lines
10 KiB
Lua
Entry = {}
|
|
Entry.__index = Entry
|
|
|
|
function Entry.new()
|
|
local self = setmetatable({}, Entry)
|
|
__hss_entry_reset = true
|
|
tex.load_animations("entry")
|
|
|
|
self.bg_flicker = tex.get_animation(1, "entry")
|
|
self.side_select_fade = tex.get_animation(0, "entry")
|
|
self.bg_flicker:start()
|
|
|
|
self.text_cancel = text.create_text("entry_cancel", { 255, 255, 255, 255 }, { 40, 24, 12, 255 }, false, 3, 0)
|
|
self.text_credit_p = {
|
|
text.create_text("entry_credit_1p", { 0, 0, 0, 255 }, { 255, 255, 255, 255 }, false, 7.0 / tex.get_screen_scale(), 0),
|
|
text.create_text("entry_credit_2p", { 0, 0, 0, 255 }, { 255, 255, 255, 255 }, false, 7.0 / tex.get_screen_scale(), 0),
|
|
}
|
|
local CREDIT_BORDER = 7.0 / tex.get_screen_scale()
|
|
self.text_credit_msg = text.create_text("entry_credit_start", { 255, 255, 255, 255 }, { 0, 0, 0, 255 }, false, CREDIT_BORDER, 0)
|
|
self.text_credit_msg_hl = text.create_text("entry_credit_start", { 255, 255, 255, 255 }, { 255, 236, 67, 255 }, false, CREDIT_BORDER, 0)
|
|
|
|
self.bg_bg = tex.load_texture("entry/background/bg")
|
|
self.bg_tower = tex.load_texture("entry/background/tower")
|
|
self.bg_shops_center = tex.load_texture("entry/background/shops_center")
|
|
self.bg_people = tex.load_texture("entry/background/people")
|
|
self.bg_shops_left = tex.load_texture("entry/background/shops_left")
|
|
self.bg_shops_right = tex.load_texture("entry/background/shops_right")
|
|
self.bg_lights = tex.load_texture("entry/background/lights")
|
|
|
|
self.bg_street_lit = tex.load_texture("entry/background/street_lit")
|
|
self.bg_glow = tex.load_texture("entry/background/glow")
|
|
self.bg_twinkle = tex.load_texture("entry/background/twinkle")
|
|
self.bg_t0 = tex.get_current_ms()
|
|
|
|
self.cr_pill = tex.load_texture("entry/side_select/credit_pill")
|
|
self.cr_flash = tex.load_texture("entry/side_select/credit_flash")
|
|
self.cr_t0 = tex.get_current_ms()
|
|
self.cr_blink_t0 = self.cr_t0
|
|
self.cr_side = 1
|
|
self.cr_frame = 0
|
|
self.cr_seen_frame = nil
|
|
self.cr_decide_t0 = nil
|
|
self.cr_decide_row = nil
|
|
|
|
local arcade_cfg = tex.get_skin_config("entry_credit_arcade")
|
|
self.cr_arcade = (arcade_cfg ~= nil and (arcade_cfg.x or 0) >= 1)
|
|
self.cr_pending_decide = nil
|
|
self.global_player_entry = tex.load_texture("entry/global/player_entry")
|
|
|
|
self.guide = tex.load_texture("global/indicator/background")
|
|
self.guide_t0 = self.cr_t0
|
|
self.any_joined = false
|
|
|
|
return self
|
|
end
|
|
|
|
local GUIDE_STEP = 2
|
|
local GUIDE_SPLIT = math.floor(420 / GUIDE_STEP)
|
|
local GUIDE_END = math.floor(650 / GUIDE_STEP)
|
|
|
|
function Entry:draw_control_guide()
|
|
if not self.guide then return end
|
|
if self.any_joined then return end
|
|
local n = GUIDE_END - GUIDE_SPLIT
|
|
local f = GUIDE_SPLIT + math.floor((tex.get_current_ms() - self.guide_t0) * 0.06 / GUIDE_STEP) % n
|
|
tex.draw_texture(self.guide, { frame = f, x = 0, y = 0 })
|
|
end
|
|
|
|
function Entry:update(current_ms)
|
|
self.bg_flicker:update(current_ms)
|
|
self.side_select_fade:update(current_ms)
|
|
self.cr_frame = (self.cr_frame or 0) + 1
|
|
end
|
|
|
|
function Entry:start_side_select()
|
|
self.side_select_fade:start()
|
|
self:restart_credit()
|
|
end
|
|
|
|
function Entry:restart_side_select()
|
|
self.side_select_fade:restart()
|
|
self:restart_credit()
|
|
end
|
|
|
|
function Entry:restart_credit()
|
|
local now = tex.get_current_ms()
|
|
self.cr_t0 = now
|
|
self.cr_blink_t0 = now
|
|
self.cr_side = 1
|
|
self.cr_decide_t0 = nil
|
|
self.cr_decide_row = nil
|
|
self.cr_seen_frame = nil
|
|
self.cr_pending_decide = nil
|
|
end
|
|
|
|
function Entry:get_side_select_fade()
|
|
return self.side_select_fade.attribute
|
|
end
|
|
|
|
local _ea_ok, entry_anim = pcall(require, "anim/sampler")
|
|
if not _ea_ok then entry_anim = { safe = function()
|
|
local n = {}
|
|
n.at = function() return nil end; n.get = function() return nil end
|
|
n.label = function() return nil end; n.has = function() return false end
|
|
n.first = function() return 0 end; n.last = function() return 0 end
|
|
return n
|
|
end } end
|
|
local EBG = entry_anim.safe("anim/entry_bg")
|
|
local CR = entry_anim.safe("anim/credit_row")
|
|
local CF = entry_anim.safe("anim/credit_fade")
|
|
|
|
local CREDIT_CX = 960
|
|
local ROW_CY = { 432 + 72, 432 + 248 }
|
|
local LABEL_INK_X = CREDIT_CX - 443
|
|
local MSG_INK_X = CREDIT_CX + 190
|
|
local TEXT_INK_DY = 0.5
|
|
local PAD5 = 9
|
|
local PAD_LABEL = 2
|
|
local CANCEL_CX, CANCEL_CY = 960, 838
|
|
local ROW_LOOP_F0, ROW_LOOP_LEN = 5, 120
|
|
local DIM_UNSELECTED = 0.72
|
|
local DECIDE_FLASH_F = 24
|
|
local EBG_LEN = math.max(1, EBG:last() - EBG:first() + 1)
|
|
local BG_LIT_END = 19
|
|
local ENTRY_TWINKLES = {
|
|
{ 0, 0, "#11@1/#5@0/#3@0" },
|
|
{ 1, 0, "#11@1/#9@2/#3@0" },
|
|
{ 2, 1, "#11@1/#8@1/#6@0" },
|
|
{ 3, 1, "#11@1/#10@3/#6@0" },
|
|
}
|
|
|
|
function Entry:draw_background()
|
|
local f = ((tex.get_current_ms() - self.bg_t0) * 0.06) % EBG_LEN -- arcade frames @ 60 fps
|
|
|
|
tex.draw_texture(self.bg_bg)
|
|
|
|
if self.bg_twinkle then
|
|
for i = 1, #ENTRY_TWINKLES do
|
|
local tw = ENTRY_TWINKLES[i]
|
|
local s, a = EBG:at(tw[3], f)
|
|
if a and a > 0.002 then
|
|
tex.draw_texture(self.bg_twinkle,
|
|
{ index = tw[1], frame = tw[2], center = true, scale = s, fade = a })
|
|
end
|
|
end
|
|
end
|
|
|
|
if self.bg_glow then
|
|
local ga = EBG:get("#16@3/#14@0", f, "a") or 1.0
|
|
for i = 0, 3 do
|
|
tex.draw_texture(self.bg_glow, { index = i, frame = i, fade = ga })
|
|
end
|
|
end
|
|
|
|
if self.bg_street_lit then
|
|
local lf = (tex.get_current_ms() - self.bg_t0) * 0.06 -- monotonic, NOT wrapped
|
|
if lf < BG_LIT_END then
|
|
local la = EBG:get("#17@7", lf, "a") or 0.0
|
|
if la > 0.002 then tex.draw_texture(self.bg_street_lit, { fade = la }) end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Entry:draw_side_select()
|
|
end
|
|
|
|
-- One player row. `row` is 1 (upper, 1P) or 2 (lower, 2P); `f` is the row timeline frame.
|
|
function Entry:draw_credit_row(row, f, a)
|
|
if a <= 0.002 then return end
|
|
tex.draw_texture(self.cr_pill, { index = row - 1, fade = a })
|
|
|
|
local cy = ROW_CY[row]
|
|
local lbl = self.text_credit_p[row]
|
|
if lbl then
|
|
lbl:draw({ x = LABEL_INK_X - PAD_LABEL, y = cy + TEXT_INK_DY - lbl.height / 2, fade = a })
|
|
end
|
|
|
|
-- fill alpha and the outline copy colour multiply, both read from the export
|
|
local ma = CR:get("text_message_instance", f, "a") or 1
|
|
local _, cr = CR:at("text_message_instance_2", f)
|
|
local yellow = (cr and cr / 256.0) or 0.0 -- 0 = black outline, 1 = (256,236,67)
|
|
local msg = self.text_credit_msg
|
|
if msg and ma > 0.002 then
|
|
local x = MSG_INK_X - msg.width / 2
|
|
local y = cy + TEXT_INK_DY - msg.height / 2
|
|
msg:draw({ x = x, y = y, fade = a * ma })
|
|
if yellow > 0.001 and self.text_credit_msg_hl then
|
|
self.text_credit_msg_hl:draw({ x = x, y = y, fade = a * ma * yellow })
|
|
end
|
|
end
|
|
end
|
|
|
|
function Entry:draw_credit(a, sel, blink_f, flash_row, flash_a, loop_rows)
|
|
for row = 1, 2 do
|
|
local armed = (row == sel)
|
|
local ra = (sel == nil or sel == 0 or armed) and a or (a * DIM_UNSELECTED)
|
|
local rf = (armed or loop_rows) and blink_f or ROW_LOOP_F0
|
|
self:draw_credit_row(row, rf, ra)
|
|
end
|
|
local now = tex.get_current_ms()
|
|
if sel and sel > 0 then
|
|
local pulse = 0.08 + 0.10 * math.sin((now - self.cr_blink_t0) * 0.006)
|
|
tex.draw_texture(self.cr_flash, { index = sel - 1, fade = a * pulse })
|
|
end
|
|
|
|
|
|
if flash_row and flash_a and flash_a > 0.002 then
|
|
tex.draw_texture(self.cr_flash, { index = flash_row - 1, fade = a * flash_a })
|
|
end
|
|
end
|
|
|
|
function Entry:draw_side_select_buttons(side)
|
|
local now = tex.get_current_ms()
|
|
__hss_entry_guide = { ms = now, phase = "side" }
|
|
if side ~= self.cr_side then
|
|
self.cr_side = side
|
|
self.cr_blink_t0 = now -- a newly armed row restarts its attract cycle
|
|
end
|
|
self.cr_seen_frame = self.cr_frame
|
|
self.cr_decide_t0 = nil
|
|
|
|
local fi = math.min(15, 5 + (now - self.cr_t0) * 0.06)
|
|
local a = CF:get("player1_text_instance", fi, "a") or 1.0
|
|
|
|
local sel = (not self.cr_arcade)
|
|
and ((side == 0 and 1) or (side == 2 and 2) or 0)
|
|
or nil
|
|
local blink_f = ROW_LOOP_F0 + ((now - self.cr_blink_t0) * 0.06) % ROW_LOOP_LEN
|
|
self:draw_credit(a, sel, blink_f, nil, nil, self.cr_arcade)
|
|
-- depth 28 > depth 23: the guide sits OVER the credit rows.
|
|
self:draw_control_guide()
|
|
YD_ENTRY_CREDIT_MS = now
|
|
end
|
|
|
|
function Entry:draw_footer(p1_joined, p2_joined)
|
|
YD_ENTRY_BOTH_JOINED = (p1_joined == true and p2_joined == true)
|
|
self.any_joined = (p1_joined == true or p2_joined == true)
|
|
end
|
|
|
|
function Entry:draw_player_entry()
|
|
tex.draw_texture(self.global_player_entry)
|
|
self:draw_credit_decide()
|
|
end
|
|
|
|
function Entry:decide_side_select(side)
|
|
self.cr_pending_decide = (side == 2) and 2 or 1
|
|
end
|
|
|
|
function Entry:draw_credit_decide()
|
|
local now = tex.get_current_ms()
|
|
if self.cr_seen_frame ~= nil and self.cr_decide_t0 == nil then
|
|
if self.cr_frame > self.cr_seen_frame then
|
|
self.cr_seen_frame = nil
|
|
if self.cr_pending_decide then
|
|
-- arcade model: the engine told us which row entered
|
|
self.cr_decide_t0 = now
|
|
self.cr_decide_row = self.cr_pending_decide
|
|
self.cr_pending_decide = nil
|
|
elseif self.cr_side == 0 or self.cr_side == 2 then
|
|
-- cursor model: side 1 is 「つかわない」 -- cancelled, not decided.
|
|
self.cr_decide_t0 = now
|
|
self.cr_decide_row = (self.cr_side == 0) and 1 or 2
|
|
end
|
|
end
|
|
end
|
|
if self.cr_decide_t0 == nil then return end
|
|
|
|
local t = (now - self.cr_decide_t0) * 0.06 -- frames since decide
|
|
local flash_a = CR:get("#8@4", 125 + math.min(t, DECIDE_FLASH_F), "a") or 0
|
|
local fade_f = 16 + math.max(0, t - (DECIDE_FLASH_F + 1)) -- fade_out starts after
|
|
local a = CF:get("player1_text_instance", math.min(fade_f, 35), "a") or 0
|
|
if a <= 0.002 then
|
|
self.cr_decide_t0 = nil
|
|
return
|
|
end
|
|
self:draw_credit(a, nil, ROW_LOOP_F0, self.cr_decide_row, flash_a)
|
|
YD_ENTRY_CREDIT_MS = now
|
|
end
|