Initial setup of input stuff
This commit is contained in:
parent
2c43b50531
commit
15b0e99460
@ -9,13 +9,11 @@ SET (star_application_HEADERS
|
|||||||
StarApplication.hpp
|
StarApplication.hpp
|
||||||
StarApplicationController.hpp
|
StarApplicationController.hpp
|
||||||
StarMainApplication.hpp
|
StarMainApplication.hpp
|
||||||
StarInputEvent.hpp
|
|
||||||
StarRenderer.hpp
|
StarRenderer.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET (star_application_SOURCES
|
SET (star_application_SOURCES
|
||||||
StarApplication.cpp
|
StarApplication.cpp
|
||||||
StarInputEvent.cpp
|
|
||||||
StarRenderer.cpp
|
StarRenderer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ void ClientApplication::applicationInit(ApplicationControllerPtr appController)
|
|||||||
m_mainMixer->setVolume(0.5);
|
m_mainMixer->setVolume(0.5);
|
||||||
|
|
||||||
m_guiContext = make_shared<GuiContext>(m_mainMixer->mixer(), appController);
|
m_guiContext = make_shared<GuiContext>(m_mainMixer->mixer(), appController);
|
||||||
|
m_input = make_shared<Input>();
|
||||||
|
|
||||||
auto configuration = m_root->configuration();
|
auto configuration = m_root->configuration();
|
||||||
bool vsync = configuration->get("vsync").toBool();
|
bool vsync = configuration->get("vsync").toBool();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "StarErrorScreen.hpp"
|
#include "StarErrorScreen.hpp"
|
||||||
#include "StarCinematic.hpp"
|
#include "StarCinematic.hpp"
|
||||||
#include "StarKeyBindings.hpp"
|
#include "StarKeyBindings.hpp"
|
||||||
|
#include "StarInput.hpp"
|
||||||
#include "StarMainApplication.hpp"
|
#include "StarMainApplication.hpp"
|
||||||
|
|
||||||
namespace Star {
|
namespace Star {
|
||||||
@ -74,6 +75,7 @@ private:
|
|||||||
// Valid after applicationInit is called
|
// Valid after applicationInit is called
|
||||||
MainMixerPtr m_mainMixer;
|
MainMixerPtr m_mainMixer;
|
||||||
GuiContextPtr m_guiContext;
|
GuiContextPtr m_guiContext;
|
||||||
|
InputPtr m_input;
|
||||||
|
|
||||||
// Valid after renderInit is called the first time
|
// Valid after renderInit is called the first time
|
||||||
CinematicPtr m_cinematicOverlay;
|
CinematicPtr m_cinematicOverlay;
|
||||||
|
@ -40,6 +40,7 @@ SET (star_core_HEADERS
|
|||||||
StarIdMap.hpp
|
StarIdMap.hpp
|
||||||
StarImage.hpp
|
StarImage.hpp
|
||||||
StarImageProcessing.hpp
|
StarImageProcessing.hpp
|
||||||
|
StarInputEvent.hpp
|
||||||
StarInterpolation.hpp
|
StarInterpolation.hpp
|
||||||
StarRefPtr.hpp
|
StarRefPtr.hpp
|
||||||
StarIterator.hpp
|
StarIterator.hpp
|
||||||
@ -142,6 +143,7 @@ SET (star_core_SOURCES
|
|||||||
StarIODevice.cpp
|
StarIODevice.cpp
|
||||||
StarImage.cpp
|
StarImage.cpp
|
||||||
StarImageProcessing.cpp
|
StarImageProcessing.cpp
|
||||||
|
StarInputEvent.cpp
|
||||||
StarJson.cpp
|
StarJson.cpp
|
||||||
StarJsonBuilder.cpp
|
StarJsonBuilder.cpp
|
||||||
StarJsonExtra.cpp
|
StarJsonExtra.cpp
|
||||||
|
@ -56,6 +56,7 @@ SET (star_game_HEADERS
|
|||||||
StarGameTypes.hpp
|
StarGameTypes.hpp
|
||||||
StarHumanoid.hpp
|
StarHumanoid.hpp
|
||||||
StarImageMetadataDatabase.hpp
|
StarImageMetadataDatabase.hpp
|
||||||
|
StarInput.hpp
|
||||||
StarInteractionTypes.hpp
|
StarInteractionTypes.hpp
|
||||||
StarInterpolationTracker.hpp
|
StarInterpolationTracker.hpp
|
||||||
StarInventoryTypes.hpp
|
StarInventoryTypes.hpp
|
||||||
@ -314,6 +315,7 @@ SET (star_game_SOURCES
|
|||||||
StarGameTypes.cpp
|
StarGameTypes.cpp
|
||||||
StarHumanoid.cpp
|
StarHumanoid.cpp
|
||||||
StarImageMetadataDatabase.cpp
|
StarImageMetadataDatabase.cpp
|
||||||
|
StarInput.cpp
|
||||||
StarInteractionTypes.cpp
|
StarInteractionTypes.cpp
|
||||||
StarInterpolationTracker.cpp
|
StarInterpolationTracker.cpp
|
||||||
StarInventoryTypes.cpp
|
StarInventoryTypes.cpp
|
||||||
|
58
source/game/StarInput.cpp
Normal file
58
source/game/StarInput.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include "StarInput.hpp"
|
||||||
|
#include "StarAssets.hpp"
|
||||||
|
#include "StarRoot.hpp"
|
||||||
|
|
||||||
|
namespace Star {
|
||||||
|
|
||||||
|
size_t hash<InputVariant>::operator()(InputVariant const& v) const {
|
||||||
|
size_t indexHash = hashOf(v.typeIndex());
|
||||||
|
if (auto key = v.ptr<Key>())
|
||||||
|
hashCombine(indexHash, hashOf(*key));
|
||||||
|
else if (auto mButton = v.ptr<MouseButton>())
|
||||||
|
hashCombine(indexHash, hashOf(*mButton));
|
||||||
|
else if (auto cButton = v.ptr<ControllerButton>())
|
||||||
|
hashCombine(indexHash, hashOf(*cButton));
|
||||||
|
|
||||||
|
return indexHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input* Input::s_singleton;
|
||||||
|
|
||||||
|
Input* Input::singletonPtr() {
|
||||||
|
return s_singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input& Input::singleton() {
|
||||||
|
if (!s_singleton)
|
||||||
|
throw InputException("Input::singleton() called with no Input instance available");
|
||||||
|
else
|
||||||
|
return *s_singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input::Input() {
|
||||||
|
if (s_singleton)
|
||||||
|
throw InputException("Singleton Input has been constructed twice");
|
||||||
|
|
||||||
|
s_singleton = this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Input::~Input() {
|
||||||
|
s_singleton = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Input::reset() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Input::reload() {
|
||||||
|
reset();
|
||||||
|
|
||||||
|
auto assets = Root::singleton().assets();
|
||||||
|
|
||||||
|
for (auto& bindPath : assets->scanExtension("binds")) {
|
||||||
|
Json config = assets->json(bindPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
160
source/game/StarInput.hpp
Normal file
160
source/game/StarInput.hpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#ifndef STAR_INPUT_HPP
|
||||||
|
#define STAR_INPUT_HPP
|
||||||
|
|
||||||
|
#include "StarInputEvent.hpp"
|
||||||
|
#include "StarJson.hpp"
|
||||||
|
#include "StarListener.hpp"
|
||||||
|
#include "StarHash.hpp"
|
||||||
|
|
||||||
|
namespace Star {
|
||||||
|
|
||||||
|
STAR_CLASS(Input);
|
||||||
|
STAR_EXCEPTION(InputException, StarException);
|
||||||
|
|
||||||
|
typedef Variant<Key, MouseButton, ControllerButton> InputVariant;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<InputVariant> {
|
||||||
|
size_t operator()(InputVariant const& v) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Input {
|
||||||
|
public:
|
||||||
|
struct NoBind {
|
||||||
|
String error;
|
||||||
|
|
||||||
|
NoBind(String err);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KeyBind {
|
||||||
|
Key key = Key::Zero;
|
||||||
|
KeyMod mods = KeyMod::NoMod;
|
||||||
|
uint8_t priority = 0;
|
||||||
|
|
||||||
|
inline bool operator<(KeyBind const& rhs) const {
|
||||||
|
return priority < rhs.priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>(KeyBind const& rhs) const {
|
||||||
|
return priority > rhs.priority;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MouseBind {
|
||||||
|
MouseButton button = MouseButton::Left;
|
||||||
|
KeyMod mods = KeyMod::NoMod;
|
||||||
|
uint8_t priority = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ControllerBind {
|
||||||
|
unsigned int controller = 0;
|
||||||
|
ControllerButton button = ControllerButton::Invalid;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Variant<NoBind, KeyBind, MouseBind, ControllerBind> Bind;
|
||||||
|
|
||||||
|
static Bind bindFromJson(Json const& json);
|
||||||
|
static Json bindToJson(Bind const& bind);
|
||||||
|
|
||||||
|
struct Category;
|
||||||
|
|
||||||
|
struct BindEntry {
|
||||||
|
// The internal ID of this entry.
|
||||||
|
String id;
|
||||||
|
// The category this entry belongs to.
|
||||||
|
String category;
|
||||||
|
// The user-facing name of this entry.
|
||||||
|
String name;
|
||||||
|
|
||||||
|
// The default binds.
|
||||||
|
List<Bind> defaultBinds;
|
||||||
|
// The user-configured binds.
|
||||||
|
List<Bind> customBinds;
|
||||||
|
|
||||||
|
BindEntry(Json const& config, Category const& category);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BindRef {
|
||||||
|
KeyMod mods;
|
||||||
|
uint8_t priority;
|
||||||
|
|
||||||
|
// Invalidated on reload, careful!
|
||||||
|
BindEntry* entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BindRefSorter {
|
||||||
|
inline bool operator() (BindRef const& a, BindRef const& b) {
|
||||||
|
return a.priority > b.priority;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BindCategory {
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
Json meta;
|
||||||
|
|
||||||
|
StringMap<BindEntry> entries;
|
||||||
|
|
||||||
|
BindCategory(Json const& data);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InputState {
|
||||||
|
size_t presses = 0;
|
||||||
|
size_t releases = 0;
|
||||||
|
|
||||||
|
// Calls the passed functions for each press and release.
|
||||||
|
template <typename PressFunction, typename ReleaseFunction>
|
||||||
|
void forEach(PressFunction&& pressed, ReleaseFunction&& released) {
|
||||||
|
for (size_t i = 0; i != releases; ++i) {
|
||||||
|
pressed();
|
||||||
|
released();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool held() {
|
||||||
|
return presses < releases;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get pointer to the singleton root instance, if it exists. Otherwise,
|
||||||
|
// returns nullptr.
|
||||||
|
static Input* singletonPtr();
|
||||||
|
|
||||||
|
// Gets reference to GuiContext singleton, throws GuiContextException if root
|
||||||
|
// is not initialized.
|
||||||
|
static Input& singleton();
|
||||||
|
|
||||||
|
Input();
|
||||||
|
~Input();
|
||||||
|
|
||||||
|
Input(Input const&) = delete;
|
||||||
|
Input& operator=(Input const&) = delete;
|
||||||
|
|
||||||
|
// Clears input state. Should be done at the end of the client loop.
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
// Handles an input event.
|
||||||
|
bool handleInput(InputEvent const& event);
|
||||||
|
|
||||||
|
// Loads input categories and their binds from Assets.
|
||||||
|
void reload();
|
||||||
|
private:
|
||||||
|
static Input* s_singleton;
|
||||||
|
|
||||||
|
// Regenerated on reload.
|
||||||
|
StringMap<BindCategory> m_bindCategories;
|
||||||
|
// Contains raw pointers to bind entries in categories, so also regenerated on reload.
|
||||||
|
HashMap<InputVariant, List<BindRef>> m_inputsToBinds;
|
||||||
|
|
||||||
|
ListenerPtr m_rootReloadListener;
|
||||||
|
|
||||||
|
// Per-frame input state maps.
|
||||||
|
|
||||||
|
//Raw input state
|
||||||
|
HashMap<InputVariant, InputState> m_inputStates;
|
||||||
|
//Bind input state
|
||||||
|
HashMap<BindEntry*, InputState> m_bindStates;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user