Upgrade bpm calculator, try implement slider animation
This commit is contained in:
parent
55b62e62bb
commit
60d7b4e346
|
@ -25,6 +25,7 @@ private:
|
||||||
std::array<std::shared_ptr<GUIState>, GUIState::Tag::AMOUNT> _states;
|
std::array<std::shared_ptr<GUIState>, GUIState::Tag::AMOUNT> _states;
|
||||||
std::vector<std::shared_ptr<GUIState>> _state_stack;
|
std::vector<std::shared_ptr<GUIState>> _state_stack;
|
||||||
|
|
||||||
|
|
||||||
sf::RenderWindow _game_window;
|
sf::RenderWindow _game_window;
|
||||||
std::shared_ptr<Game> _game;
|
std::shared_ptr<Game> _game;
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,33 @@ class BPMCalculator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit BPMCalculator(const std::shared_ptr<Music>& music);
|
explicit BPMCalculator(const std::shared_ptr<Music>& music);
|
||||||
|
|
||||||
void setMusic(const std::shared_ptr<Music>& music);
|
void setMusic(const std::shared_ptr<Music>& music);
|
||||||
std::shared_ptr<Music> music() const;
|
std::shared_ptr<Music> music() const;
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
void stop();
|
||||||
void click();
|
void click();
|
||||||
int getCurrentApproximation() const;
|
float fetchCurrentBPMApproximation();
|
||||||
|
|
||||||
|
microsec getStartingOffset() const;
|
||||||
|
void setStartingOffset(microsec offset);
|
||||||
|
void moveStartingOffsetBy(microsec shift);
|
||||||
|
|
||||||
|
microsec fetchTimeUntilNextBeat();
|
||||||
|
microsec fetchBeatInterval();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _need_recalculate;
|
||||||
|
bool _calculating;
|
||||||
|
|
||||||
std::shared_ptr<Music> _music;
|
std::shared_ptr<Music> _music;
|
||||||
std::vector<microsec> _deltas;
|
std::vector<microsec> _deltas;
|
||||||
microsec _previous_click_offset;
|
microsec _previous_click_offset;
|
||||||
|
microsec _first_click_offset;
|
||||||
|
|
||||||
|
int _approximated_bpm;
|
||||||
|
|
||||||
|
inline float calculateBPM(microsec all_microseconds, std::size_t beats_amount) const;
|
||||||
|
inline void reset();
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,12 +26,18 @@ Application::Application() :
|
||||||
_game_window.setMouseCursorGrabbed(false);
|
_game_window.setMouseCursorGrabbed(false);
|
||||||
_game_window.setVerticalSyncEnabled(true);
|
_game_window.setVerticalSyncEnabled(true);
|
||||||
|
|
||||||
MainMenu::Callbacks callbacks = {[&](){ pushState(GUIState::Tag::EDITOR); }};
|
MainMenu::Callbacks callbacks =
|
||||||
|
{
|
||||||
|
[&](){ pushState(GUIState::Tag::GAME); },
|
||||||
|
[&](){ pushState(GUIState::Tag::EDITOR); }
|
||||||
|
};
|
||||||
|
|
||||||
Editor::Callbacks editor_callbacks = {[&](){ popState(); }};
|
Editor::Callbacks editor_callbacks = {[&](){ popState(); }};
|
||||||
|
|
||||||
const auto main_menu = std::make_shared<MainMenu>(_game_window, std::move(callbacks), _font_holder);
|
const auto main_menu = std::make_shared<MainMenu>(_game_window, std::move(callbacks), _font_holder);
|
||||||
const auto game_state = std::make_shared<GameState>(_game_window, _game, GameState::Callbacks());
|
const auto game_state = std::make_shared<GameState>(_game_window, _game, GameState::Callbacks());
|
||||||
const auto editor = std::make_shared<Editor>(_game_window, std::move(editor_callbacks), std::make_unique<MusicSFML>(), _font_holder);
|
const auto editor = std::make_shared<Editor>(_game_window, std::move(editor_callbacks), std::make_unique<MusicSFML>(), _font_holder);
|
||||||
|
|
||||||
_states[GUIState::Tag::MAIN_MENU] = main_menu;
|
_states[GUIState::Tag::MAIN_MENU] = main_menu;
|
||||||
_states[GUIState::Tag::GAME] = game_state;
|
_states[GUIState::Tag::GAME] = game_state;
|
||||||
_states[GUIState::Tag::EDITOR] = editor;
|
_states[GUIState::Tag::EDITOR] = editor;
|
||||||
|
|
|
@ -106,5 +106,6 @@ void Editor::enter()
|
||||||
void Editor::leave()
|
void Editor::leave()
|
||||||
{
|
{
|
||||||
_group.reset();
|
_group.reset();
|
||||||
|
_bpm_calculator.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,23 @@ MainMenu::MainMenu(sf::RenderWindow& game_window, Callbacks&& callbacks, const F
|
||||||
const float window_width = game_window.getSize().x;
|
const float window_width = game_window.getSize().x;
|
||||||
const float window_height = game_window.getSize().y;
|
const float window_height = game_window.getSize().y;
|
||||||
|
|
||||||
std::shared_ptr<PushButton> button_start = std::make_shared<PushButton>("Start", font_holder.get(Fonts::Id::GUI), 48);
|
auto button_start = std::make_shared<PushButton>("Start", font_holder.get(Fonts::Id::GUI), 48);
|
||||||
button_start->setRect(sf::FloatRect(window_width / 3., window_height / 7. * 2, window_width / 3., window_height / 7.));
|
button_start->setRect(sf::FloatRect(window_width / 3., window_height / 7., window_width / 3., window_height / 7.));
|
||||||
button_start->setCallback(callbacks.onAppendGameState);
|
button_start->setCallback(callbacks.onAppendGameState);
|
||||||
|
|
||||||
std::shared_ptr<PushButton> button_exit = std::make_shared<PushButton>("Exit", font_holder.get(Fonts::Id::GUI), 48);
|
auto button_editor = std::make_shared<PushButton>("Editor", font_holder.get(Fonts::Id::GUI), 48);
|
||||||
button_exit->setRect(sf::FloatRect(window_width / 3., window_height / 7. * 4, window_width / 3., window_height / 7.));
|
button_editor->setRect(sf::FloatRect(window_width / 3., window_height / 7. * 3, window_width / 3., window_height / 7.));
|
||||||
|
button_editor->setCallback(callbacks.onAppendEditorState);
|
||||||
|
|
||||||
|
auto button_exit = std::make_shared<PushButton>("Exit", font_holder.get(Fonts::Id::GUI), 48);
|
||||||
|
button_exit->setRect(sf::FloatRect(window_width / 3., window_height / 7. * 5, window_width / 3., window_height / 7.));
|
||||||
button_exit->setCallback([&]()
|
button_exit->setCallback([&]()
|
||||||
{
|
{
|
||||||
_game_window.close();
|
_game_window.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
_buttons->addChild(button_start);
|
_buttons->addChild(button_start);
|
||||||
|
_buttons->addChild(button_editor);
|
||||||
_buttons->addChild(button_exit);
|
_buttons->addChild(button_exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ public:
|
||||||
struct Callbacks
|
struct Callbacks
|
||||||
{
|
{
|
||||||
std::function<void(void)> onAppendGameState;
|
std::function<void(void)> onAppendGameState;
|
||||||
|
std::function<void(void)> onAppendEditorState;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit MainMenu(sf::RenderWindow& game_window, Callbacks&& callbacks, const FontHolder &font_holder);
|
explicit MainMenu(sf::RenderWindow& game_window, Callbacks&& callbacks, const FontHolder &font_holder);
|
||||||
|
|
|
@ -34,10 +34,18 @@ void BPMCalculatorWidget::update(const sf::Time& dt)
|
||||||
{
|
{
|
||||||
Window::update(dt);
|
Window::update(dt);
|
||||||
|
|
||||||
const auto approximation = _bpm_calculator->getCurrentApproximation();
|
const auto approximation = _bpm_calculator->fetchCurrentBPMApproximation();
|
||||||
if (approximation != 0)
|
if (approximation != 0)
|
||||||
{
|
{
|
||||||
_bpm_value.setString(std::to_string(approximation));
|
_bpm_value.setString(std::to_string(approximation));
|
||||||
|
|
||||||
|
const microsec until_beat = _bpm_calculator->fetchTimeUntilNextBeat();
|
||||||
|
const microsec beat_interval = _bpm_calculator->fetchBeatInterval();
|
||||||
|
|
||||||
|
const auto time_relation = beat_interval / until_beat;
|
||||||
|
const auto slider_path_left = Window::rect().width / time_relation;
|
||||||
|
|
||||||
|
_slider->setTickPosition(slider_path_left);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,3 +49,17 @@ bool BPMSlider::isUnderMouse(int mouse_x, int mouse_y) const
|
||||||
return mouse_x == mouse_y; // just to compile
|
return mouse_x == mouse_y; // just to compile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::FloatRect BPMSlider::rect() const
|
||||||
|
{
|
||||||
|
return _slider_background.getGlobalBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f BPMSlider::position() const
|
||||||
|
{
|
||||||
|
return _slider_background.getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPMSlider::setTickPosition(float x_position)
|
||||||
|
{
|
||||||
|
_slider_tick.setPosition(_slider_background.getPosition().x + x_position, _slider_tick.getPosition().y);
|
||||||
|
}
|
||||||
|
|
|
@ -13,11 +13,17 @@ public:
|
||||||
virtual void input(const sf::Event& event) override;
|
virtual void input(const sf::Event& event) override;
|
||||||
virtual void update(const sf::Time& dt) override;
|
virtual void update(const sf::Time& dt) override;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
virtual void setRect(const sf::FloatRect& rect) override;
|
|
||||||
virtual void setPosition(const sf::Vector2f& position) override;
|
|
||||||
virtual void move(const sf::Vector2f& delta) override;
|
virtual void move(const sf::Vector2f& delta) override;
|
||||||
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
||||||
|
|
||||||
|
virtual void setRect(const sf::FloatRect& rect) override;
|
||||||
|
virtual sf::FloatRect rect() const override;
|
||||||
|
|
||||||
|
virtual void setPosition(const sf::Vector2f& position) override;
|
||||||
|
virtual sf::Vector2f position() const override;
|
||||||
|
|
||||||
|
void setTickPosition(float x_position);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::RectangleShape _slider_background;
|
sf::RectangleShape _slider_background;
|
||||||
sf::RectangleShape _slider_tick;
|
sf::RectangleShape _slider_tick;
|
||||||
|
|
|
@ -54,3 +54,13 @@ void Button::setText(const std::string& text)
|
||||||
{
|
{
|
||||||
_button_text.setString(text);
|
_button_text.setString(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::FloatRect Button::rect() const
|
||||||
|
{
|
||||||
|
return _button_content.getGlobalBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f Button::position() const
|
||||||
|
{
|
||||||
|
return _button_content.getPosition();
|
||||||
|
}
|
||||||
|
|
|
@ -13,11 +13,14 @@ public:
|
||||||
virtual void input(const sf::Event& event) override = 0;
|
virtual void input(const sf::Event& event) override = 0;
|
||||||
virtual void update(const sf::Time& dt) override final;
|
virtual void update(const sf::Time& dt) override final;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override final;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override final;
|
||||||
virtual void setPosition(const sf::Vector2f& position) override final;
|
|
||||||
virtual void move(const sf::Vector2f& delta) override final;
|
virtual void move(const sf::Vector2f& delta) override final;
|
||||||
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override final;
|
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override final;
|
||||||
|
|
||||||
virtual void setRect(const sf::FloatRect& rect) override;
|
virtual void setRect(const sf::FloatRect& rect) override;
|
||||||
|
virtual sf::FloatRect rect() const override;
|
||||||
|
|
||||||
|
virtual void setPosition(const sf::Vector2f& position) override;
|
||||||
|
virtual sf::Vector2f position() const override;
|
||||||
|
|
||||||
virtual void setText(const std::string& text);
|
virtual void setText(const std::string& text);
|
||||||
|
|
||||||
|
|
|
@ -38,3 +38,18 @@ bool Group::isUnderMouse(int mouse_x, int mouse_y) const
|
||||||
{
|
{
|
||||||
return _rect.contains(mouse_x, mouse_y);
|
return _rect.contains(mouse_x, mouse_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::FloatRect Group::rect() const
|
||||||
|
{
|
||||||
|
return _rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f Group::position() const
|
||||||
|
{
|
||||||
|
return sf::Vector2f
|
||||||
|
{
|
||||||
|
_rect.top,
|
||||||
|
_rect.left
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,15 @@ public:
|
||||||
virtual void input(const sf::Event& event) override;
|
virtual void input(const sf::Event& event) override;
|
||||||
virtual void update(const sf::Time& dt) override;
|
virtual void update(const sf::Time& dt) override;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
virtual void setRect(const sf::FloatRect& rect) override;
|
|
||||||
virtual void setPosition(const sf::Vector2f& position) override;
|
|
||||||
virtual void move(const sf::Vector2f& delta) override;
|
virtual void move(const sf::Vector2f& delta) override;
|
||||||
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
||||||
|
|
||||||
|
virtual void setRect(const sf::FloatRect& rect) override;
|
||||||
|
virtual sf::FloatRect rect() const override;
|
||||||
|
|
||||||
|
virtual void setPosition(const sf::Vector2f& position) override;
|
||||||
|
virtual sf::Vector2f position() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::FloatRect _rect;
|
sf::FloatRect _rect;
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,3 +113,13 @@ void MenuBar::setVisibility(bool is_visible)
|
||||||
for (auto& submenu : _submenus)
|
for (auto& submenu : _submenus)
|
||||||
submenu->setVisibility(false);
|
submenu->setVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::FloatRect MenuBar::rect() const
|
||||||
|
{
|
||||||
|
return _bar_rect.getGlobalBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f MenuBar::position() const
|
||||||
|
{
|
||||||
|
return _bar_rect.getPosition();
|
||||||
|
}
|
||||||
|
|
|
@ -14,12 +14,16 @@ public:
|
||||||
virtual void input(const sf::Event& event) override;
|
virtual void input(const sf::Event& event) override;
|
||||||
virtual void update(const sf::Time& dt) override;
|
virtual void update(const sf::Time& dt) override;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
virtual void setRect(const sf::FloatRect& rect) override;
|
|
||||||
virtual void setPosition(const sf::Vector2f& position) override;
|
|
||||||
virtual void move(const sf::Vector2f& delta) override;
|
virtual void move(const sf::Vector2f& delta) override;
|
||||||
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
||||||
virtual void setVisibility(bool is_visible = true) override;
|
virtual void setVisibility(bool is_visible = true) override;
|
||||||
|
|
||||||
|
virtual void setRect(const sf::FloatRect& rect) override;
|
||||||
|
virtual sf::FloatRect rect() const override;
|
||||||
|
|
||||||
|
virtual void setPosition(const sf::Vector2f& position) override;
|
||||||
|
virtual sf::Vector2f position() const override;
|
||||||
|
|
||||||
void addRootSubMenu(std::string name, const std::shared_ptr<MenuDrop>& submenu);
|
void addRootSubMenu(std::string name, const std::shared_ptr<MenuDrop>& submenu);
|
||||||
void addDependentSubmenu(const std::shared_ptr<MenuDrop>& submenu);
|
void addDependentSubmenu(const std::shared_ptr<MenuDrop>& submenu);
|
||||||
|
|
||||||
|
|
|
@ -147,3 +147,12 @@ bool MenuDrop::isLocked() const
|
||||||
return _is_locked;
|
return _is_locked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::FloatRect MenuDrop::rect() const
|
||||||
|
{
|
||||||
|
return _content_rect.getGlobalBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f MenuDrop::position() const
|
||||||
|
{
|
||||||
|
return _content_rect.getPosition();
|
||||||
|
}
|
||||||
|
|
|
@ -13,12 +13,16 @@ public:
|
||||||
virtual void input(const sf::Event& event) override;
|
virtual void input(const sf::Event& event) override;
|
||||||
virtual void update(const sf::Time& dt) override;
|
virtual void update(const sf::Time& dt) override;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
virtual void setRect(const sf::FloatRect& rect) override;
|
|
||||||
virtual void setPosition(const sf::Vector2f& position) override;
|
|
||||||
virtual void move(const sf::Vector2f& delta) override;
|
virtual void move(const sf::Vector2f& delta) override;
|
||||||
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
||||||
virtual void setVisibility(bool is_visible = true) override;
|
virtual void setVisibility(bool is_visible = true) override;
|
||||||
|
|
||||||
|
virtual void setRect(const sf::FloatRect& rect) override;
|
||||||
|
virtual sf::FloatRect rect() const override;
|
||||||
|
|
||||||
|
virtual void setPosition(const sf::Vector2f& position) override;
|
||||||
|
virtual sf::Vector2f position() const override;
|
||||||
|
|
||||||
void addPushButton(const std::shared_ptr<PushButton>& button);
|
void addPushButton(const std::shared_ptr<PushButton>& button);
|
||||||
void addCascadeButton(const std::shared_ptr<CascadeMenuButton>& button);
|
void addCascadeButton(const std::shared_ptr<CascadeMenuButton>& button);
|
||||||
void addSeparator();
|
void addSeparator();
|
||||||
|
|
|
@ -37,3 +37,12 @@ bool MenuSeparator::isUnderMouse(int mouse_x, int mouse_y) const
|
||||||
return _is_visible && _rect.contains(mouse_x, mouse_y);
|
return _is_visible && _rect.contains(mouse_x, mouse_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::FloatRect MenuSeparator::rect() const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f MenuSeparator::position() const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
|
@ -10,11 +10,15 @@ public:
|
||||||
virtual void input(const sf::Event& event) override;
|
virtual void input(const sf::Event& event) override;
|
||||||
virtual void update(const sf::Time& dt) override;
|
virtual void update(const sf::Time& dt) override;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
virtual void setRect(const sf::FloatRect& rect) override;
|
|
||||||
virtual void setPosition(const sf::Vector2f& position) override;
|
|
||||||
virtual void move(const sf::Vector2f& delta) override;
|
virtual void move(const sf::Vector2f& delta) override;
|
||||||
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
|
||||||
|
|
||||||
|
virtual void setRect(const sf::FloatRect& rect) override;
|
||||||
|
virtual sf::FloatRect rect() const override;
|
||||||
|
|
||||||
|
virtual void setPosition(const sf::Vector2f& position) override;
|
||||||
|
virtual sf::Vector2f position() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::VertexArray _line;
|
sf::VertexArray _line;
|
||||||
sf::FloatRect _rect;
|
sf::FloatRect _rect;
|
||||||
|
|
|
@ -14,11 +14,15 @@ public:
|
||||||
virtual void input(const sf::Event& event) = 0;
|
virtual void input(const sf::Event& event) = 0;
|
||||||
virtual void update(const sf::Time& dt) = 0;
|
virtual void update(const sf::Time& dt) = 0;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const = 0;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const = 0;
|
||||||
virtual void setRect(const sf::FloatRect& rect) = 0;
|
|
||||||
virtual void setPosition(const sf::Vector2f& position) = 0;
|
|
||||||
virtual void move(const sf::Vector2f& delta) = 0;
|
virtual void move(const sf::Vector2f& delta) = 0;
|
||||||
virtual bool isUnderMouse(int mouse_x, int mouse_y) const = 0;
|
virtual bool isUnderMouse(int mouse_x, int mouse_y) const = 0;
|
||||||
|
|
||||||
|
virtual void setRect(const sf::FloatRect& rect) = 0;
|
||||||
|
virtual sf::FloatRect rect() const = 0;
|
||||||
|
|
||||||
|
virtual void setPosition(const sf::Vector2f& position) = 0;
|
||||||
|
virtual sf::Vector2f position() const = 0;
|
||||||
|
|
||||||
virtual void setVisibility(bool is_visible = true);
|
virtual void setVisibility(bool is_visible = true);
|
||||||
bool isVisible() const;
|
bool isVisible() const;
|
||||||
|
|
||||||
|
|
|
@ -108,3 +108,12 @@ void Window::addBarButton(const std::string &text, std::function<void(void)> cal
|
||||||
addChild(b);
|
addChild(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::FloatRect Window::rect() const
|
||||||
|
{
|
||||||
|
return _window_content.getGlobalBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f Window::position() const
|
||||||
|
{
|
||||||
|
return _window_content.getPosition();
|
||||||
|
}
|
||||||
|
|
|
@ -13,11 +13,15 @@ public:
|
||||||
virtual void input(const sf::Event& event) override;
|
virtual void input(const sf::Event& event) override;
|
||||||
virtual void update(const sf::Time& dt) override;
|
virtual void update(const sf::Time& dt) override;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
virtual void setRect(const sf::FloatRect& rect) override;
|
|
||||||
virtual void setPosition(const sf::Vector2f& position) override;
|
|
||||||
virtual void move(const sf::Vector2f& delta) override;
|
virtual void move(const sf::Vector2f& delta) override;
|
||||||
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override final;
|
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override final;
|
||||||
|
|
||||||
|
virtual void setRect(const sf::FloatRect& rect) override;
|
||||||
|
virtual sf::FloatRect rect() const override;
|
||||||
|
|
||||||
|
virtual void setPosition(const sf::Vector2f& position) override;
|
||||||
|
virtual sf::Vector2f position() const override;
|
||||||
|
|
||||||
void addBarButton(const std::string& text, std::function<void(void)> callback);
|
void addBarButton(const std::string& text, std::function<void(void)> callback);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -3,18 +3,27 @@
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
constexpr microsec MICROSECONDS_IN_MINUTE = 60000000;
|
constexpr float MICROSECONDS_IN_MINUTE_f = 60000000.;
|
||||||
|
|
||||||
BPMCalculator::BPMCalculator(const std::shared_ptr<Music>& music) :
|
BPMCalculator::BPMCalculator(const std::shared_ptr<Music>& music) :
|
||||||
_music(music),
|
_music(music)
|
||||||
_previous_click_offset(0)
|
{
|
||||||
{}
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPMCalculator::reset()
|
||||||
|
{
|
||||||
|
_calculating = false;
|
||||||
|
_deltas.clear();
|
||||||
|
_previous_click_offset = 0;
|
||||||
|
_approximated_bpm = 0;
|
||||||
|
_need_recalculate = true;
|
||||||
|
}
|
||||||
|
|
||||||
void BPMCalculator::setMusic(const std::shared_ptr<Music>& music)
|
void BPMCalculator::setMusic(const std::shared_ptr<Music>& music)
|
||||||
{
|
{
|
||||||
_deltas.clear();
|
|
||||||
_previous_click_offset = 0;
|
|
||||||
_music = music;
|
_music = music;
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Music> BPMCalculator::music() const
|
std::shared_ptr<Music> BPMCalculator::music() const
|
||||||
|
@ -24,15 +33,23 @@ std::shared_ptr<Music> BPMCalculator::music() const
|
||||||
|
|
||||||
void BPMCalculator::start()
|
void BPMCalculator::start()
|
||||||
{
|
{
|
||||||
_deltas.clear();
|
reset();
|
||||||
_previous_click_offset = 0;
|
|
||||||
|
_calculating = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPMCalculator::stop()
|
||||||
|
{
|
||||||
|
_calculating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculator::click()
|
void BPMCalculator::click()
|
||||||
{
|
{
|
||||||
const microsec click_offset = _music->fetchOffset();
|
if (!_calculating)
|
||||||
|
return;
|
||||||
|
|
||||||
std::cout << click_offset << "\n\n\n\n";
|
const microsec click_offset = _music->fetchOffset();
|
||||||
|
_need_recalculate = true;
|
||||||
|
|
||||||
if (_previous_click_offset == 0)
|
if (_previous_click_offset == 0)
|
||||||
{
|
{
|
||||||
|
@ -46,14 +63,57 @@ void BPMCalculator::click()
|
||||||
_previous_click_offset = click_offset;
|
_previous_click_offset = click_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BPMCalculator::getCurrentApproximation() const
|
float BPMCalculator::fetchCurrentBPMApproximation()
|
||||||
{
|
{
|
||||||
|
if (!_need_recalculate)
|
||||||
|
return _approximated_bpm;
|
||||||
|
|
||||||
|
_need_recalculate = false;
|
||||||
|
|
||||||
const microsec sum = std::accumulate(_deltas.begin(), _deltas.end(), 0);
|
const microsec sum = std::accumulate(_deltas.begin(), _deltas.end(), 0);
|
||||||
|
bool hasEnoughDeltas = _deltas.size() >= 8;
|
||||||
|
|
||||||
std::cout << "S: " << sum << " _deltas.size(): " << _deltas.size();
|
_approximated_bpm = (!hasEnoughDeltas)
|
||||||
std::cout << "\n " << (static_cast<float>(sum) / static_cast<float>(_deltas.size())) << '\n';
|
? 0.
|
||||||
|
: calculateBPM(sum, _deltas.size());
|
||||||
|
|
||||||
return (sum == 0 || _deltas.size() < 8)
|
return _approximated_bpm;
|
||||||
? 0.
|
}
|
||||||
: static_cast<int>(static_cast<float>(MICROSECONDS_IN_MINUTE) / (static_cast<float>(sum) / static_cast<float>(_deltas.size())));
|
|
||||||
|
float BPMCalculator::calculateBPM(microsec all_microseconds, std::size_t beats_amount) const
|
||||||
|
{
|
||||||
|
if (beats_amount == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
float relation = static_cast<float>(all_microseconds)
|
||||||
|
/ static_cast<float>(beats_amount);
|
||||||
|
|
||||||
|
return static_cast<float>(1. / relation);
|
||||||
|
}
|
||||||
|
|
||||||
|
microsec BPMCalculator::getStartingOffset() const
|
||||||
|
{
|
||||||
|
return _first_click_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPMCalculator::setStartingOffset(microsec offset)
|
||||||
|
{
|
||||||
|
_first_click_offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPMCalculator::moveStartingOffsetBy(microsec shift)
|
||||||
|
{
|
||||||
|
_first_click_offset += shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
microsec BPMCalculator::fetchTimeUntilNextBeat()
|
||||||
|
{
|
||||||
|
const microsec actual_offset = _music->fetchOffset() - _first_click_offset;
|
||||||
|
|
||||||
|
return fetchBeatInterval() % actual_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
microsec BPMCalculator::fetchBeatInterval()
|
||||||
|
{
|
||||||
|
return static_cast<microsec>(1. / fetchCurrentBPMApproximation());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue