Files
2026-10-01 14:52:38 -04:00

113 lines
4.3 KiB
Lua

-- SongSelectState constants (must match enums.h)
local STATE_BROWSING = 0
local STATE_SONG_SELECTED = 1
local STATE_DIFF_SORTING = 2
local STATE_SEARCHING = 3
local STATE_DAN_SELECTED = 4
SongSelect = {}
SongSelect.__index = SongSelect
-- The wheel box drawing (BaseBox/YellowBox/SongBox/FolderBox/BackBox) lives in
-- file_navigator/, mirroring src/objects/song_select/file_navigator/. Each module adds
-- its draw_* methods onto SongSelect as a side effect of being required.
require("song_select/file_navigator/box_base")
require("song_select/file_navigator/box_song")
require("song_select/file_navigator/box_folder")
require("song_select/file_navigator/box_back")
require("song_select/file_navigator/genre_bg")
local base = require("song_select/file_navigator/box_base")
function SongSelect.new()
local self = setmetatable({}, SongSelect)
base.reset_yellow_box()
tex.load_folder("song_select", "global")
tex.load_folder("song_select", "box")
tex.load_folder("song_select", "yellow_box")
tex.load_folder("song_select", "diff_select")
-- Animations (IDs from song_select/animation.json)
self.text_fade_in = tex.get_animation(4) -- fade in/out the top-left label text
self.blue_arrow_fade = tex.get_animation(29) -- blue arrow opacity pulse
self.blue_arrow_move = tex.get_animation(30) -- blue arrow horizontal drift
self.blue_arrow_fade:start()
self.blue_arrow_move:start()
self.text_fade_in:start()
-- Cached texture IDs
self._id_footer = tex.get_texture("song_select/global/footer") or 0
self._id_arrow = tex.get_texture("song_select/global/arrow") or 0
self._id_song_num_bg = tex.get_texture("song_select/global/song_num_bg") or 0
self._id_song_select = tex.get_texture("song_select/global/song_select") or 0
self._id_difficulty_select = tex.get_texture("song_select/global/difficulty_select") or 0
return self
end
function SongSelect:update(current_ms)
self.text_fade_in:update(current_ms)
self.blue_arrow_fade:update(current_ms)
self.blue_arrow_move:update(current_ms)
base.update_yellow_box(current_ms)
end
-- Call whenever the screen state changes so the label cross-fades correctly.
function SongSelect:restart_text_fade()
self.text_fade_in:start()
end
function SongSelect:draw_footer()
tex.draw_texture(self._id_footer)
end
-- Draw the navigation arrows and the top-left state label.
-- state: one of the STATE_* constants above (passed from C++ as an int).
function SongSelect:draw_overlays(state)
-- Blue navigation arrows are only shown while browsing.
if state == STATE_BROWSING then
local drift = self.blue_arrow_move.attribute * 2
local fade = self.blue_arrow_fade.attribute
tex.draw_texture(self._id_arrow, { x = -drift, fade = fade, index = 0 })
tex.draw_texture(self._id_arrow, { mirror = "horizontal",
x = drift, fade = fade, index = 1 })
end
-- Top-left label: cross-fade between "SONG SELECT" and "DIFFICULTY SELECT".
local label_fade = self.text_fade_in.attribute
if state == STATE_SONG_SELECTED then
tex.draw_texture(self._id_difficulty_select, { fade = label_fade })
tex.draw_texture(self._id_song_select, { fade = 1 - label_fade })
else
tex.draw_texture(self._id_difficulty_select, { fade = 1 - label_fade })
tex.draw_texture(self._id_song_select, { fade = label_fade })
end
end
function SongSelect:draw_box(box)
base.track_yellow_box(box)
local kind = box:lua_kind()
local state = box:draw_state()
if kind == "song" then
if state == "diff_select" then
self:draw_song_diff_select(box)
elseif state == "open" then
self:draw_song_open(box)
else
self:draw_song_closed(box)
end
elseif kind == "folder" then
if state == "open" then
self:draw_folder_open(box)
else
self:draw_folder_closed(box)
end
elseif kind == "back" then
if state == "open" then
self:draw_back_open(box)
else
self:draw_back_closed(box)
end
end
end