162 lines
7.3 KiB
Lua
162 lines
7.3 KiB
Lua
-- Default song-select player UI: the difficulty cursor under the wheel and the difficulty banner
|
|
-- behind it. SongSelectPlayer keeps the state (selection, animations); this draws it.
|
|
--
|
|
-- Not a SongSelect class: SongSelectScript installs draw_selector / draw_background_diffs from here
|
|
-- when the skin's own SongSelect does not define them (or its hook returns false).
|
|
|
|
local M = {}
|
|
|
|
local S = tex.get_screen_scale()
|
|
|
|
local SELECTOR_OFFSET = 115 * S -- distance between the course columns
|
|
local BALLOON_OFFSET_1 = -220 * S -- balloon shift on the back / neiro slots
|
|
local BALLOON_OFFSET_2 = 70 * S -- distance between the back / neiro slots
|
|
local BG_DIFF_P2_OFFSET = 1025 * S
|
|
local DIFF_TEXT_X, DIFF_TEXT_Y, DIFF_TEXT_FONT = 125 * S, 203 * S, math.floor(61 * S)
|
|
|
|
local DIFF_NEIRO, DIFF_BACK, DIFF_EASY, DIFF_ONI, DIFF_URA = -1, -3, 0, 3, 4
|
|
|
|
local function diff_select_sprite(name)
|
|
return tex.get_texture("song_select/diff_select/" .. name)
|
|
end
|
|
|
|
-- pass 0 is drawn under the wheel by the skins that split the cursor; the default draws it once, over
|
|
function M.draw_selector(_self, player, is_half, fade_in, pass)
|
|
if pass ~= 1 or fade_in < 1.0 then return end
|
|
local st = player:selector_state()
|
|
local fade = st.panel and 0.5 or fade_in
|
|
local direction = st.move_right and 1 or -1
|
|
local selected, prev = st.selected, st.prev
|
|
|
|
local p = player:player_num() .. "p"
|
|
local suffix = is_half and "_half" or ""
|
|
local balloon = diff_select_sprite(p .. "_balloon" .. suffix)
|
|
local outline = diff_select_sprite(p .. "_outline" .. suffix)
|
|
local outline_back = diff_select_sprite(p .. "_outline_back" .. suffix)
|
|
|
|
if selected <= DIFF_NEIRO or prev == DIFF_NEIRO then
|
|
if prev == DIFF_NEIRO and selected >= DIFF_EASY then
|
|
if not st.move2_done then
|
|
local bx = ((prev + 3) * BALLOON_OFFSET_2) + BALLOON_OFFSET_1 + st.move2 * direction
|
|
tex.draw_texture(balloon, { x = bx, fade = fade })
|
|
tex.draw_texture(outline_back, { x = ((prev + 3) * BALLOON_OFFSET_2) + st.move2 * direction })
|
|
else
|
|
local difficulty = math.min(DIFF_ONI, selected)
|
|
tex.draw_texture(balloon, { x = difficulty * SELECTOR_OFFSET, fade = fade })
|
|
tex.draw_texture(outline, { x = difficulty * SELECTOR_OFFSET })
|
|
end
|
|
elseif not st.move2_done then
|
|
if selected ~= DIFF_BACK then
|
|
tex.draw_texture(outline_back, { x = ((prev + 3) * BALLOON_OFFSET_2) + st.move2 * direction })
|
|
local bx = ((prev + 3) * BALLOON_OFFSET_2) + BALLOON_OFFSET_1 + st.move2 * direction
|
|
tex.draw_texture(balloon, { x = bx, fade = fade })
|
|
else
|
|
tex.draw_texture(outline_back, { x = ((prev + 3) * BALLOON_OFFSET_2) + st.move2 * direction, fade = fade })
|
|
end
|
|
else
|
|
if selected ~= DIFF_BACK then
|
|
tex.draw_texture(outline_back, { x = (selected + 3) * BALLOON_OFFSET_2 })
|
|
tex.draw_texture(balloon, { x = ((selected + 3) * BALLOON_OFFSET_2) + BALLOON_OFFSET_1, fade = fade })
|
|
else
|
|
tex.draw_texture(outline_back, { x = (selected + 3) * BALLOON_OFFSET_2, fade = fade })
|
|
end
|
|
end
|
|
else
|
|
if prev == DIFF_NEIRO then return end
|
|
if not st.move1_done then
|
|
local difficulty = math.min(DIFF_ONI, prev)
|
|
local bx = (difficulty * SELECTOR_OFFSET) + st.move1 * direction
|
|
tex.draw_texture(balloon, { x = bx, fade = fade })
|
|
tex.draw_texture(outline, { x = bx })
|
|
else
|
|
local difficulty = math.min(DIFF_ONI, selected)
|
|
tex.draw_texture(balloon, { x = difficulty * SELECTOR_OFFSET, fade = fade })
|
|
tex.draw_texture(outline, { x = difficulty * SELECTOR_OFFSET })
|
|
end
|
|
end
|
|
end
|
|
|
|
-- the four banner labels (easy .. oni), rebuilt when the language changes
|
|
local labels, labels_lang
|
|
|
|
local function diff_label(index)
|
|
local lang = tex.language()
|
|
if lang ~= labels_lang then
|
|
labels = {}
|
|
for i, key in ipairs({ "diff_tower_easy", "diff_tower_normal", "diff_tower_hard", "diff_tower_oni" }) do
|
|
labels[i] = text.create_raw_text(tex.skin_text(key), DIFF_TEXT_FONT,
|
|
{ 255, 255, 255, 255 }, { 0, 0, 0, 255 }, false, 5.0, 2.0)
|
|
end
|
|
labels_lang = lang
|
|
end
|
|
return labels[index + 1]
|
|
end
|
|
|
|
local function global_sprite(name)
|
|
return tex.get_texture("song_select/global/" .. name)
|
|
end
|
|
|
|
-- called only while a song is selected and a course is chosen
|
|
function M.draw_background_diffs(_self, player)
|
|
local st = player:bg_diff_state()
|
|
local x_offset = (player:player_num() == 2) and BG_DIFF_P2_OFFSET or 0
|
|
local bounce_y, bounce_y2 = -st.bounce, st.bounce
|
|
local diff_frame = math.min(DIFF_URA, st.selected)
|
|
local diff_frame_oni = math.min(DIFF_ONI, st.selected)
|
|
|
|
tex.draw_texture(global_sprite("background_diff"),
|
|
{ frame = diff_frame, x = x_offset, y = bounce_y, y2 = bounce_y2, fade = math.min(0.5, st.fade_in) })
|
|
if st.highlight_on then
|
|
tex.draw_texture(global_sprite("background_diff"),
|
|
{ frame = diff_frame, x = x_offset, y = bounce_y, y2 = bounce_y2 })
|
|
end
|
|
tex.draw_texture(global_sprite("background_diff_highlight"),
|
|
{ frame = diff_frame_oni, x = x_offset, fade = st.highlight_fade })
|
|
tex.draw_texture(global_sprite("bg_diff_text_bg"),
|
|
{ scale = st.text_resize, center = true, x = x_offset, fade = math.min(0.5, st.text_fade_in) })
|
|
|
|
local label = diff_label(diff_frame_oni)
|
|
label:draw({
|
|
scale = st.text_resize,
|
|
center = true,
|
|
x = DIFF_TEXT_X + x_offset - label.width / 2.0,
|
|
y = DIFF_TEXT_Y - label.height / 2.0,
|
|
fade = st.text_fade_in,
|
|
})
|
|
end
|
|
|
|
-- The search overlay. A skin's SongSelect can set `search_box_layout = { x, y, width, height }` (pixels,
|
|
-- x/y offset from the screen centre) to move the text pill without drawing the overlay itself.
|
|
local search_text, search_text_str
|
|
|
|
function M.draw_search_box(self, box)
|
|
local sw, sh = tex.get_screen_width(), tex.get_screen_height()
|
|
tex.draw_rect(0, 0, sw, sh, 0, 0, 0, 153)
|
|
local background = tex.get_texture("song_select/diff_sort/background")
|
|
local info = tex.get_texture_info("diff_sort", "background")
|
|
if not background or not info then return end
|
|
|
|
local cx, cy = sw / 2.0, sh / 2.0
|
|
tex.draw_texture(background, {
|
|
scale = box.bg_resize, center = true,
|
|
x = cx - (info.width / 2 + info.x[1]), y = cy - (info.height / 2 + info.y[1]),
|
|
})
|
|
|
|
local layout = self.search_box_layout or { x = 0, y = 0, width = 400 * S, height = 60 * S }
|
|
local w, h = layout.width, layout.height
|
|
local x, y = cx - w / 2 + layout.x, cy - h / 2 + layout.y
|
|
local alpha = math.floor(255 * box.fade_in)
|
|
tex.draw_rounded_rect(x, y, w, h, h > 0 and math.min(40 / h, 1) or 0,
|
|
{ 255, 255, 255, alpha }, 3, { 119, 26, 45, alpha })
|
|
|
|
if box.search == "" then return end
|
|
if box.search ~= search_text_str then
|
|
search_text = text.create_raw_text(box.search, math.floor(30 * S),
|
|
{ 0, 0, 0, 255 }, { 0, 0, 0, 0 }, false, 0, 1.0)
|
|
search_text_str = box.search
|
|
end
|
|
search_text:draw({ x = x + w / 2 - search_text.width / 2, y = y + h / 2 - search_text.height / 2 })
|
|
end
|
|
|
|
return M
|