diff --git a/Graphics/song_select/diff_mark_anim/mark_0.png b/Graphics/song_select/diff_mark_anim/mark_0.png new file mode 100644 index 0000000..c9804dd Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/mark_0.png differ diff --git a/Graphics/song_select/diff_mark_anim/mark_1.png b/Graphics/song_select/diff_mark_anim/mark_1.png new file mode 100644 index 0000000..ef0d48c Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/mark_1.png differ diff --git a/Graphics/song_select/diff_mark_anim/mark_2.png b/Graphics/song_select/diff_mark_anim/mark_2.png new file mode 100644 index 0000000..37b2c78 Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/mark_2.png differ diff --git a/Graphics/song_select/diff_mark_anim/mark_3.png b/Graphics/song_select/diff_mark_anim/mark_3.png new file mode 100644 index 0000000..b0a1848 Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/mark_3.png differ diff --git a/Graphics/song_select/diff_mark_anim/mark_4.png b/Graphics/song_select/diff_mark_anim/mark_4.png new file mode 100644 index 0000000..acaaf06 Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/mark_4.png differ diff --git a/Graphics/song_select/diff_mark_anim/texture.json b/Graphics/song_select/diff_mark_anim/texture.json new file mode 100644 index 0000000..97ec661 --- /dev/null +++ b/Graphics/song_select/diff_mark_anim/texture.json @@ -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 + } +} \ No newline at end of file diff --git a/Graphics/song_select/diff_mark_anim/white_0.png b/Graphics/song_select/diff_mark_anim/white_0.png new file mode 100644 index 0000000..cfb3943 Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/white_0.png differ diff --git a/Graphics/song_select/diff_mark_anim/white_1.png b/Graphics/song_select/diff_mark_anim/white_1.png new file mode 100644 index 0000000..9233a35 Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/white_1.png differ diff --git a/Graphics/song_select/diff_mark_anim/white_2.png b/Graphics/song_select/diff_mark_anim/white_2.png new file mode 100644 index 0000000..862ee0c Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/white_2.png differ diff --git a/Graphics/song_select/diff_mark_anim/white_3.png b/Graphics/song_select/diff_mark_anim/white_3.png new file mode 100644 index 0000000..d89a515 Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/white_3.png differ diff --git a/Graphics/song_select/diff_mark_anim/white_4.png b/Graphics/song_select/diff_mark_anim/white_4.png new file mode 100644 index 0000000..d89a515 Binary files /dev/null and b/Graphics/song_select/diff_mark_anim/white_4.png differ diff --git a/Scripts/song_select/song_select.lua b/Scripts/song_select/song_select.lua index 6973b7a..d280ee5 100644 --- a/Scripts/song_select/song_select.lua +++ b/Scripts/song_select/song_select.lua @@ -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,15 +1603,66 @@ 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 - draw_centered(self._id_diff_mark, DS_MARK_X[p], DS_MARK_Y, 680, 680, { frame = d, fade = fade }) - end + for p = 1, 2 do + local d = self._mark_diff[p] + 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 tex.draw_texture(self._id_backboard, { frame = box:genre_frame(), x = 960 - 636, y = 440 - 392, fade = fade }) @@ -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()