diff --git a/TODO.md b/TODO.md index 9c7a6a6..f28b5ac 100644 --- a/TODO.md +++ b/TODO.md @@ -2,6 +2,7 @@ ## Misc ## Gameplay Screen +- Precise Input handling, the dirty way ## Results Screen diff --git a/meson.build b/meson.build index abae5a9..6fc6ad5 100644 --- a/meson.build +++ b/meson.build @@ -30,23 +30,26 @@ sources = [ 'src/Data/Note.hpp', 'src/Data/Preferences.hpp', 'src/Data/Preferences.cpp', - 'src/Data/Score.hpp', 'src/Data/Song.hpp', 'src/Data/Song.cpp', 'src/Drawables/BlackFrame.hpp', 'src/Drawables/BlackFrame.cpp', 'src/Drawables/ButtonHighlight.hpp', 'src/Drawables/ButtonHighlight.cpp', + 'src/Drawables/DensityGraph.hpp', + 'src/Drawables/DensityGraph.cpp', 'src/Input/Buttons.hpp', 'src/Input/Buttons.cpp', 'src/Input/KeyMapping.hpp', 'src/Input/KeyMapping.cpp', - 'src/Input/MappableKeys.hpp', - 'src/Input/MappableKeys.cpp', + 'src/Input/Events.hpp', + 'src/Input/Events.cpp', 'src/Resources/TextureCache.cpp', 'src/Resources/TextureCache.hpp', 'src/Resources/Marker.cpp', 'src/Resources/Marker.hpp', + 'src/Resources/SharedResources.hpp', + 'src/Resources/SharedResources.cpp', # 'src/Resources/CoverAtlas.hpp', # 'src/Resources/CoverAtlas.cpp', # 'src/Screens/Gameplay.hpp', @@ -62,8 +65,6 @@ sources = [ 'src/Screens/MusicSelect/Panels/Panel.cpp', 'src/Screens/MusicSelect/Panels/SubpagePanel.hpp', 'src/Screens/MusicSelect/Panels/SubpagePanel.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', @@ -72,10 +73,16 @@ sources = [ 'src/Screens/MusicSelect/PanelLayout.cpp', 'src/Screens/MusicSelect/Ribbon.hpp', 'src/Screens/MusicSelect/Ribbon.cpp', - 'src/Screens/MusicSelect/SharedResources.hpp', - 'src/Screens/MusicSelect/SharedResources.cpp', + 'src/Screens/MusicSelect/Resources.hpp', + 'src/Screens/MusicSelect/Resources.cpp', 'src/Screens/MusicSelect/SongInfo.hpp', 'src/Screens/MusicSelect/SongInfo.cpp', + 'src/Screens/Gameplay/Gameplay.hpp', + 'src/Screens/Gameplay/Gameplay.cpp', + 'src/Screens/Gameplay/PreciseMusic.hpp', + 'src/Screens/Gameplay/PreciseMusic.cpp', + 'src/Screens/Gameplay/Silence.hpp', + 'src/Screens/Gameplay/Silence.cpp', # 'src/Screens/Result.hpp', 'src/Toolkit/AffineTransform.hpp', 'src/Toolkit/Cache.hpp', diff --git a/src/Data/Chart.cpp b/src/Data/Chart.cpp index 8aa8ec7..36f48e8 100644 --- a/src/Data/Chart.cpp +++ b/src/Data/Chart.cpp @@ -11,21 +11,21 @@ namespace Data { auto [_, chart] = *it; level = chart.level; resolution = static_cast(chart.resolution); - Toolkit::AffineTransform memon_timing_to_1000Hz( + Toolkit::AffineTransform memon_timing_to_seconds( 0.f, static_cast(chart.resolution), - -memon.offset*1000.f, (-memon.offset+60.f/memon.BPM)*1000.f + -memon.offset, (-memon.offset+60.f/memon.BPM) ); - Toolkit::AffineTransform memon_timing_to_300Hz_proportional( + Toolkit::AffineTransform memon_timing_to_seconds_proportional( 0.f, static_cast(chart.resolution), - 0.f, (60.f/memon.BPM)*300.f + 0.f, (60.f/memon.BPM)*1000.f ); for (auto &¬e : chart.notes) { - auto timing = static_cast(memon_timing_to_1000Hz.transform(note.get_timing())); + auto timing = sf::seconds(memon_timing_to_seconds.transform(note.get_timing())); auto position = static_cast(note.get_pos()); - std::size_t length = 0; + sf::Time length = sf::Time::Zero; auto tail = Input::Button::B1; if (note.get_length() != 0) { - length = static_cast(memon_timing_to_300Hz_proportional.transform(note.get_length())); + length = sf::seconds(memon_timing_to_seconds_proportional.transform(note.get_length())); tail = convert_memon_tail(position, note.get_tail_pos()); } notes.insert({timing, position, length, tail}); @@ -74,4 +74,12 @@ namespace Data { } return *tail; } + + sf::Time Chart::get_duration_based_on_notes() const { + if (notes.rbegin() == notes.rend()) { + return sf::Time::Zero; + } else { + return notes.rbegin()->timing; + } + } } diff --git a/src/Data/Chart.hpp b/src/Data/Chart.hpp index d775f0b..73b5ccc 100644 --- a/src/Data/Chart.hpp +++ b/src/Data/Chart.hpp @@ -4,6 +4,7 @@ #include #include +#include #include "../Input/Buttons.hpp" #include "Note.hpp" @@ -14,6 +15,7 @@ namespace Data { int level; std::set notes; std::size_t resolution; + sf::Time get_duration_based_on_notes() const; }; Input::Button convert_memon_tail(Input::Button note, unsigned int tail_position); } \ No newline at end of file diff --git a/src/Data/Note.hpp b/src/Data/Note.hpp index 2f67f79..5d8dac6 100644 --- a/src/Data/Note.hpp +++ b/src/Data/Note.hpp @@ -1,14 +1,16 @@ #pragma once +#include + #include "../Input/Buttons.hpp" namespace Data { struct Note { - // Timing is stored as ticks on a 1000Hz clock starting at the begging of the audio - long int timing; + // offset since the begging of the audio + sf::Time timing; Input::Button position; - // zero length means it's a standard note - std::size_t length; + // zero means it's a normal note + sf::Time duration; Input::Button tail; bool operator==(const Note &rhs) const { diff --git a/src/Data/Score.hpp b/src/Data/Score.hpp index c617c49..7e5980d 100644 --- a/src/Data/Score.hpp +++ b/src/Data/Score.hpp @@ -5,4 +5,4 @@ namespace Data { public: Score(); }; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/src/Screens/MusicSelect/DensityGraph.cpp b/src/Drawables/DensityGraph.cpp similarity index 83% rename from src/Screens/MusicSelect/DensityGraph.cpp rename to src/Drawables/DensityGraph.cpp index 15becba..c20c3ad 100644 --- a/src/Screens/MusicSelect/DensityGraph.cpp +++ b/src/Drawables/DensityGraph.cpp @@ -5,9 +5,9 @@ #include -#include "../../Toolkit/AffineTransform.hpp" +#include "../Toolkit/AffineTransform.hpp" -namespace MusicSelect { +namespace Drawables { DensityGraph::DensityGraph(const std::array& t_densities) : m_densities(t_densities), @@ -53,7 +53,7 @@ namespace MusicSelect { throw std::invalid_argument("Song "+song.title+" has no "+difficulty+" chart"); } if (c->notes.empty()) { - return compute_density_graph_from_chart(*c, 0, 0); + return compute_density_graph_from_chart(*c, sf::Time::Zero, sf::Time::Zero); } if (not song.audio.has_value()) { return compute_density_graph_from_chart(*c, c->notes.begin()->timing, c->notes.rbegin()->timing); @@ -64,22 +64,22 @@ namespace MusicSelect { } return compute_density_graph_from_chart( *c, - std::min(0L, c->notes.begin()->timing), - std::max(c->notes.rbegin()->timing, static_cast(m.getDuration().asMilliseconds()*3/10)) + sf::microseconds(std::min(0LL, c->notes.begin()->timing.asMicroseconds())), + sf::microseconds(std::max(c->notes.rbegin()->timing.asMicroseconds(), m.getDuration().asMicroseconds())) ); } - DensityGraph compute_density_graph_from_chart(const Data::Chart& chart, long start, long end) { + DensityGraph compute_density_graph_from_chart(const Data::Chart& chart, sf::Time start, sf::Time end) { std::array d{}; if (start != end) { Toolkit::AffineTransform ticks_to_column{ - static_cast(start), - static_cast(end), + start.asSeconds(), + end.asSeconds(), 0.f, 115.f }; for (auto &¬e : chart.notes) { - auto index = static_cast(ticks_to_column.transform(static_cast(note.timing))); + auto index = static_cast(ticks_to_column.transform(note.timing.asSeconds())); d.at(index) += 1; } std::replace_if( @@ -95,7 +95,7 @@ namespace MusicSelect { namespace Toolkit { template<> - void set_origin_normalized(MusicSelect::DensityGraph& s, float x, float y) { + void set_origin_normalized(Drawables::DensityGraph& s, float x, float y) { s.setOrigin(x*574.f, y*39.f); } } \ No newline at end of file diff --git a/src/Screens/MusicSelect/DensityGraph.hpp b/src/Drawables/DensityGraph.hpp similarity index 81% rename from src/Screens/MusicSelect/DensityGraph.hpp rename to src/Drawables/DensityGraph.hpp index 67ad06e..5c1eaeb 100644 --- a/src/Screens/MusicSelect/DensityGraph.hpp +++ b/src/Drawables/DensityGraph.hpp @@ -5,12 +5,12 @@ #include -#include "../../Data/Chart.hpp" -#include "../../Data/Song.hpp" -#include "../../Toolkit/Cache.hpp" -#include "../../Toolkit/NormalizedOrigin.hpp" +#include "../Data/Chart.hpp" +#include "../Data/Song.hpp" +#include "../Toolkit/Cache.hpp" +#include "../Toolkit/NormalizedOrigin.hpp" -namespace MusicSelect { +namespace Drawables { class DensityGraph : public sf::Drawable, public sf::Transformable { public: explicit DensityGraph(const std::array& t_densities); @@ -22,7 +22,7 @@ namespace MusicSelect { DensityGraph compute_density_graph_from_struct(const Data::SongDifficulty& sd); DensityGraph compute_density_graph_from_song_difficulty(const Data::Song& song, const std::string& difficulty); - DensityGraph compute_density_graph_from_chart(const Data::Chart& chart, long start, long end); + DensityGraph compute_density_graph_from_chart(const Data::Chart& chart, sf::Time start, sf::Time end); using DensityGraphCache = Toolkit::Cache; } @@ -40,5 +40,5 @@ namespace std { namespace Toolkit { template<> - void set_origin_normalized(MusicSelect::DensityGraph& s, float x, float y); + void set_origin_normalized(Drawables::DensityGraph& s, float x, float y); } \ No newline at end of file diff --git a/src/Input/MappableKeys.cpp b/src/Input/Events.cpp similarity index 85% rename from src/Input/MappableKeys.cpp rename to src/Input/Events.cpp index 28a739c..6824587 100644 --- a/src/Input/MappableKeys.cpp +++ b/src/Input/Events.cpp @@ -1,19 +1,19 @@ -#include "MappableKeys.hpp" +#include "Events.hpp" namespace Input { - MappableKeyToString mappable_button_to_string; + EventToString mappable_button_to_string; - std::string to_string(const MappableKey& mk) { + std::string to_string(const Event& mk) { return std::visit(mappable_button_to_string, mk); } std::regex mappable_button_regex("(.+?)::(.+)"); std::regex joystick_button_regex("(\\d+)_(\\d+)"); - MappableKey from_string(const std::string& s) { + Event from_string(const std::string& s) { std::smatch matches; if (not std::regex_match(s, matches, mappable_button_regex)) { - throw std::runtime_error("Unknown MappableKey : "+s); + throw std::runtime_error("Unknown Event : "+s); } auto device = matches[1].str(); auto button = matches[2].str(); diff --git a/src/Input/MappableKeys.hpp b/src/Input/Events.hpp similarity index 97% rename from src/Input/MappableKeys.hpp rename to src/Input/Events.hpp index f9ae953..4dc2411 100644 --- a/src/Input/MappableKeys.hpp +++ b/src/Input/Events.hpp @@ -33,7 +33,7 @@ namespace std { } namespace Input { - using MappableKey = std::variant; + using Event = std::variant; const std::unordered_map keyboard_to_string{ { @@ -249,8 +249,7 @@ namespace Input { } }; - struct MappableKeyToString { - public: + struct EventToString { std::string operator() (const sf::Keyboard::Key& k) { return "Keyboard::"+keyboard_to_string.at(k); }; @@ -259,6 +258,6 @@ namespace Input { }; }; - std::string to_string(const MappableKey& mk); - MappableKey from_string(const std::string& s); + std::string to_string(const Event& mk); + Event from_string(const std::string& s); } \ No newline at end of file diff --git a/src/Input/KeyMapping.cpp b/src/Input/KeyMapping.cpp index 3a05f34..168ac22 100644 --- a/src/Input/KeyMapping.cpp +++ b/src/Input/KeyMapping.cpp @@ -24,21 +24,21 @@ namespace Input { } } - KeyMapping::KeyMapping(std::unordered_map button_to_key) : m_button_to_key(button_to_key) { + KeyMapping::KeyMapping(std::unordered_map button_to_key) : m_button_to_key(button_to_key) { for (auto &&[button, key] : m_button_to_key) { m_key_to_button[key] = button; } assert((m_button_to_key.size() == m_key_to_button.size())); } - KeyMapping::KeyMapping(std::unordered_map key_to_button) : m_key_to_button(key_to_button) { + KeyMapping::KeyMapping(std::unordered_map key_to_button) : m_key_to_button(key_to_button) { for (auto &&[key, button] : m_key_to_button) { m_button_to_key[button] = key; } assert((m_button_to_key.size() == m_key_to_button.size())); } - void KeyMapping::set_button_to_key(const Button& button, const MappableKey& key) { + void KeyMapping::set_button_to_key(const Button& button, const Event& key) { if (m_key_to_button.find(key) != m_key_to_button.end()) { m_button_to_key.erase(m_key_to_button[key]); m_key_to_button.erase(key); @@ -47,7 +47,7 @@ namespace Input { m_key_to_button[key] = button; } - std::optional