-- 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