diff --git a/src/editor_state.cpp b/src/editor_state.cpp index 7bac4b4..176623f 100644 --- a/src/editor_state.cpp +++ b/src/editor_state.cpp @@ -37,8 +37,11 @@ void EditorState::reloadMusic() { std::filesystem::path music_path = std::filesystem::path(fumen.path).parent_path() / fumen.musicPath; - if (fumen.musicPath.empty() or not std::filesystem::exists(music_path) - or not music->openFromFile(music_path.string())) { + if ( + fumen.musicPath.empty() + or not std::filesystem::exists(music_path) + or not music->openFromFile(music_path.string()) + ) { music.reset(); } @@ -48,25 +51,26 @@ void EditorState::reloadMusic() { } void EditorState::reloadPreviewEnd() { + float music_duration = 0; if (music) { - if (chart) { - previewEnd = sf::seconds( - std::max( - music->getDuration().asSeconds(), - fumen.getChartRuntime(chart->ref) - fumen.offset) - + 2.f); - } else { - previewEnd = - sf::seconds(std::max(-fumen.offset, music->getDuration().asSeconds())); - } - } else { - if (chart) { - previewEnd = sf::seconds( - std::max(fumen.getChartRuntime(chart->ref) - fumen.offset, 2.f)); - } else { - previewEnd = sf::seconds(std::max(-fumen.offset, 2.f)); - } + music_duration = music->getDuration().asSeconds(); } + + float chart_runtime = 0; + if (chart) { + chart_runtime = fumen.getChartRuntime(chart->ref); + } + + // Chart end in seconds using the music file "coordinate system" + // (beat 0 is at -offset seconds) + float chart_end = std::max(chart_runtime - fumen.offset, 0.f); + float preview_end_seconds = std::max(music_duration, chart_end) ; + + // Add some extra time at the end to allow for more notes to be placed + // after the end of the chart + // TODO: is this really the way to do it ? + preview_end_seconds += 2.f; + previewEnd = sf::seconds(preview_end_seconds); } /* @@ -425,21 +429,14 @@ void EditorState::displayTimeline() { ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove); { - if (music and chart) { + if (chart) { ImGui::SetCursorPos({0, 0}); ImGui::Image(chart->densityGraph.graph.getTexture(), ImVec2(0, 1), ImVec2(1, 0)); AffineTransform scroll(-fumen.offset, previewEnd.asSeconds(), 1.f, 0.f); float slider_pos = scroll.transform(playbackPosition.asSeconds()); ImGui::SetCursorPos({0, 0}); - if (ImGui::VSliderFloat( - "", - ImGui::GetContentRegionMax(), - &slider_pos, - 0.f, - 1.f, - "")) { - setPlaybackAndMusicPosition( - sf::seconds(scroll.backwards_transform(slider_pos))); + if (ImGui::VSliderFloat("TimelineSlider", ImGui::GetContentRegionMax(), &slider_pos, 0.f, 1.f, "")) { + setPlaybackAndMusicPosition(sf::seconds(scroll.backwards_transform(slider_pos))); } } } diff --git a/src/editor_state.hpp b/src/editor_state.hpp index 94bfd7e..6cd731f 100644 --- a/src/editor_state.hpp +++ b/src/editor_state.hpp @@ -63,8 +63,8 @@ public: sf::Time playbackPosition; private: - sf::Time previewEnd; // sf::Time at which the chart preview stops, can be - // after the end of the audio + sf::Time previewEnd; // sf::Time (in the audio file "coordinates") at which the chart preview stops, can be + // after the end of the actual audio file public: const sf::Time& getPreviewEnd(); diff --git a/src/fumen.cpp b/src/fumen.cpp index be7434f..1d2edb4 100644 --- a/src/fumen.cpp +++ b/src/fumen.cpp @@ -142,8 +142,9 @@ void Fumen::saveAsMemon(std::filesystem::path path) { float Fumen::getChartRuntime(Chart c) { if (!c.Notes.empty()) { Note last_note = *c.Notes.rbegin(); - return ((static_cast(last_note.getTiming()) / c.getResolution()) / this->BPM) - * 60.f; + auto beats = static_cast(last_note.getTiming()) / c.getResolution(); + auto minutes = beats / this->BPM; + return minutes * 60.f; } else { return 0; } diff --git a/src/widgets/density_graph.cpp b/src/widgets/density_graph.cpp index 840d35f..6596f31 100644 --- a/src/widgets/density_graph.cpp +++ b/src/widgets/density_graph.cpp @@ -1,5 +1,7 @@ #include "density_graph.hpp" +#include + const std::string texture_file = "textures/edit_textures/game_front_edit_tex_1.tex.png"; DensityGraph::DensityGraph(std::filesystem::path assets) : @@ -43,8 +45,11 @@ void DensityGraph::computeDensities(int height, float chartRuntime, Chart& chart last_section_length = section_length; for (auto const& note : chart.Notes) { - auto section = - static_cast(ticksToSeconds(note.getTiming()) / section_length); + auto note_time = note.getTiming(); + auto note_seconds = ticksToSeconds(note_time); + auto float_section = note_seconds / section_length; + auto int_section = static_cast(float_section); + auto section = std::clamp(int_section, 0, sections - 1); densities.at(section).density += 1; if (not densities.at(section).has_collisions) { densities.at(section).has_collisions =