Implement keyboard converter for SFML

This commit is contained in:
NaiJi ✨ 2022-01-11 23:15:24 +03:00
parent 833dd2b781
commit d94454d36b
18 changed files with 283 additions and 149 deletions

View File

@ -32,7 +32,113 @@ struct SystemEvent
struct Key struct Key
{ {
char view = char(0); enum class Code
{
Unknown = -1,
A = 0,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Num0,
Num1,
Num2,
Num3,
Num4,
Num5,
Num6,
Num7,
Num8,
Num9,
Escape,
LControl,
LShift,
LAlt,
LSystem,
RControl,
RShift,
RAlt,
RSystem,
Menu,
LBracket,
RBracket,
Semicolon,
Comma,
Period,
Quote,
Slash,
Backslash,
Tilde,
Equal,
Hyphen,
Space,
Enter,
Backspace,
Tab,
PageUp,
PageDown,
End,
Home,
Insert,
Delete,
Add,
Subtract,
Multiply,
Divide,
Left,
Right,
Up,
Down,
Numpad0,
Numpad1,
Numpad2,
Numpad3,
Numpad4,
Numpad5,
Numpad6,
Numpad7,
Numpad8,
Numpad9,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
Pause
};
Code view = Code::Unknown;
bool alt = false; bool alt = false;
bool control = false; bool control = false;
bool shift = false; bool shift = false;
@ -62,4 +168,4 @@ struct SystemEvent
std::variant<Size, Key, Mouse, None> data; std::variant<Size, Key, Mouse, None> data;
}; };
} }

View File

@ -3,6 +3,7 @@
#include "state.h" #include "state.h"
#include "core/music.h" #include "core/music.h"
#include "core/game.h" #include "core/game.h"
#include "core/corefactory.h"
class Group; class Group;
@ -16,7 +17,7 @@ public:
}; };
explicit GameState(const std::shared_ptr<kku::Game>& game, Callbacks&& callbacks); explicit GameState(const std::shared_ptr<kku::CoreFactory>& core_factory, const std::shared_ptr<kku::Game>& game, Callbacks&& callbacks);
virtual void input(const kku::SystemEvent& event) override; virtual void input(const kku::SystemEvent& event) override;
virtual void update(const kku::microsec& dt) override; virtual void update(const kku::microsec& dt) override;
@ -26,6 +27,7 @@ public:
virtual void leave() override; virtual void leave() override;
private: private:
const std::shared_ptr<kku::CoreFactory> _core_factory;
std::shared_ptr<kku::Music> _music; std::shared_ptr<kku::Music> _music;
std::shared_ptr<kku::Game> _game; std::shared_ptr<kku::Game> _game;

View File

@ -22,7 +22,7 @@ bool Application::init()
EditorState::Callbacks editor_callbacks = {[&](){ popState(); }}; EditorState::Callbacks editor_callbacks = {[&](){ popState(); }};
const auto main_menu = std::make_shared<MainMenu>(_core_factory, std::move(callbacks)); const auto main_menu = std::make_shared<MainMenu>(_core_factory, std::move(callbacks));
const auto game_state = std::make_shared<GameState>(_game_factory->getGame(), GameState::Callbacks()); const auto game_state = std::make_shared<GameState>(_core_factory, _game_factory->getGame(), GameState::Callbacks());
const auto editor = std::make_shared<EditorState>(_core_factory, _game_factory->getEditor(), std::move(editor_callbacks)); const auto editor = std::make_shared<EditorState>(_core_factory, _game_factory->getEditor(), std::move(editor_callbacks));
_states[GUIState::Tag::MAIN_MENU] = main_menu; _states[GUIState::Tag::MAIN_MENU] = main_menu;

View File

@ -158,7 +158,7 @@ void EditorState::enter()
callbacks.onInput = [&editor, &music](const kku::SystemEvent& event) callbacks.onInput = [&editor, &music](const kku::SystemEvent& event)
{ {
if (event.type == kku::SystemEvent::Type::KeyRelease if (event.type == kku::SystemEvent::Type::KeyRelease
&& std::get<kku::SystemEvent::Key>(event.data).view == ' ') && std::get<kku::SystemEvent::Key>(event.data).view == kku::SystemEvent::Key::Code::Space)
music->isPlaying() ? music->pause() : music->play(); music->isPlaying() ? music->pause() : music->play();
else if (event.type == kku::SystemEvent::Type::MouseWheelScroll) else if (event.type == kku::SystemEvent::Type::MouseWheelScroll)
{ {

View File

@ -4,10 +4,13 @@
#include "core/game.h" #include "core/game.h"
GameState::GameState(const std::shared_ptr<kku::Game>& game, Callbacks&& callbacks) : GameState::GameState(const std::shared_ptr<kku::CoreFactory>& core_factory, const std::shared_ptr<kku::Game>& game, Callbacks&& callbacks) :
_core_factory(core_factory),
_game(game), _game(game),
_onLeaveGameCallback(callbacks.onLeaveGame) _onLeaveGameCallback(callbacks.onLeaveGame)
{} {
_music = _core_factory->getMusic();
}
void GameState::input(const kku::SystemEvent& event) void GameState::input(const kku::SystemEvent& event)
{ {
@ -17,7 +20,7 @@ void GameState::input(const kku::SystemEvent& event)
break; break;
case kku::SystemEvent::Type::KeyRelease: case kku::SystemEvent::Type::KeyRelease:
if (std::get<kku::SystemEvent::Key>(event.data).view == ' ') if (std::get<kku::SystemEvent::Key>(event.data).view == kku::SystemEvent::Key::Code::Space)
_music->isPlaying() ? _music->pause() : _music->play(); _music->isPlaying() ? _music->pause() : _music->play();
} }

View File

@ -29,7 +29,7 @@ void BPMCalculatorWidget::input(const kku::SystemEvent& event)
case kku::SystemEvent::Type::KeyPress: case kku::SystemEvent::Type::KeyPress:
{ {
if (std::get<kku::SystemEvent::Key>(event.data).view == ' ') if (std::get<kku::SystemEvent::Key>(event.data).view == kku::SystemEvent::Key::Code::Space)
{ {
_bpm_calculator->click(_current_time()); _bpm_calculator->click(_current_time());
} }

View File

@ -1,6 +1,7 @@
#include "applicationsfml.h" #include "applicationsfml.h"
#include "sfml/corefactorysfml.h" #include "sfml/corefactorysfml.h"
#include "sfml/classicmode/classicfactorysfml.h" #include "sfml/classicmode/classicfactorysfml.h"
#include "sfml/application/inputconvertersfml.h"
#include <SFML/System/Clock.hpp> #include <SFML/System/Clock.hpp>
@ -47,7 +48,7 @@ void ApplicationSFML::run()
break; break;
default: default:
Application::input(convert(event)); Application::input(kku::convert(event));
break; break;
} }
} }
@ -61,127 +62,3 @@ void ApplicationSFML::run()
} }
} }
} }
kku::SystemEvent ApplicationSFML::convert(const sf::Event& event) const
{
switch (event.type)
{
default:
break;
case sf::Event::Resized:
return kku::SystemEvent
{
kku::SystemEvent::Type::Resize,
kku::SystemEvent::Size
{
event.size.width,
event.size.height
}
};
case sf::Event::KeyPressed:
return kku::SystemEvent
{
kku::SystemEvent::Type::KeyPress,
kku::SystemEvent::Key
{
' ', // converter
event.key.alt,
event.key.control,
event.key.shift
}
};
case sf::Event::KeyReleased:
return kku::SystemEvent
{
kku::SystemEvent::Type::KeyRelease,
kku::SystemEvent::Key
{
' ', // converter
event.key.alt,
event.key.control,
event.key.shift
}
};
case sf::Event::MouseWheelScrolled:
return kku::SystemEvent
{
kku::SystemEvent::Type::MouseWheelScroll,
kku::SystemEvent::Mouse
{
kku::Point
{
event.mouseWheelScroll.x,
event.mouseWheelScroll.y
},
(event.mouseWheelScroll.delta > 0),
kku::SystemEvent::Mouse::Button::Wheel
}
};
case sf::Event::MouseMoved:
return kku::SystemEvent
{
kku::SystemEvent::Type::MouseMove,
kku::SystemEvent::Mouse
{
kku::Point
{
event.mouseMove.x,
event.mouseMove.y
},
false,
kku::SystemEvent::Mouse::Button::None
}
};
case sf::Event::MouseButtonPressed:
return kku::SystemEvent
{
kku::SystemEvent::Type::MousePress,
kku::SystemEvent::Mouse
{
kku::Point
{
event.mouseButton.x,
event.mouseButton.y
},
false,
((event.mouseButton.button == sf::Mouse::Button::Left)
? kku::SystemEvent::Mouse::Button::Left
: kku::SystemEvent::Mouse::Button::Right)
}
};
case sf::Event::MouseButtonReleased:
return kku::SystemEvent
{
kku::SystemEvent::Type::MouseRelease,
kku::SystemEvent::Mouse
{
kku::Point
{
event.mouseButton.x,
event.mouseButton.y
},
false,
((event.mouseButton.button == sf::Mouse::Button::Left)
? kku::SystemEvent::Mouse::Button::Left
: kku::SystemEvent::Mouse::Button::Right)
}
};
}
return kku::SystemEvent
{
kku::SystemEvent::Type::None,
kku::SystemEvent::None{}
};
}

View File

@ -14,6 +14,4 @@ public:
private: private:
const std::shared_ptr<sf::RenderWindow> _render_window; const std::shared_ptr<sf::RenderWindow> _render_window;
inline kku::SystemEvent convert(const sf::Event& event) const;
}; };

View File

@ -0,0 +1,138 @@
#pragma once
#include "core/systemevent.h"
#include <SFML/Window/Event.hpp>
namespace kku
{
constexpr kku::SystemEvent::Key::Code convert(sf::Keyboard::Key key) noexcept
{
return kku::SystemEvent::Key::Code{int(key)};
}
constexpr kku::SystemEvent convert(const sf::Event& event) noexcept
{
switch (event.type)
{
default:
break;
case sf::Event::Resized:
return kku::SystemEvent
{
kku::SystemEvent::Type::Resize,
kku::SystemEvent::Size
{
event.size.width,
event.size.height
}
};
case sf::Event::KeyPressed:
return kku::SystemEvent
{
kku::SystemEvent::Type::KeyPress,
kku::SystemEvent::Key
{
kku::convert(event.key.code),
event.key.alt,
event.key.control,
event.key.shift
}
};
case sf::Event::KeyReleased:
return kku::SystemEvent
{
kku::SystemEvent::Type::KeyRelease,
kku::SystemEvent::Key
{
kku::convert(event.key.code),
event.key.alt,
event.key.control,
event.key.shift
}
};
case sf::Event::MouseWheelScrolled:
return kku::SystemEvent
{
kku::SystemEvent::Type::MouseWheelScroll,
kku::SystemEvent::Mouse
{
kku::Point
{
event.mouseWheelScroll.x,
event.mouseWheelScroll.y
},
(event.mouseWheelScroll.delta > 0),
kku::SystemEvent::Mouse::Button::Wheel
}
};
case sf::Event::MouseMoved:
return kku::SystemEvent
{
kku::SystemEvent::Type::MouseMove,
kku::SystemEvent::Mouse
{
kku::Point
{
event.mouseMove.x,
event.mouseMove.y
},
false,
kku::SystemEvent::Mouse::Button::None
}
};
case sf::Event::MouseButtonPressed:
return kku::SystemEvent
{
kku::SystemEvent::Type::MousePress,
kku::SystemEvent::Mouse
{
kku::Point
{
event.mouseButton.x,
event.mouseButton.y
},
false,
((event.mouseButton.button == sf::Mouse::Button::Left)
? kku::SystemEvent::Mouse::Button::Left
: kku::SystemEvent::Mouse::Button::Right)
}
};
case sf::Event::MouseButtonReleased:
return kku::SystemEvent
{
kku::SystemEvent::Type::MouseRelease,
kku::SystemEvent::Mouse
{
kku::Point
{
event.mouseButton.x,
event.mouseButton.y
},
false,
((event.mouseButton.button == sf::Mouse::Button::Left)
? kku::SystemEvent::Mouse::Button::Left
: kku::SystemEvent::Mouse::Button::Right)
}
};
}
return kku::SystemEvent
{
kku::SystemEvent::Type::None,
kku::SystemEvent::None{}
};
}
}

View File

@ -51,7 +51,10 @@ void ClassicEditor::input(kku::GameEvent&& input)
element.element.position = std::get<kku::SystemEvent::Mouse>(event.data).position; element.element.position = std::get<kku::SystemEvent::Mouse>(event.data).position;
element.element.falling_curve_interpolation = {}; element.element.falling_curve_interpolation = {};
element.keys = {'W', 'w'};
element.keys = {kku::SystemEvent::Key::Code::W,
kku::SystemEvent::Key::Code::Up};
element.element.type = Type::UP; element.element.type = Type::UP;
init.elements = { element }; init.elements = { element };

View File

@ -16,11 +16,12 @@ struct ArrowElement
{ {
std::shared_ptr<ClassicSprite> sprite; std::shared_ptr<ClassicSprite> sprite;
std::array<std::shared_ptr<ClassicAnimationScenario>, 5> animations; std::array<std::shared_ptr<ClassicAnimationScenario>, 5> animations;
char pressed_as = ' ';
kku::SystemEvent::Key::Code pressed_as = kku::SystemEvent::Key::Code::Unknown;
kku::Point position; kku::Point position;
std::vector<kku::Point> falling_curve_interpolation; std::vector<kku::Point> falling_curve_interpolation;
std::array<char, 2> keys; std::array<kku::SystemEvent::Key::Code, 2> keys;
Type type = Type::NONE; Type type = Type::NONE;
bool pressed = false; bool pressed = false;

View File

@ -32,7 +32,7 @@ void ClassicArrowNote::input(kku::GameEvent&& input)
if (element.pressed) if (element.pressed)
return false; return false;
const char code = std::get<kku::SystemEvent::Key>(input.event.data).view; const auto code = std::get<kku::SystemEvent::Key>(input.event.data).view;
auto key_iterator = std::find(element.keys.begin(), element.keys.end(), code); auto key_iterator = std::find(element.keys.begin(), element.keys.end(), code);
bool found_key = key_iterator != element.keys.end(); bool found_key = key_iterator != element.keys.end();
@ -110,7 +110,7 @@ bool ClassicArrowNote::allElementsPressed() const
}); });
} }
bool ClassicArrowNote::isPressedAs(char key) const bool ClassicArrowNote::isPressedAs(kku::SystemEvent::Key::Code key) const
{ {
return std::any_of(_elements.begin(), _elements.end(), return std::any_of(_elements.begin(), _elements.end(),
[key](const auto& element) [key](const auto& element)

View File

@ -19,7 +19,7 @@ public:
virtual void setGraphics(ClassicGraphicsManager * const manager, kku::TimeRange&& range) override; virtual void setGraphics(ClassicGraphicsManager * const manager, kku::TimeRange&& range) override;
bool allElementsPressed() const; bool allElementsPressed() const;
bool isPressedAs(char key) const; bool isPressedAs(kku::SystemEvent::Key::Code key) const;
inline bool isHold() const; inline bool isHold() const;
private: private:

View File

@ -54,13 +54,13 @@ void ClassicGame::input(kku::GameEvent&& input)
void ClassicGame::update(kku::UpdateData&& updatedata) void ClassicGame::update(kku::UpdateData&& updatedata)
{ {
// UNCOMMENT TO TEST AUTOPLAY // UNCOMMENT TO TEST AUTOPLAY
auto note_it = _timeline->getActiveNote(updatedata.timestamp); /*auto note_it = _timeline->getActiveNote(updatedata.timestamp);
if (!_timeline->isExpired(note_it) && updatedata.timestamp >= (*note_it)->getPerfectOffset()) if (!_timeline->isExpired(note_it) && updatedata.timestamp >= (*note_it)->getPerfectOffset())
{ {
auto note = (*note_it); auto note = (*note_it);
note->input(kku::GameEvent{updatedata.timestamp, kku::SystemEvent{kku::SystemEvent::Type::None, kku::SystemEvent::Key{}}}); note->input(kku::GameEvent{updatedata.timestamp, kku::SystemEvent{kku::SystemEvent::Type::None, kku::SystemEvent::Key{}}});
} }*/
_timeline->update(updatedata.timestamp); _timeline->update(updatedata.timestamp);
_graphics_manager->update(updatedata.timestamp); _graphics_manager->update(updatedata.timestamp);

View File

@ -40,13 +40,19 @@ auto classic::createBeatmap(const std::string& filepath, const Context &context)
element.element.position = kku::Point(x, 390.f); element.element.position = kku::Point(x, 390.f);
element.element.falling_curve_interpolation = {}; element.element.falling_curve_interpolation = {};
element.keys = {'W', 'w'};
element.keys = {kku::SystemEvent::Key::Code::W,
kku::SystemEvent::Key::Code::Up};
element.element.type = Type::UP; element.element.type = Type::UP;
if (counter == 0) if (counter == 0)
{ {
init.hold = true; init.hold = true;
element.keys = {'D', 'd'};
element.keys = {kku::SystemEvent::Key::Code::D,
kku::SystemEvent::Key::Code::Right};
element.element.type = Type::RIGHT; element.element.type = Type::RIGHT;
} }

View File

@ -9,7 +9,7 @@ void HoldManager::emplace(ClassicArrowNote* note)
_notes_on_hold.emplace_back(note); _notes_on_hold.emplace_back(note);
} }
void HoldManager::checkRelease(char released_key) void HoldManager::checkRelease(kku::SystemEvent::Key::Code released_key)
{ {
bool key_match = std::any_of(_notes_on_hold.begin(), _notes_on_hold.end(), bool key_match = std::any_of(_notes_on_hold.begin(), _notes_on_hold.end(),
[released_key](const auto& note) [released_key](const auto& note)

View File

@ -12,7 +12,7 @@ class HoldManager
{ {
public: public:
void emplace(ClassicArrowNote* note); void emplace(ClassicArrowNote* note);
void checkRelease(char released_key); void checkRelease(kku::SystemEvent::Key::Code released_key);
void drawHoldBar(); void drawHoldBar();

View File

@ -5,5 +5,5 @@
struct ArrowElementInitializer struct ArrowElementInitializer
{ {
ElementInitializer element; ElementInitializer element;
std::array<char, 2> keys; std::array<kku::SystemEvent::Key::Code, 2> keys;
}; };