Song select: the course mark pops to its decided look once the course is locked in #20
No files matched your search
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"mark_0": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"white_0": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"mark_1": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"white_1": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"mark_2": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"white_2": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"mark_3": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"white_3": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"mark_4": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"white_4": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
@@ -263,6 +263,15 @@ function SongSelect.new()
|
||||
self._id_dot_star = tex.get_id("diff_select", "disable") -- 24x24 star for the dots
|
||||
self._id_guide_s = tex.get_id("diff_select", "diff_tower") -- 372x96 control_guide_s, 210-cell loop sheet (name reused)
|
||||
self._id_diff_mark = tex.get_id("diff_select", "diff_tower_shadow") -- 680x680 main_diff_mark 'wait' (alpha 154/256), frame = course (name reused)
|
||||
-- main_diff_mark 'course_decide_start': once the course is locked in the mark pops to its
|
||||
-- opaque look (mark_course over a white backing, a white copy flashing on top). Opaque
|
||||
-- 680x680 shapes of mark_course (course_1..5) and mark_course_white, origin = centre.
|
||||
tex.load_folder("song_select", "diff_mark_anim")
|
||||
self._id_mark, self._id_mark_w = {}, {}
|
||||
for i = DIFF_EASY, DIFF_URA do
|
||||
self._id_mark[i] = tex.get_id("diff_mark_anim", "mark_" .. i)
|
||||
self._id_mark_w[i] = tex.get_id("diff_mark_anim", "white_" .. i)
|
||||
end
|
||||
-- ROUND 4b: oni<->ura switch = CS/main_diff_board oni_main 'change_ura' / 'change_oni' (90 arcade frames,
|
||||
-- 1.5 s) baked every 2nd frame into 45 cells of 340x400 (origin 170,210 = card centre). Names reused
|
||||
-- (1p/2p_outline_half are vertical-path-only). The engine's own ura_switch is a transparent texture.
|
||||
@@ -278,6 +287,7 @@ function SongSelect.new()
|
||||
self._course_labels = {}
|
||||
self._chip_labels = {}
|
||||
self._mark_diff = {} -- per player: last cursor column for main_diff_mark (set by draw_selector)
|
||||
self._mark_decided = {} -- per player: { t0 = ms, course } once player:difficulty_decided()
|
||||
self._ura_prev = nil -- box.is_ura seen last frame (toggle detection; C++ flips it instantly)
|
||||
self._ura_anim = nil -- { t0 = ms, to_ura = bool } while the arcade change animation plays
|
||||
self._guide_labels = nil
|
||||
@@ -1593,17 +1603,68 @@ local DS_NEIRO_Y = 602
|
||||
-- board's left/right edge (QA `shots/select_c1/z_plum.png`, `select_c2/c2_03_p2_moved.png`).
|
||||
local DS_MARK_X = { [1] = 200, [2] = 1720 }
|
||||
local DS_MARK_Y = 408
|
||||
-- main_diff_mark 'course_decide_start' (frames 35..64, 60 fps), one row per frame:
|
||||
-- { mark alpha, mark y-scale, white alpha, white y-scale, white backing alpha }. The
|
||||
-- last row is the 'course_decide' hold: opaque mark on its white backing.
|
||||
local DS_MARK_DECIDE = {
|
||||
{ 0.5, 1, 0, 1, 0 },
|
||||
{ 0.5938, 1.0447, 0.1914, 1.0447, 0.1016 },
|
||||
{ 0.6797, 1.0847, 0.3594, 1.0847, 0.1992 },
|
||||
{ 0.7539, 1.12, 0.5117, 1.12, 0.3008 },
|
||||
{ 0.8203, 1.1506, 0.6406, 1.1506, 0.3984 },
|
||||
{ 0.875, 1.1765, 0.75, 1.1765, 0.5 },
|
||||
{ 0.9219, 1.1976, 0.8398, 1.1976, 0.6016 },
|
||||
{ 0.9531, 1.2141, 0.9102, 1.2141, 0.6992 },
|
||||
{ 0.9805, 1.2259, 0.9609, 1.2259, 0.8008 },
|
||||
{ 0.9961, 1.2329, 0.9883, 1.2329, 0.8984 },
|
||||
{ 1, 1.2353, 1, 1.2353, 1 },
|
||||
{ 1, 1.2229, 0.9961, 1.2346, 1 },
|
||||
{ 1, 1.2105, 0.9883, 1.2327, 1 },
|
||||
{ 1, 1.1981, 0.9766, 1.2294, 1 },
|
||||
{ 1, 1.1858, 0.957, 1.2248, 1 },
|
||||
{ 1, 1.1733, 0.9297, 1.219, 1 },
|
||||
{ 1, 1.161, 0.8984, 1.2118, 1 },
|
||||
{ 1, 1.1486, 0.8633, 1.2033, 1 },
|
||||
{ 1, 1.1362, 0.8242, 1.1936, 1 },
|
||||
{ 1, 1.1238, 0.7773, 1.1825, 1 },
|
||||
{ 1, 1.1114, 0.7227, 1.1701, 1 },
|
||||
{ 1, 1.0991, 0.6641, 1.1564, 1 },
|
||||
{ 1, 1.0867, 0.6016, 1.1414, 1 },
|
||||
{ 1, 1.0743, 0.5312, 1.1251, 1 },
|
||||
{ 1, 1.0619, 0.457, 1.1075, 1 },
|
||||
{ 1, 1.0495, 0.375, 1.0886, 1 },
|
||||
{ 1, 1.0371, 0.2891, 1.0684, 1 },
|
||||
{ 1, 1.0247, 0.1992, 1.0469, 1 },
|
||||
{ 1, 1.0124, 0.1016, 1.0241, 1 },
|
||||
{ 1, 1, 0, 1, 1 },
|
||||
}
|
||||
local DS_MARK_DECIDE_MS = 1000 / 60
|
||||
|
||||
function SongSelect:draw_diff_mark_decided(p, dec, fade)
|
||||
local f = math.floor((tex.get_current_ms() - dec.t0) / DS_MARK_DECIDE_MS) + 1
|
||||
local k = DS_MARK_DECIDE[math.min(f, #DS_MARK_DECIDE)]
|
||||
local id, id_w = self._id_mark[dec.course], self._id_mark_w[dec.course]
|
||||
local cx, cy = DS_MARK_X[p], DS_MARK_Y
|
||||
local function stretched(tid, a, sy)
|
||||
if a <= 0 then return end
|
||||
tex.draw_texture(tid, { x = cx, y = cy, y2 = 680 * (sy - 1), origin = { 340, 340 * sy }, fade = a * fade })
|
||||
end
|
||||
stretched(id_w, k[5], 1) -- mark_course_white_2: backing that makes the mark solid
|
||||
stretched(id, k[1], k[2]) -- mark_course
|
||||
stretched(id_w, k[3], k[4]) -- mark_course_white: the flash on top
|
||||
end
|
||||
|
||||
function SongSelect:draw_song_diff_select_bg(box)
|
||||
local fade = box.diff_fade_in.attribute
|
||||
if self._id_diff_mark then
|
||||
for p = 1, 2 do
|
||||
local d = self._mark_diff[p]
|
||||
if d and d >= DIFF_EASY and DS_MARK_X[p] then
|
||||
local dec = self._mark_decided[p]
|
||||
if dec and self._id_mark[dec.course] then
|
||||
self:draw_diff_mark_decided(p, dec, fade)
|
||||
elseif self._id_diff_mark and d and d >= DIFF_EASY and DS_MARK_X[p] then
|
||||
draw_centered(self._id_diff_mark, DS_MARK_X[p], DS_MARK_Y, 680, 680, { frame = d, fade = fade })
|
||||
end
|
||||
end
|
||||
end
|
||||
tex.draw_texture(self._id_backboard, { frame = box:genre_frame(), x = 960 - 636, y = 440 - 392, fade = fade })
|
||||
end
|
||||
|
||||
@@ -1825,6 +1886,16 @@ function SongSelect:draw_selector(player, is_half, fade_in, pass)
|
||||
local p = player:player_num()
|
||||
if under then
|
||||
self._mark_diff[p] = diff -- main_diff_mark course for draw_song_diff_select_bg (next frame)
|
||||
-- course locked in (engine binding, PR #162): start the decide pop once; cleared again
|
||||
-- when the engine resets the selection (course back / song change)
|
||||
local decided = diff >= DIFF_EASY and player.difficulty_decided and player:difficulty_decided()
|
||||
if decided then
|
||||
if not self._mark_decided[p] then
|
||||
self._mark_decided[p] = { t0 = tex.get_current_ms(), course = diff }
|
||||
end
|
||||
else
|
||||
self._mark_decided[p] = nil
|
||||
end
|
||||
end
|
||||
if fade_in < 1.0 then return end
|
||||
local mod_on = player:modifier_active()
|
||||
|
||||