Refactor music position, implement flow for Editor, link everything together
This commit is contained in:
parent
79543f6b93
commit
5e3ddccac0
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "core/inputtype.h"
|
#include "core/inputtype.h"
|
||||||
|
#include "core/updatedata.h"
|
||||||
#include "core/bpmsection.h"
|
#include "core/bpmsection.h"
|
||||||
|
|
||||||
class Editor
|
class Editor
|
||||||
|
@ -10,7 +11,7 @@ public:
|
||||||
virtual ~Editor() = default;
|
virtual ~Editor() = default;
|
||||||
|
|
||||||
virtual void input(PlayerInput&& inputdata) = 0;
|
virtual void input(PlayerInput&& inputdata) = 0;
|
||||||
virtual void update(const sf::Time& dt) = 0;
|
virtual void update(UpdateData&& updatedata) = 0;
|
||||||
virtual void draw() const = 0;
|
virtual void draw() const = 0;
|
||||||
|
|
||||||
inline void setBPMSections(const std::set<BPMSection, BPMSectionCompt>& sections) noexcept
|
inline void setBPMSections(const std::set<BPMSection, BPMSectionCompt>& sections) noexcept
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/inputtype.h"
|
#include "core/inputtype.h"
|
||||||
|
#include "core/updatedata.h"
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
|
@ -10,6 +11,6 @@ public:
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
|
|
||||||
virtual void input(PlayerInput&& inputdata) = 0;
|
virtual void input(PlayerInput&& inputdata) = 0;
|
||||||
virtual void update() = 0;
|
virtual void update(UpdateData&& updatedata) = 0;
|
||||||
virtual void draw() const = 0;
|
virtual void draw() const = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,9 @@ public:
|
||||||
expire(_last_visible_note);
|
expire(_last_visible_note);
|
||||||
expire(_active_note);
|
expire(_active_note);
|
||||||
|
|
||||||
|
if (isExpired(_top_note))
|
||||||
|
return;
|
||||||
|
|
||||||
fetchVisibleNotes();
|
fetchVisibleNotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,21 +58,20 @@ public:
|
||||||
{
|
{
|
||||||
_current_offset = offset;
|
_current_offset = offset;
|
||||||
|
|
||||||
|
if (isExpired(_top_note))
|
||||||
|
return;
|
||||||
|
|
||||||
checkCurrentActiveNote();
|
checkCurrentActiveNote();
|
||||||
checkForNextActiveNote();
|
checkForNextActiveNote();
|
||||||
updateVisibleSprites(_current_offset);
|
updateVisibleSprites(_current_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawVisibleNotes() const
|
std::pair<Iterator, Iterator> getVisibleNotes() const
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
if (nothingToDraw())
|
||||||
return;
|
return std::pair<Iterator, Iterator>();
|
||||||
|
|
||||||
std::for_each(_first_visible_note, _last_visible_note,
|
return std::make_pair(_first_visible_note, _last_visible_note);
|
||||||
[](const auto& note)
|
|
||||||
{
|
|
||||||
note->draw();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchVisibleNotes()
|
void fetchVisibleNotes()
|
||||||
|
@ -80,6 +82,9 @@ public:
|
||||||
|
|
||||||
void findLastVisibleNote(const microsec& music_offset)
|
void findLastVisibleNote(const microsec& music_offset)
|
||||||
{
|
{
|
||||||
|
if (isExpired(_top_note))
|
||||||
|
return;
|
||||||
|
|
||||||
Iterator note_iterator = _top_note;
|
Iterator note_iterator = _top_note;
|
||||||
while (isVisiblyClose(note_iterator, music_offset))
|
while (isVisiblyClose(note_iterator, music_offset))
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SFML/System/Time.hpp>
|
||||||
|
#include "tools/mathutils.h"
|
||||||
|
|
||||||
|
struct UpdateData
|
||||||
|
{
|
||||||
|
const microsec timestamp;
|
||||||
|
const sf::Time dt;
|
||||||
|
};
|
|
@ -2,15 +2,17 @@
|
||||||
|
|
||||||
ClassicEditor::ClassicEditor(std::shared_ptr<ClassicGraphicsManager>&& manager) :
|
ClassicEditor::ClassicEditor(std::shared_ptr<ClassicGraphicsManager>&& manager) :
|
||||||
_graphics_manager(manager),
|
_graphics_manager(manager),
|
||||||
_selected_type(Type::UP)
|
_selected_type(Type::UP),
|
||||||
|
_current_time(0)
|
||||||
{
|
{
|
||||||
_context.graphics_manager = _graphics_manager;
|
_context.graphics_manager = _graphics_manager;
|
||||||
|
_timeline.setNotes({}, 1648648);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::input(PlayerInput&& inputdata)
|
void ClassicEditor::input(PlayerInput&& inputdata)
|
||||||
{
|
{
|
||||||
|
_current_time = inputdata.timestamp;
|
||||||
const auto& event = inputdata.event;
|
const auto& event = inputdata.event;
|
||||||
const auto offset = _music.fetchOffset();
|
|
||||||
|
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
|
@ -20,13 +22,13 @@ void ClassicEditor::input(PlayerInput&& inputdata)
|
||||||
|
|
||||||
case sf::Event::MouseButtonPressed:
|
case sf::Event::MouseButtonPressed:
|
||||||
{
|
{
|
||||||
const auto note = _timeline.getNoteBy(offset);
|
const auto note = _timeline.getNoteBy(_current_time);
|
||||||
if (_timeline.isExpired(note))
|
if (_timeline.isExpired(note))
|
||||||
{
|
{
|
||||||
NoteInitializer init;
|
NoteInitializer init;
|
||||||
init.context = &_context;
|
init.context = &_context;
|
||||||
init.intervals = {};
|
init.intervals = {};
|
||||||
init.perfect_offset = offset;
|
init.perfect_offset = _current_time;
|
||||||
|
|
||||||
ElementInitializer elem_init;
|
ElementInitializer elem_init;
|
||||||
elem_init.type = _selected_type;
|
elem_init.type = _selected_type;
|
||||||
|
@ -45,18 +47,22 @@ void ClassicEditor::input(PlayerInput&& inputdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::update(const sf::Time& dt)
|
void ClassicEditor::update(UpdateData&& updatedata)
|
||||||
{
|
{
|
||||||
(void)dt;
|
_timeline.update(updatedata.timestamp);
|
||||||
// TODO!!!
|
|
||||||
|
|
||||||
_timeline.update(_music.fetchOffset());
|
|
||||||
_timeline.fetchVisibleNotes();
|
_timeline.fetchVisibleNotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::draw() const
|
void ClassicEditor::draw() const
|
||||||
{
|
{
|
||||||
_timeline.drawVisibleNotes();
|
const auto& graphics_manager = _graphics_manager;
|
||||||
|
auto notes = _timeline.getVisibleNotes();
|
||||||
|
|
||||||
|
std::for_each(notes.first, notes.second,
|
||||||
|
[graphics_manager](const auto& note)
|
||||||
|
{
|
||||||
|
note->draw();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::selectNoteType(Type type) noexcept
|
void ClassicEditor::selectNoteType(Type type) noexcept
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "core/editor.h"
|
#include "core/editor.h"
|
||||||
#include "core/timeline.h"
|
#include "core/timeline.h"
|
||||||
#include "tools/music.h"
|
|
||||||
|
|
||||||
#include "mockclassicnote.h"
|
#include "mockclassicnote.h"
|
||||||
|
|
||||||
|
@ -16,17 +15,17 @@ public:
|
||||||
explicit ClassicEditor(std::shared_ptr<ClassicGraphicsManager>&& manager);
|
explicit ClassicEditor(std::shared_ptr<ClassicGraphicsManager>&& manager);
|
||||||
|
|
||||||
virtual void input(PlayerInput&& inputdata) override;
|
virtual void input(PlayerInput&& inputdata) override;
|
||||||
virtual void update(const sf::Time& dt) override;
|
virtual void update(UpdateData&& updatedata) override;
|
||||||
virtual void draw() const override;
|
virtual void draw() const override;
|
||||||
|
|
||||||
void selectNoteType(Type type) noexcept;
|
void selectNoteType(Type type) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Music _music;
|
|
||||||
Context _context;
|
Context _context;
|
||||||
|
|
||||||
std::shared_ptr<ClassicGraphicsManager> _graphics_manager;
|
std::shared_ptr<ClassicGraphicsManager> _graphics_manager;
|
||||||
Timeline<MockClassicNote> _timeline;
|
Timeline<MockClassicNote> _timeline;
|
||||||
|
|
||||||
Type _selected_type;
|
Type _selected_type;
|
||||||
|
microsec _current_time;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "classicgame.h"
|
#include "classicgame.h"
|
||||||
#include "classicnote.h"
|
#include "classicnote.h"
|
||||||
#include "classicmapcreator.h"
|
#include "classicmapcreator.h"
|
||||||
|
#include "graphics/classicgraphicsmanager.h"
|
||||||
#include "holdmanager.h"
|
#include "holdmanager.h"
|
||||||
|
|
||||||
ClassicGame::ClassicGame(std::shared_ptr<ClassicGraphicsManager>&& manager) :
|
ClassicGame::ClassicGame(std::shared_ptr<ClassicGraphicsManager>&& manager) :
|
||||||
|
@ -59,16 +60,11 @@ void ClassicGame::run()
|
||||||
_context.graphics_manager = _graphics_manager;
|
_context.graphics_manager = _graphics_manager;
|
||||||
|
|
||||||
auto beatmap = classic::createBeatmap("aa", _context);
|
auto beatmap = classic::createBeatmap("aa", _context);
|
||||||
_music.openFromFile("METEOR.flac");
|
|
||||||
_music.setVolume(10);
|
|
||||||
_music.play();
|
|
||||||
_timeline.setNotes(beatmap.notes, beatmap.visibility_offset);
|
_timeline.setNotes(beatmap.notes, beatmap.visibility_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::input(PlayerInput&& inputdata)
|
void ClassicGame::input(PlayerInput&& inputdata)
|
||||||
{
|
{
|
||||||
inputdata.timestamp = _music.fetchOffset();
|
|
||||||
|
|
||||||
switch (inputdata.event.type)
|
switch (inputdata.event.type)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
@ -77,20 +73,6 @@ void ClassicGame::input(PlayerInput&& inputdata)
|
||||||
|
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
{
|
{
|
||||||
if (inputdata.event.key.code == sf::Keyboard::Space)
|
|
||||||
{
|
|
||||||
if (_music.isPaused())
|
|
||||||
{
|
|
||||||
_music.play();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_music.pause();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto note_it = _timeline.getActiveNote();
|
auto note_it = _timeline.getActiveNote();
|
||||||
|
|
||||||
if (!_timeline.isExpired(note_it))
|
if (!_timeline.isExpired(note_it))
|
||||||
|
@ -111,13 +93,20 @@ void ClassicGame::input(PlayerInput&& inputdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::update()
|
void ClassicGame::update(UpdateData&& updatedata)
|
||||||
{
|
{
|
||||||
_timeline.update(_music.fetchOffset());
|
_timeline.update(updatedata.timestamp);
|
||||||
_timeline.fetchVisibleNotes();
|
_timeline.fetchVisibleNotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::draw() const
|
void ClassicGame::draw() const
|
||||||
{
|
{
|
||||||
_timeline.drawVisibleNotes();
|
const auto& graphics_manager = _graphics_manager;
|
||||||
|
auto notes = _timeline.getVisibleNotes();
|
||||||
|
|
||||||
|
std::for_each(notes.first, notes.second,
|
||||||
|
[graphics_manager](const auto& note)
|
||||||
|
{
|
||||||
|
note->draw();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,8 @@
|
||||||
|
|
||||||
#include "core/game.h"
|
#include "core/game.h"
|
||||||
#include "core/timeline.h"
|
#include "core/timeline.h"
|
||||||
#include "tools/music.h"
|
|
||||||
|
|
||||||
#include "classicmode/context.h"
|
#include "context.h"
|
||||||
#include "classicnote.h"
|
#include "classicnote.h"
|
||||||
|
|
||||||
#include "classicmode/classicactions.h"
|
#include "classicmode/classicactions.h"
|
||||||
|
@ -27,7 +26,7 @@ public:
|
||||||
virtual void run() override;
|
virtual void run() override;
|
||||||
|
|
||||||
virtual void input(PlayerInput&& inputdata) override;
|
virtual void input(PlayerInput&& inputdata) override;
|
||||||
virtual void update() override;
|
virtual void update(UpdateData&& updatedata) override;
|
||||||
virtual void draw() const override;
|
virtual void draw() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -42,6 +41,5 @@ private:
|
||||||
sf::SoundBuffer _slap_buffer;
|
sf::SoundBuffer _slap_buffer;
|
||||||
sf::Sound _slap;
|
sf::Sound _slap;
|
||||||
|
|
||||||
Music _music;
|
|
||||||
Context _context;
|
Context _context;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "classicmode/context.h"
|
#include "context.h"
|
||||||
#include "core/note.h"
|
#include "core/note.h"
|
||||||
#include "core/precisionevaluator.h"
|
#include "core/precisionevaluator.h"
|
||||||
#include "classicmode/noteinitializer.h"
|
#include "classicmode/noteinitializer.h"
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class ClassicGraphicsManager;
|
||||||
|
class HoldManager;
|
||||||
|
|
||||||
|
struct Context
|
||||||
|
{
|
||||||
|
std::shared_ptr<ClassicGraphicsManager> graphics_manager;
|
||||||
|
std::shared_ptr<HoldManager> hold_manager;
|
||||||
|
};
|
|
@ -23,6 +23,9 @@ EditorState::~EditorState()
|
||||||
|
|
||||||
void EditorState::input(const sf::Event& event)
|
void EditorState::input(const sf::Event& event)
|
||||||
{
|
{
|
||||||
|
if (event.key.code == sf::Keyboard::Space && event.type == sf::Event::KeyReleased)
|
||||||
|
_music.isPaused() ? _music.play() : _music.pause();
|
||||||
|
|
||||||
_group->input(event);
|
_group->input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,19 +41,57 @@ void EditorState::draw() const
|
||||||
|
|
||||||
void EditorState::enter()
|
void EditorState::enter()
|
||||||
{
|
{
|
||||||
|
_music.openFromFile("Uta-test.flac");
|
||||||
|
_music.setVolume(5);
|
||||||
|
|
||||||
auto& group = _group;
|
auto& group = _group;
|
||||||
auto& music = _music;
|
auto& music = _music;
|
||||||
auto& editor = _editor;
|
auto& editor = _editor;
|
||||||
|
|
||||||
_music->openFromFile("Uta-test.flac");
|
_bpm_calculator = std::make_shared<BPMCalculator>();
|
||||||
_music->setVolume(5);
|
auto& bpm_calculator = _bpm_calculator;
|
||||||
|
|
||||||
_bpm_calculator = std::make_shared<BPMCalculator>(_music);
|
|
||||||
std::shared_ptr<BPMCalculatorWidget> bpm_widget = std::make_shared<BPMCalculatorWidget>(_bpm_calculator, _font);
|
std::shared_ptr<BPMCalculatorWidget> bpm_widget = std::make_shared<BPMCalculatorWidget>(_bpm_calculator, _font);
|
||||||
bpm_widget->init(_editor);
|
|
||||||
|
auto button_start = std::make_shared<PushButton>("Start", _font);
|
||||||
|
auto button_stop = std::make_shared<PushButton>("Stop", _font);
|
||||||
|
auto button_apply = std::make_shared<PushButton>("Apply", _font);
|
||||||
|
|
||||||
|
button_start->setCallback([bpm_calculator, button_start, button_stop, &music]()
|
||||||
|
{
|
||||||
|
music.play();
|
||||||
|
bpm_calculator->start();
|
||||||
|
button_start->setVisibility(false);
|
||||||
|
button_stop->setVisibility(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
button_stop->setCallback([bpm_calculator, button_start, button_stop, &music]()
|
||||||
|
{
|
||||||
|
music.stop();
|
||||||
|
bpm_calculator->stop();
|
||||||
|
button_start->setVisibility(true);
|
||||||
|
button_stop->setVisibility(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
button_apply->setCallback([&editor, bpm_calculator]()
|
||||||
|
{
|
||||||
|
BPMSection section;
|
||||||
|
section.bpm = bpm_calculator->fetchApproximatedInfo().BPM;
|
||||||
|
section.fraction = 2;
|
||||||
|
section.offset_start = bpm_calculator->getStartingOffset();
|
||||||
|
|
||||||
|
editor->insertBPMSection(std::move(section));
|
||||||
|
});
|
||||||
|
|
||||||
|
BPMCalculatorWidget::Init bpm_widget_init;
|
||||||
|
bpm_widget_init.stop = button_stop;
|
||||||
|
bpm_widget_init.apply = button_apply;
|
||||||
|
bpm_widget_init.start = button_start;
|
||||||
|
bpm_widget_init.current_time = [&music]() -> microsec { return music.fetchOffset(); };
|
||||||
|
|
||||||
|
bpm_widget->init(std::move(bpm_widget_init));
|
||||||
const auto bpm_widget_callback = [&group, bpm_widget=bpm_widget, &music]()
|
const auto bpm_widget_callback = [&group, bpm_widget=bpm_widget, &music]()
|
||||||
{
|
{
|
||||||
music->stop();
|
music.stop();
|
||||||
bpm_widget->setVisibility(false);
|
bpm_widget->setVisibility(false);
|
||||||
group->unblock();
|
group->unblock();
|
||||||
};
|
};
|
||||||
|
@ -113,14 +154,14 @@ void EditorState::enter()
|
||||||
editor->draw();
|
editor->draw();
|
||||||
};
|
};
|
||||||
|
|
||||||
callbacks.onInput = [&editor](const sf::Event& event)
|
callbacks.onInput = [&editor, &music](const sf::Event& event)
|
||||||
{
|
{
|
||||||
editor->input(PlayerInput{0, event});
|
editor->input(PlayerInput{music.fetchOffset(), event});
|
||||||
};
|
};
|
||||||
|
|
||||||
callbacks.onUpdate = [&editor](const sf::Time& dt)
|
callbacks.onUpdate = [&editor, &music](const sf::Time& dt)
|
||||||
{
|
{
|
||||||
editor->update(dt);
|
editor->update(UpdateData{music.fetchOffset(), dt});
|
||||||
};
|
};
|
||||||
|
|
||||||
auto editor_widget = std::make_shared<EditorWidget>(std::move(callbacks));
|
auto editor_widget = std::make_shared<EditorWidget>(std::move(callbacks));
|
||||||
|
|
|
@ -33,7 +33,7 @@ private:
|
||||||
|
|
||||||
Callbacks _callbacks;
|
Callbacks _callbacks;
|
||||||
|
|
||||||
std::shared_ptr<Music> _music;
|
Music _music;
|
||||||
std::shared_ptr<BPMCalculator> _bpm_calculator;
|
std::shared_ptr<BPMCalculator> _bpm_calculator;
|
||||||
std::shared_ptr<Group> _group;
|
std::shared_ptr<Group> _group;
|
||||||
|
|
||||||
|
|
|
@ -13,17 +13,15 @@ GameState::GameState(sf::RenderWindow& game_window, const std::shared_ptr<Game>&
|
||||||
|
|
||||||
void GameState::input(const sf::Event& event)
|
void GameState::input(const sf::Event& event)
|
||||||
{
|
{
|
||||||
_game->input({0, event});
|
if (event.key.code == sf::Keyboard::Space && event.type == sf::Event::KeyReleased)
|
||||||
|
_music.isPaused() ? _music.play() : _music.pause();
|
||||||
|
|
||||||
|
_game->input(PlayerInput{_music.fetchOffset(), event});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::update(const sf::Time& dt)
|
void GameState::update(const sf::Time& dt)
|
||||||
{
|
{
|
||||||
(void)dt;
|
_game->update(UpdateData{_music.fetchOffset(), dt});
|
||||||
// !!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
// TODO.
|
|
||||||
//
|
|
||||||
// Oh dude... hang in there
|
|
||||||
_game->update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::draw() const
|
void GameState::draw() const
|
||||||
|
@ -34,6 +32,10 @@ void GameState::draw() const
|
||||||
void GameState::enter()
|
void GameState::enter()
|
||||||
{
|
{
|
||||||
_game->run();
|
_game->run();
|
||||||
|
|
||||||
|
_music.openFromFile("METEOR.flac");
|
||||||
|
_music.setVolume(10);
|
||||||
|
_music.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::leave()
|
void GameState::leave()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
|
#include "tools/music.h"
|
||||||
#include <SFML/Graphics/RenderWindow.hpp>
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
|
|
||||||
class Group;
|
class Group;
|
||||||
|
@ -28,6 +29,7 @@ public:
|
||||||
virtual void leave() override;
|
virtual void leave() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Music _music;
|
||||||
std::shared_ptr<Game> _game;
|
std::shared_ptr<Game> _game;
|
||||||
sf::RenderWindow& _game_window;
|
sf::RenderWindow& _game_window;
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ void BPMCalculatorWidget::input(const sf::Event& event)
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space)
|
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space)
|
||||||
{
|
{
|
||||||
_bpm_calculator->click();
|
_bpm_calculator->click(_current_time());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ void BPMCalculatorWidget::update(const sf::Time& dt)
|
||||||
{
|
{
|
||||||
_bpm_value.setString(std::to_string(static_cast<int>(beat_info.BPM)));
|
_bpm_value.setString(std::to_string(static_cast<int>(beat_info.BPM)));
|
||||||
|
|
||||||
const microsec until_beat = _bpm_calculator->fetchTimeUntilNextBeat();
|
const microsec until_beat = _bpm_calculator->fetchTimeUntilNextBeat(_current_time());
|
||||||
const auto time_relation = static_cast<long double>(beat_info.interval) / static_cast<long double>(until_beat);
|
const auto time_relation = static_cast<long double>(beat_info.interval) / static_cast<long double>(until_beat);
|
||||||
const auto slider_path_left = _slider->rect().width / time_relation;
|
const auto slider_path_left = _slider->rect().width / time_relation;
|
||||||
if (slider_path_left < 50)
|
if (slider_path_left < 50)
|
||||||
|
@ -111,39 +111,13 @@ void BPMCalculatorWidget::setPosition(const sf::Vector2f &position)
|
||||||
Window::setPosition(position);
|
Window::setPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculatorWidget::init(const std::unique_ptr<Editor>& _editor)
|
void BPMCalculatorWidget::init(Init &&init)
|
||||||
{
|
{
|
||||||
auto& bpm_calculator = _bpm_calculator;
|
_button_start = init.start;
|
||||||
|
_button_stop = init.stop;
|
||||||
|
_button_apply = init.apply;
|
||||||
|
|
||||||
_button_start = std::make_shared<PushButton>("Start", _font);
|
_current_time = init.current_time;
|
||||||
_button_stop = std::make_shared<PushButton>("Stop", _font);
|
|
||||||
_button_apply = std::make_shared<PushButton>("Apply", _font);
|
|
||||||
|
|
||||||
_button_start->setCallback([bpm_calculator, button_start=_button_start, button_stop=_button_stop]()
|
|
||||||
{
|
|
||||||
bpm_calculator->music()->play(); // Remove when global play/stop available
|
|
||||||
bpm_calculator->start();
|
|
||||||
button_start->setVisibility(false);
|
|
||||||
button_stop->setVisibility(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
_button_stop->setCallback([bpm_calculator, button_start=_button_start, button_stop=_button_stop]()
|
|
||||||
{
|
|
||||||
bpm_calculator->music()->stop(); // Remove when global play/stop available
|
|
||||||
bpm_calculator->stop();
|
|
||||||
button_start->setVisibility(true);
|
|
||||||
button_stop->setVisibility(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
_button_apply->setCallback([&_editor, bpm_calculator]()
|
|
||||||
{
|
|
||||||
BPMSection section;
|
|
||||||
section.bpm = bpm_calculator->fetchApproximatedInfo().BPM;
|
|
||||||
section.fraction = 2;
|
|
||||||
section.offset_start = bpm_calculator->getStartingOffset();
|
|
||||||
|
|
||||||
_editor->insertBPMSection(std::move(section));
|
|
||||||
});
|
|
||||||
|
|
||||||
addChild(_button_start);
|
addChild(_button_start);
|
||||||
addChild(_button_stop);
|
addChild(_button_stop);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <SFML/Graphics/Text.hpp>
|
#include <SFML/Graphics/Text.hpp>
|
||||||
#include <SFML/Audio/Sound.hpp>
|
#include <SFML/Audio/Sound.hpp>
|
||||||
#include <SFML/Audio/SoundBuffer.hpp>
|
#include <SFML/Audio/SoundBuffer.hpp>
|
||||||
|
#include "tools/mathutils.h"
|
||||||
|
|
||||||
class BPMCalculator;
|
class BPMCalculator;
|
||||||
class Editor;
|
class Editor;
|
||||||
|
@ -15,6 +16,15 @@ class Editor;
|
||||||
class BPMCalculatorWidget : public Window
|
class BPMCalculatorWidget : public Window
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
struct Init
|
||||||
|
{
|
||||||
|
std::shared_ptr<PushButton> start;
|
||||||
|
std::shared_ptr<PushButton> stop;
|
||||||
|
std::shared_ptr<PushButton> apply;
|
||||||
|
std::function<microsec(void)> current_time;
|
||||||
|
};
|
||||||
|
|
||||||
explicit BPMCalculatorWidget(const std::shared_ptr<BPMCalculator>& bpm_calculator, const std::shared_ptr<sf::Font> &font);
|
explicit BPMCalculatorWidget(const std::shared_ptr<BPMCalculator>& bpm_calculator, const std::shared_ptr<sf::Font> &font);
|
||||||
|
|
||||||
virtual void input(const sf::Event& event) override;
|
virtual void input(const sf::Event& event) override;
|
||||||
|
@ -26,7 +36,7 @@ public:
|
||||||
|
|
||||||
virtual void setVisibility(bool is_visible = true) override;
|
virtual void setVisibility(bool is_visible = true) override;
|
||||||
|
|
||||||
void init(const std::unique_ptr<Editor>& _editor);
|
void init(Init&& init);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<PushButton> _button_start;
|
std::shared_ptr<PushButton> _button_start;
|
||||||
|
@ -41,5 +51,6 @@ private:
|
||||||
bool _ticked;
|
bool _ticked;
|
||||||
|
|
||||||
sf::Text _bpm_value;
|
sf::Text _bpm_value;
|
||||||
|
std::function<microsec(void)> _current_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,16 @@
|
||||||
class BPMCalculator
|
class BPMCalculator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit BPMCalculator(const std::shared_ptr<Music>& music);
|
explicit BPMCalculator();
|
||||||
|
|
||||||
void setMusic(const std::shared_ptr<Music>& music);
|
|
||||||
std::shared_ptr<Music> music() const;
|
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
void click();
|
void click(const microsec& offset);
|
||||||
|
|
||||||
bool calculating() const;
|
bool calculating() const;
|
||||||
|
|
||||||
const beat_utils::BeatInfo& fetchApproximatedInfo();
|
const beat_utils::BeatInfo& fetchApproximatedInfo();
|
||||||
microsec fetchTimeUntilNextBeat();
|
microsec fetchTimeUntilNextBeat(const microsec& offset);
|
||||||
|
|
||||||
microsec getStartingOffset() const;
|
microsec getStartingOffset() const;
|
||||||
void setStartingOffset(microsec offset);
|
void setStartingOffset(microsec offset);
|
||||||
|
@ -29,7 +26,6 @@ private:
|
||||||
bool _need_recalculate;
|
bool _need_recalculate;
|
||||||
bool _calculating;
|
bool _calculating;
|
||||||
|
|
||||||
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;
|
microsec _first_click_offset;
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
BPMCalculator::BPMCalculator(const std::shared_ptr<Music>& music) :
|
BPMCalculator::BPMCalculator()
|
||||||
_music(music)
|
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
@ -18,17 +17,6 @@ void BPMCalculator::reset()
|
||||||
_need_recalculate = true;
|
_need_recalculate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculator::setMusic(const std::shared_ptr<Music>& music)
|
|
||||||
{
|
|
||||||
_music = music;
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Music> BPMCalculator::music() const
|
|
||||||
{
|
|
||||||
return _music;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BPMCalculator::start()
|
void BPMCalculator::start()
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
@ -46,25 +34,24 @@ bool BPMCalculator::calculating() const
|
||||||
return _calculating;
|
return _calculating;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculator::click()
|
void BPMCalculator::click(const microsec &offset)
|
||||||
{
|
{
|
||||||
if (!_calculating)
|
if (!_calculating)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const microsec click_offset = _music->fetchOffset();
|
|
||||||
_need_recalculate = true;
|
_need_recalculate = true;
|
||||||
|
|
||||||
if (_previous_click_offset == 0)
|
if (_previous_click_offset == 0)
|
||||||
{
|
{
|
||||||
_previous_click_offset = click_offset;
|
_previous_click_offset = offset;
|
||||||
_first_click_offset = click_offset;
|
_first_click_offset = offset;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const microsec delta = click_offset - _previous_click_offset;
|
const microsec delta = offset - _previous_click_offset;
|
||||||
_deltas.emplace_back(delta);
|
_deltas.emplace_back(delta);
|
||||||
|
|
||||||
_previous_click_offset = click_offset;
|
_previous_click_offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
const beat_utils::BeatInfo& BPMCalculator::fetchApproximatedInfo()
|
const beat_utils::BeatInfo& BPMCalculator::fetchApproximatedInfo()
|
||||||
|
@ -98,9 +85,9 @@ void BPMCalculator::moveStartingOffsetBy(microsec shift)
|
||||||
_first_click_offset += shift;
|
_first_click_offset += shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
microsec BPMCalculator::fetchTimeUntilNextBeat()
|
microsec BPMCalculator::fetchTimeUntilNextBeat(const microsec& offset)
|
||||||
{
|
{
|
||||||
const microsec actual_offset = _music->fetchOffset() - getStartingOffset();
|
const microsec actual_offset = offset - getStartingOffset();
|
||||||
|
|
||||||
return actual_offset % fetchApproximatedInfo().interval;
|
return actual_offset % fetchApproximatedInfo().interval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ void Music::stop()
|
||||||
|
|
||||||
bool Music::isPaused() const
|
bool Music::isPaused() const
|
||||||
{
|
{
|
||||||
return (_music.getStatus() == sf::Music::Paused);
|
return (_music.getStatus() != sf::Music::Playing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Music::setVolume(int volume)
|
void Music::setVolume(int volume)
|
||||||
|
|
Loading…
Reference in New Issue