Add voice muting, add input key and mouse functions

This commit is contained in:
Kae 2023-07-20 12:52:08 +10:00
parent db3d004d30
commit 3aa45ab799
4 changed files with 120 additions and 45 deletions

View File

@ -80,17 +80,18 @@ local function drawSpeakerBar(mouse, pos, speaker, i)
hoveredSpeaker = speaker hoveredSpeaker = speaker
hoveredSpeakerIndex = i hoveredSpeakerIndex = i
hoveredSpeakerPosition = pos hoveredSpeakerPosition = pos
--if input.key("LShift") then if input.keyHeld("LShift") then
-- textPositioning.position = {pos[1] + 288, pos[2] + 24} textPositioning.position = {pos[1] + 288, pos[2] + 24}
-- textPositioning.horizontalAnchor = "right" textPositioning.horizontalAnchor = "right"
-- canvas:drawText("^#fff7;" .. tostring(speaker.speakerId), textPositioning, 16, nil, nil, nil, FONT_DIRECTIVES) canvas:drawText("^#fff7,font=iosevka-semibold;" .. tostring(speaker.speakerId), textPositioning, 16, nil, nil, nil, FONT_DIRECTIVES)
--end end
--
--if input.mouseDown("MouseLeft") then if input.mouseDown("MouseLeft") then
-- local muted = not voice.muted(speaker.speakerId) local muted = not voice.speakerMuted(speaker.speakerId)
-- interface.queueMessage((muted and "^#f43030;Muted^reset; " or "^#31d2f7;Unmuted^reset; ") .. speaker.name, 4, 0.5) interface.queueMessage((muted and "^#f43030;Muted^reset; " or "^#31d2f7;Unmuted^reset; ") .. speaker.name, 4, 0.5)
-- voice.setMuted(speaker.speakerId, muted) voice.setSpeakerMuted(speaker.speakerId, muted)
--end speaker.muted = muted
end
end end
end end

View File

@ -316,10 +316,6 @@ Input::InputState* Input::bindStatePtr(String const& categoryId, String const& b
return nullptr; return nullptr;
} }
Input::InputState* Input::inputStatePtr(InputVariant key) {
return m_inputStates.ptr(key);
}
Input* Input::s_singleton; Input* Input::s_singleton;
Input* Input::singletonPtr() { Input* Input::singletonPtr() {
@ -361,28 +357,17 @@ List<std::pair<InputEvent, bool>> const& Input::inputEventsThisFrame() const {
void Input::reset() { void Input::reset() {
m_inputEvents.resize(0); // keeps reserved memory m_inputEvents.clear();
{ auto eraseCond = [](auto& p) {
auto it = m_inputStates.begin(); if (p.second.held)
while (it != m_inputStates.end()) { p.second.reset();
if (it->second.held) { return !p.second.held;
it->second.reset(); };
++it;
}
else it = m_inputStates.erase(it);
}
}
{ eraseWhere(m_keyStates, eraseCond);
auto it = m_bindStates.begin(); eraseWhere(m_mouseStates, eraseCond);
while (it != m_bindStates.end()) { eraseWhere(m_controllerStates, eraseCond);
if (it->second.held) { eraseWhere(m_bindStates, eraseCond);
it->second.reset();
++it;
}
else it = m_bindStates.erase(it);
}
}
} }
void Input::update() { void Input::update() {
@ -397,7 +382,10 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) {
m_pressedMods |= *keyToMod; m_pressedMods |= *keyToMod;
if (!gameProcessed && !m_textInputActive) { if (!gameProcessed && !m_textInputActive) {
m_inputStates[keyDown->key].press(); auto& state = m_keyStates[keyDown->key];
if (keyToMod)
state.mods |= *keyToMod;
state.press();
if (auto binds = m_bindMappings.ptr(keyDown->key)) { if (auto binds = m_bindMappings.ptr(keyDown->key)) {
for (auto bind : filterBindEntries(*binds, keyDown->mods)) for (auto bind : filterBindEntries(*binds, keyDown->mods))
@ -410,8 +398,11 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) {
m_pressedMods &= ~*keyToMod; m_pressedMods &= ~*keyToMod;
// We need to be able to release input even when gameProcessed is true, but only if it's already down. // We need to be able to release input even when gameProcessed is true, but only if it's already down.
if (auto state = m_inputStates.ptr(keyUp->key)) if (auto state = m_keyStates.ptr(keyUp->key)) {
if (keyToMod)
state->mods &= ~*keyToMod;
state->release(); state->release();
}
if (auto binds = m_bindMappings.ptr(keyUp->key)) { if (auto binds = m_bindMappings.ptr(keyUp->key)) {
for (auto& bind : *binds) { for (auto& bind : *binds) {
@ -421,7 +412,9 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) {
} }
} else if (auto mouseDown = input.ptr<MouseButtonDownEvent>()) { } else if (auto mouseDown = input.ptr<MouseButtonDownEvent>()) {
if (!gameProcessed) { if (!gameProcessed) {
m_inputStates[mouseDown->mouseButton].press(); auto& state = m_mouseStates[mouseDown->mouseButton];
state.pressPositions.append(mouseDown->mousePosition);
state.press();
if (auto binds = m_bindMappings.ptr(mouseDown->mouseButton)) { if (auto binds = m_bindMappings.ptr(mouseDown->mouseButton)) {
for (auto bind : filterBindEntries(*binds, m_pressedMods)) for (auto bind : filterBindEntries(*binds, m_pressedMods))
@ -429,8 +422,10 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) {
} }
} }
} else if (auto mouseUp = input.ptr<MouseButtonUpEvent>()) { } else if (auto mouseUp = input.ptr<MouseButtonUpEvent>()) {
if (auto state = m_inputStates.ptr(mouseUp->mouseButton)) if (auto state = m_mouseStates.ptr(mouseUp->mouseButton)) {
state->releasePositions.append(mouseUp->mousePosition);
state->release(); state->release();
}
if (auto binds = m_bindMappings.ptr(mouseUp->mouseButton)) { if (auto binds = m_bindMappings.ptr(mouseUp->mouseButton)) {
for (auto& bind : *binds) { for (auto& bind : *binds) {
@ -497,10 +492,10 @@ void Input::setTextInputActive(bool active) {
} }
Maybe<unsigned> Input::bindDown(String const& categoryId, String const& bindId) { Maybe<unsigned> Input::bindDown(String const& categoryId, String const& bindId) {
if (auto state = bindStatePtr(categoryId, bindId)) if (auto state = bindStatePtr(categoryId, bindId)) {
if (state->presses) if (state->presses)
return state->presses; return state->presses;
}
return {}; return {};
} }
@ -512,10 +507,52 @@ bool Input::bindHeld(String const& categoryId, String const& bindId) {
} }
Maybe<unsigned> Input::bindUp(String const& categoryId, String const& bindId) { Maybe<unsigned> Input::bindUp(String const& categoryId, String const& bindId) {
if (auto state = bindStatePtr(categoryId, bindId)) if (auto state = bindStatePtr(categoryId, bindId)) {
if (state->releases) if (state->releases)
return state->releases; return state->releases;
}
return {};
}
Maybe<unsigned> Input::keyDown(Key key, Maybe<KeyMod> keyMod) {
if (auto state = m_keyStates.ptr(key)) {
if (state->presses && (!keyMod || compareKeyMod(*keyMod, state->mods)))
return state->presses;
}
return {};
}
bool Input::keyHeld(Key key) {
auto state = m_keyStates.ptr(key);
return state && state->held;
}
Maybe<unsigned> Input::keyUp(Key key) {
if (auto state = m_keyStates.ptr(key)) {
if (state->releases)
return state->releases;
}
return {};
}
Maybe<List<Vec2I>> Input::mouseDown(MouseButton button) {
if (auto state = m_mouseStates.ptr(button)) {
if (state->presses)
return state->pressPositions;
}
return {};
}
bool Input::mouseHeld(MouseButton button) {
auto state = m_mouseStates.ptr(button);
return state && state->held;
}
Maybe<List<Vec2I>> Input::mouseUp(MouseButton button) {
if (auto state = m_mouseStates.ptr(button)) {
if (state->releases)
return state->releasePositions;
}
return {}; return {};
} }

View File

@ -117,6 +117,17 @@ public:
inline void release() { released = ++releases; held = false; } inline void release() { released = ++releases; held = false; }
}; };
struct KeyInputState : InputState {
KeyMod mods = KeyMod::NoMod;
};
struct MouseInputState : InputState {
List<Vec2I> pressPositions;
List<Vec2I> releasePositions;
};
typedef InputState ControllerInputState;
// Get pointer to the singleton Input instance, if it exists. Otherwise, // Get pointer to the singleton Input instance, if it exists. Otherwise,
// returns nullptr. // returns nullptr.
static Input* singletonPtr(); static Input* singletonPtr();
@ -152,6 +163,14 @@ public:
bool bindHeld(String const& categoryId, String const& bindId); bool bindHeld(String const& categoryId, String const& bindId);
Maybe<unsigned> bindUp (String const& categoryId, String const& bindId); Maybe<unsigned> bindUp (String const& categoryId, String const& bindId);
Maybe<unsigned> keyDown(Key key, Maybe<KeyMod> keyMod);
bool keyHeld(Key key);
Maybe<unsigned> keyUp (Key key);
Maybe<List<Vec2I>> mouseDown(MouseButton button);
bool mouseHeld(MouseButton button);
Maybe<List<Vec2I>> mouseUp (MouseButton button);
void resetBinds(String const& categoryId, String const& bindId); void resetBinds(String const& categoryId, String const& bindId);
void setBinds(String const& categoryId, String const& bindId, Json const& binds); void setBinds(String const& categoryId, String const& bindId, Json const& binds);
Json getDefaultBinds(String const& categoryId, String const& bindId); Json getDefaultBinds(String const& categoryId, String const& bindId);
@ -163,7 +182,6 @@ private:
BindEntry& bindEntry(String const& categoryId, String const& bindId); BindEntry& bindEntry(String const& categoryId, String const& bindId);
InputState* bindStatePtr(String const& categoryId, String const& bindId); InputState* bindStatePtr(String const& categoryId, String const& bindId);
InputState* inputStatePtr(InputVariant key);
static Input* s_singleton; static Input* s_singleton;
@ -179,7 +197,9 @@ private:
// Per-frame input state maps. // Per-frame input state maps.
//Input states //Input states
HashMap<InputVariant, InputState> m_inputStates; HashMap<Key, KeyInputState> m_keyStates;
HashMap<MouseButton, MouseInputState> m_mouseStates;
HashMap<ControllerButton, ControllerInputState> m_controllerStates;
//Bind states //Bind states
HashMap<BindEntry const*, InputState> m_bindStates; HashMap<BindEntry const*, InputState> m_bindStates;

View File

@ -13,6 +13,23 @@ LuaCallbacks LuaBindings::makeInputCallbacks() {
callbacks.registerCallbackWithSignature<bool, String, String>("bindHeld", bind(mem_fn(&Input::bindHeld), input, _1, _2)); callbacks.registerCallbackWithSignature<bool, String, String>("bindHeld", bind(mem_fn(&Input::bindHeld), input, _1, _2));
callbacks.registerCallbackWithSignature<Maybe<unsigned>, String, String>("bindUp", bind(mem_fn(&Input::bindUp), input, _1, _2)); callbacks.registerCallbackWithSignature<Maybe<unsigned>, String, String>("bindUp", bind(mem_fn(&Input::bindUp), input, _1, _2));
callbacks.registerCallback("keyDown", [input](String const& keyName, Maybe<StringList>& const modNames) -> Maybe<unsigned> {
Key key = KeyNames.getLeft(keyName);
Maybe<KeyMod> mod;
if (modNames) {
mod = KeyMod::NoMod;
for (auto& modName : *modNames)
*mod |= KeyModNames.getLeft(modName);
}
return input->keyDown(key, mod);
});
callbacks.registerCallback("keyHeld", [input](String const& keyName) -> bool { return input->keyHeld(KeyNames.getLeft(keyName)); });
callbacks.registerCallback("keyUp", [input](String const& keyName) -> Maybe<unsigned> { return input->keyUp( KeyNames.getLeft(keyName)); });
callbacks.registerCallback("mouseDown", [input](String const& buttonName) -> Maybe<List<Vec2I>> { return input->mouseDown(MouseButtonNames.getLeft(buttonName)); });
callbacks.registerCallback("mouseHeld", [input](String const& buttonName) -> bool { return input->mouseHeld(MouseButtonNames.getLeft(buttonName)); });
callbacks.registerCallback("mouseUp", [input](String const& buttonName) -> Maybe<List<Vec2I>> { return input->mouseUp( MouseButtonNames.getLeft(buttonName)); });
callbacks.registerCallbackWithSignature<void, String, String>("resetBinds", bind(mem_fn(&Input::resetBinds), input, _1, _2)); callbacks.registerCallbackWithSignature<void, String, String>("resetBinds", bind(mem_fn(&Input::resetBinds), input, _1, _2));
callbacks.registerCallbackWithSignature<void, String, String, Json>("setBinds", bind(mem_fn(&Input::setBinds), input, _1, _2, _3)); callbacks.registerCallbackWithSignature<void, String, String, Json>("setBinds", bind(mem_fn(&Input::setBinds), input, _1, _2, _3));
callbacks.registerCallbackWithSignature<Json, String, String>("getDefaultBinds", bind(mem_fn(&Input::getDefaultBinds), input, _1, _2)); callbacks.registerCallbackWithSignature<Json, String, String>("getDefaultBinds", bind(mem_fn(&Input::getDefaultBinds), input, _1, _2));