Initial setup of input stuff
This commit is contained in:
parent
2c43b50531
commit
15b0e99460
@ -9,13 +9,11 @@ SET (star_application_HEADERS
|
||||
StarApplication.hpp
|
||||
StarApplicationController.hpp
|
||||
StarMainApplication.hpp
|
||||
StarInputEvent.hpp
|
||||
StarRenderer.hpp
|
||||
)
|
||||
|
||||
SET (star_application_SOURCES
|
||||
StarApplication.cpp
|
||||
StarInputEvent.cpp
|
||||
StarRenderer.cpp
|
||||
)
|
||||
|
||||
|
@ -167,7 +167,7 @@ void ClientApplication::applicationInit(ApplicationControllerPtr appController)
|
||||
m_mainMixer->setVolume(0.5);
|
||||
|
||||
m_guiContext = make_shared<GuiContext>(m_mainMixer->mixer(), appController);
|
||||
|
||||
m_input = make_shared<Input>();
|
||||
|
||||
auto configuration = m_root->configuration();
|
||||
bool vsync = configuration->get("vsync").toBool();
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "StarErrorScreen.hpp"
|
||||
#include "StarCinematic.hpp"
|
||||
#include "StarKeyBindings.hpp"
|
||||
#include "StarInput.hpp"
|
||||
#include "StarMainApplication.hpp"
|
||||
|
||||
namespace Star {
|
||||
@ -74,6 +75,7 @@ private:
|
||||
// Valid after applicationInit is called
|
||||
MainMixerPtr m_mainMixer;
|
||||
GuiContextPtr m_guiContext;
|
||||
InputPtr m_input;
|
||||
|
||||
// Valid after renderInit is called the first time
|
||||
CinematicPtr m_cinematicOverlay;
|
||||
|
@ -40,6 +40,7 @@ SET (star_core_HEADERS
|
||||
StarIdMap.hpp
|
||||
StarImage.hpp
|
||||
StarImageProcessing.hpp
|
||||
StarInputEvent.hpp
|
||||
StarInterpolation.hpp
|
||||
StarRefPtr.hpp
|
||||
StarIterator.hpp
|
||||
@ -142,6 +143,7 @@ SET (star_core_SOURCES
|
||||
StarIODevice.cpp
|
||||
StarImage.cpp
|
||||
StarImageProcessing.cpp
|
||||
StarInputEvent.cpp
|
||||
StarJson.cpp
|
||||
StarJsonBuilder.cpp
|
||||
StarJsonExtra.cpp
|
||||
|
@ -56,6 +56,7 @@ SET (star_game_HEADERS
|
||||
StarGameTypes.hpp
|
||||
StarHumanoid.hpp
|
||||
StarImageMetadataDatabase.hpp
|
||||
StarInput.hpp
|
||||
StarInteractionTypes.hpp
|
||||
StarInterpolationTracker.hpp
|
||||
StarInventoryTypes.hpp
|
||||
@ -314,6 +315,7 @@ SET (star_game_SOURCES
|
||||
StarGameTypes.cpp
|
||||
StarHumanoid.cpp
|
||||
StarImageMetadataDatabase.cpp
|
||||
StarInput.cpp
|
||||
StarInteractionTypes.cpp
|
||||
StarInterpolationTracker.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