From 99c1227553911090cbb6582397a2db34f391b07d Mon Sep 17 00:00:00 2001 From: Stepland <16676308+Stepland@users.noreply.github.com> Date: Tue, 25 Feb 2020 23:47:29 +0100 Subject: [PATCH] Play the music preview when a song panel is clicked --- TODO.md | 4 +- meson.build | 2 + src/Data/Chart.hpp | 2 +- src/Data/Song.cpp | 8 +++- src/Data/Song.hpp | 5 ++- src/Screens/MusicSelect/DensityGraph.cpp | 4 +- src/Screens/MusicSelect/MusicPreview.cpp | 44 +++++++++++++++++++++ src/Screens/MusicSelect/MusicPreview.hpp | 28 +++++++++++++ src/Screens/MusicSelect/MusicSelect.cpp | 1 + src/Screens/MusicSelect/Panel.cpp | 1 + src/Screens/MusicSelect/SharedResources.hpp | 4 ++ 11 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 src/Screens/MusicSelect/MusicPreview.cpp create mode 100644 src/Screens/MusicSelect/MusicPreview.hpp diff --git a/TODO.md b/TODO.md index 555137c..6dcd83f 100644 --- a/TODO.md +++ b/TODO.md @@ -28,6 +28,8 @@ - Density graph - format-agnostic chart class - Black frame +- Sound + - Music Sample ### Misc - Handling Resolution changes @@ -45,7 +47,7 @@ ### Music Select Screen - Sound - - Music Sample + - Sound Effects - Fullscreen handling - Song Panel click - animation diff --git a/meson.build b/meson.build index 53c1f7c..8ab9cc2 100644 --- a/meson.build +++ b/meson.build @@ -45,6 +45,8 @@ sources = [ 'src/Screens/MusicSelect/ButtonHighlight.cpp', 'src/Screens/MusicSelect/DensityGraph.hpp', 'src/Screens/MusicSelect/DensityGraph.cpp', + 'src/Screens/MusicSelect/MusicPreview.hpp', + 'src/Screens/MusicSelect/MusicPreview.cpp', 'src/Screens/MusicSelect/MusicSelect.hpp', 'src/Screens/MusicSelect/MusicSelect.cpp', 'src/Screens/MusicSelect/Panel.hpp', diff --git a/src/Data/Chart.hpp b/src/Data/Chart.hpp index 7dbb669..83fb2d8 100644 --- a/src/Data/Chart.hpp +++ b/src/Data/Chart.hpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include "Buttons.hpp" #include "Note.hpp" diff --git a/src/Data/Song.cpp b/src/Data/Song.cpp index ae90905..41baf13 100644 --- a/src/Data/Song.cpp +++ b/src/Data/Song.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace fs = ghc::filesystem; @@ -115,6 +115,12 @@ namespace Data { if (not m.music_path.empty()) { this->audio.emplace(m.music_path); } + if (m.preview) { + this->preview.emplace( + sf::seconds(m.preview->position), + sf::seconds(m.preview->duration) + ); + } for (const auto& [difficulty, chart] : m.charts) { this->chart_levels[difficulty] = chart.level; } diff --git a/src/Data/Song.hpp b/src/Data/Song.hpp index d5815a4..eaa4b79 100644 --- a/src/Data/Song.hpp +++ b/src/Data/Song.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -10,6 +9,9 @@ #include #include +#include +#include + #include "Chart.hpp" namespace fs = ghc::filesystem; @@ -33,6 +35,7 @@ namespace Data { std::optional cover; // Path the the audio file std::optional audio; + std::optional preview; // Mapping from chart difficulty (BSC, ADV, EXT ...) to the numeric level, std::map chart_levels; diff --git a/src/Screens/MusicSelect/DensityGraph.cpp b/src/Screens/MusicSelect/DensityGraph.cpp index 618aa71..b58e1f9 100644 --- a/src/Screens/MusicSelect/DensityGraph.cpp +++ b/src/Screens/MusicSelect/DensityGraph.cpp @@ -44,10 +44,10 @@ namespace MusicSelect { } DensityGraph compute_density_graph_from_struct(const SongDifficulty& sd) { - return compute_density_graph_from_song(sd.song, sd.difficulty); + return compute_density_graph_from_song_difficulty(sd.song, sd.difficulty); } - DensityGraph compute_density_graph_from_song(const Data::Song& song, const std::string& difficulty) { + DensityGraph compute_density_graph_from_song_difficulty(const Data::Song& song, const std::string& difficulty) { auto c = song.get_chart(difficulty); if (not c.has_value()) { throw std::invalid_argument("Song "+song.title+" has no "+difficulty+" chart"); diff --git a/src/Screens/MusicSelect/MusicPreview.cpp b/src/Screens/MusicSelect/MusicPreview.cpp new file mode 100644 index 0000000..22c9ed5 --- /dev/null +++ b/src/Screens/MusicSelect/MusicPreview.cpp @@ -0,0 +1,44 @@ +#include "MusicPreview.hpp" + +#include + +namespace MusicSelect { + + void MusicPreview::play(std::optional music_path, std::optional loop) { + m_music_loop.emplace(); + if (not music_path.has_value()) { + return; + } + if (not m_music_loop->music.openFromFile(music_path->string())) { + std::cerr << "Could not load " << music_path->string() << std::endl; + return; + } + if (not loop.has_value()) { + if (m_music_loop->music.getDuration() < sf::seconds(30)) { + loop.emplace(sf::seconds(0.f), m_music_loop->music.getDuration()); + } else { + loop.emplace(sf::seconds(15.f), sf::seconds(10.f)); + } + } + m_music_loop->music.setLoopPoints(*loop); + m_music_loop->loop = m_music_loop->music.getLoopPoints(); + m_music_loop->music.setLoop(true); + m_music_loop->music.setPlayingOffset(loop->offset); + auto end = m_music_loop->loop.offset + m_music_loop->loop.length; + m_music_loop->fade_out = Toolkit::AffineTransform{ + (end - sf::seconds(2)).asSeconds(), end.asSeconds(), + 100.f, 0.f + }; + m_music_loop->music.play(); + } + + void MusicPreview::update() { + if (m_music_loop) { + m_music_loop->music.setVolume( + m_music_loop->fade_out.clampedTransform( + m_music_loop->music.getPlayingOffset().asSeconds() + ) + ); + } + } +} diff --git a/src/Screens/MusicSelect/MusicPreview.hpp b/src/Screens/MusicSelect/MusicPreview.hpp new file mode 100644 index 0000000..3fbd52b --- /dev/null +++ b/src/Screens/MusicSelect/MusicPreview.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +#include +#include + +#include "../../Toolkit/AffineTransform.hpp" + +namespace fs = ghc::filesystem; + +namespace MusicSelect { + struct MusicLoop { + sf::Music music; + sf::Music::TimeSpan loop; + Toolkit::AffineTransform fade_out = {0.f, 1.f, 0.f, 1.f}; // placeholder value + }; + + class MusicPreview { + public: + MusicPreview() = default; + void play(std::optional music_path, std::optional loop); + void update(); + private: + std::optional m_music_loop; + }; +} diff --git a/src/Screens/MusicSelect/MusicSelect.cpp b/src/Screens/MusicSelect/MusicSelect.cpp index 055784a..e5daa99 100644 --- a/src/Screens/MusicSelect/MusicSelect.cpp +++ b/src/Screens/MusicSelect/MusicSelect.cpp @@ -76,6 +76,7 @@ void MusicSelect::Screen::select_chart(sf::RenderWindow& window) { window.draw(black_frame); ImGui::SFML::Render(window); window.display(); + resources.music_preview.update(); } ImGui::SFML::Shutdown(); } diff --git a/src/Screens/MusicSelect/Panel.cpp b/src/Screens/MusicSelect/Panel.cpp index 60d495e..c13f9ab 100644 --- a/src/Screens/MusicSelect/Panel.cpp +++ b/src/Screens/MusicSelect/Panel.cpp @@ -91,6 +91,7 @@ namespace MusicSelect { m_resources.selected_panel->panel.unselect(); } m_resources.selected_panel.emplace(TimedSelectedPanel{*this}); + m_resources.music_preview.play(m_song->full_audio_path(), m_song->preview); } } diff --git a/src/Screens/MusicSelect/SharedResources.hpp b/src/Screens/MusicSelect/SharedResources.hpp index 6fb41bc..aaaba46 100644 --- a/src/Screens/MusicSelect/SharedResources.hpp +++ b/src/Screens/MusicSelect/SharedResources.hpp @@ -11,6 +11,7 @@ #include "../../Data/Song.hpp" #include "DensityGraph.hpp" +#include "MusicPreview.hpp" namespace MusicSelect { @@ -24,6 +25,7 @@ namespace MusicSelect { bool is_first_click = true; }; + // Holds everything that needs to be shared by all levels of the class hierarchy struct SharedResources : public Data::HoldsPreferences { SharedResources(Data::Preferences& p); @@ -43,6 +45,8 @@ namespace MusicSelect { sf::Color ADV_color = sf::Color{252,212,32}; sf::Color EXT_color = sf::Color{234,46,32}; sf::Color get_chart_color(const std::string& chart); + + MusicPreview music_preview; }; // Proxy for HoldsPreferences