Skip to content

Commit 78d951e

Browse files
Mouse mapping support (Kenix3#741)
* init * fix spelling * mose key to button mapping * more button mouse mapping * separate file for mouse things cause Ive got recursive include problem * some fixes * updating dxgi mouse capture now compatible with sdl one * fix * fix mouse capture clip missing after alt+tab * mouse binding & gui conflict check * new mouse input block * Mouse mapping menu update * fix ImGui `WantCaptureKeyboard` locks when holding mouse button * reading mouse from config casually forgotten * fixed strange buffered mapping bug * mouse buttons callbacks * mouse button to axis mapping * fix * mark * use propper cursor hide method * merge-fixes * clang-format * store main game window ID to reduce load * update on_mouse_up/down in dxgi * MouseMeta migration * MouseKey -> MouseButton * fix name collision * another name collision fix * remove imgui direct calls * clang-format * MouseCapture keybind * replace cursor visibility with mouse capture * clang-format * mUseKeydownEventToCreateNewMapping -> mUseInputToCreateNewMapping * change MAPPING_TYPE_UNKNOWN to -1 * dxgi/sdl GetMouseDelta parity * set x/y to zero when no capture * mapping type uint -> int for MAPPING_TYPE_UNKNOWN = -1 * offset mapping popup * simple popup check completely dropped complexity * clang format * simplify mouse capture toggle * boundaries check for mouse buttons * remove duplicate cursor visibility change in fullscreen * Windows ignore mouse input while mouse is captured * simplify * make separate method for handling capture * fix cast * clang-format * ProcessMouseEvent -> ProcessMouseButtonEvent * wheel mapping support WIP * fix for axis * wheel logging * macos fix? * clang format * fix wheel axis on dx backend * Revert "wheel logging" This reverts commit 43082d8. * buffered wheel axis mapping (test) * clang format * fix * extend buffer * dxgi horizontal scrolling support * clang format --------- Co-authored-by: lilacLunatic <[email protected]>
1 parent 2942915 commit 78d951e

File tree

59 files changed

+1055
-73
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1055
-73
lines changed

src/controller/controldeck/ControlDeck.cpp

+31-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#endif
1010
#include <imgui.h>
1111
#include "controller/deviceindex/ShipDeviceIndexMappingManager.h"
12+
#include "controller/controldevice/controller/mapping/mouse/WheelHandler.h"
1213

1314
namespace Ship {
1415

@@ -33,6 +34,7 @@ void ControlDeck::Init(uint8_t* controllerBits) {
3334
// if we don't have a config for controller 1, set default keyboard bindings
3435
if (!mPorts[0]->GetConnectedController()->HasConfig()) {
3536
mPorts[0]->GetConnectedController()->AddDefaultMappings(ShipDeviceIndex::Keyboard);
37+
mPorts[0]->GetConnectedController()->AddDefaultMappings(ShipDeviceIndex::Mouse);
3638
}
3739

3840
Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Controller Reordering")->Show();
@@ -51,6 +53,19 @@ bool ControlDeck::ProcessKeyboardEvent(KbEventType eventType, KbScancode scancod
5153
return result;
5254
}
5355

56+
bool ControlDeck::ProcessMouseButtonEvent(bool isPressed, MouseBtn button) {
57+
bool result = false;
58+
for (auto port : mPorts) {
59+
auto controller = port->GetConnectedController();
60+
61+
if (controller != nullptr) {
62+
result = controller->ProcessMouseButtonEvent(isPressed, button) || result;
63+
}
64+
}
65+
66+
return result;
67+
}
68+
5469
bool ControlDeck::AllGameInputBlocked() {
5570
return !mGameInputBlockers.empty();
5671
}
@@ -63,7 +78,21 @@ bool ControlDeck::GamepadGameInputBlocked() {
6378

6479
bool ControlDeck::KeyboardGameInputBlocked() {
6580
// block keyboard input when typing in imgui
66-
return AllGameInputBlocked() || ImGui::GetIO().WantCaptureKeyboard;
81+
ImGuiWindow* activeIDWindow = ImGui::GetCurrentContext()->ActiveIdWindow;
82+
return AllGameInputBlocked() ||
83+
(activeIDWindow != NULL &&
84+
activeIDWindow->ID != Context::GetInstance()->GetWindow()->GetGui()->GetMainGameWindowID()) ||
85+
ImGui::GetTopMostPopupModal() != NULL; // ImGui::GetIO().WantCaptureKeyboard, but ActiveId check altered
86+
}
87+
88+
bool ControlDeck::MouseGameInputBlocked() {
89+
// block mouse input when user interacting with gui
90+
ImGuiWindow* window = ImGui::GetCurrentContext()->HoveredWindow;
91+
if (window == NULL) {
92+
return true;
93+
}
94+
return AllGameInputBlocked() ||
95+
(window->ID != Context::GetInstance()->GetWindow()->GetGui()->GetMainGameWindowID());
6796
}
6897

6998
std::shared_ptr<Controller> ControlDeck::GetControllerByPort(uint8_t port) {
@@ -112,6 +141,7 @@ void ControlDeck::WriteToPad(void* pad) {
112141

113142
void ControlDeck::WriteToOSContPad(OSContPad* pad) {
114143
SDL_PumpEvents();
144+
Ship::WheelHandler::GetInstance()->Update();
115145

116146
if (AllGameInputBlocked()) {
117147
return;

src/controller/controldeck/ControlDeck.h

+3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ class ControlDeck {
2121
void UnblockGameInput(int32_t blockId);
2222
bool GamepadGameInputBlocked();
2323
bool KeyboardGameInputBlocked();
24+
bool MouseGameInputBlocked();
2425
void SetSinglePlayerMappingMode(bool singlePlayer);
2526
bool IsSinglePlayerMappingMode();
2627
bool ProcessKeyboardEvent(KbEventType eventType, KbScancode scancode);
28+
bool ProcessMouseButtonEvent(bool isPressed, MouseBtn button);
29+
2730
std::shared_ptr<ShipDeviceIndexMappingManager> GetDeviceIndexMappingManager();
2831

2932
protected:

src/controller/controldevice/controller/Controller.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ bool Controller::ProcessKeyboardEvent(KbEventType eventType, KbScancode scancode
136136
return result;
137137
}
138138

139+
bool Controller::ProcessMouseButtonEvent(bool isPressed, MouseBtn mouseButton) {
140+
bool result = false;
141+
for (auto [bitmask, button] : GetAllButtons()) {
142+
result = button->ProcessMouseButtonEvent(isPressed, mouseButton) || result;
143+
}
144+
result = GetLeftStick()->ProcessMouseButtonEvent(isPressed, mouseButton) || result;
145+
result = GetRightStick()->ProcessMouseButtonEvent(isPressed, mouseButton) || result;
146+
return result;
147+
}
148+
139149
bool Controller::HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex) {
140150
for (auto [bitmask, button] : GetAllButtons()) {
141151
if (button->HasMappingsForShipDeviceIndex(lusIndex)) {

src/controller/controldevice/controller/Controller.h

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class Controller : public ControlDevice {
4949
std::vector<std::shared_ptr<ControllerMapping>> GetAllMappings();
5050

5151
bool ProcessKeyboardEvent(KbEventType eventType, KbScancode scancode);
52+
bool ProcessMouseButtonEvent(bool isPressed, MouseBtn button);
5253

5354
bool HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex);
5455
void MoveMappingsToDifferentController(std::shared_ptr<Controller> newController, ShipDeviceIndex lusIndex);

src/controller/controldevice/controller/ControllerButton.cpp

+41-5
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@
33
#include "controller/controldevice/controller/mapping/factories/ButtonMappingFactory.h"
44

55
#include "controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.h"
6+
#include "controller/controldevice/controller/mapping/mouse/MouseButtonToButtonMapping.h"
67

78
#include "public/bridge/consolevariablebridge.h"
89
#include "utils/StringHelper.h"
910
#include <sstream>
1011
#include <algorithm>
1112

13+
#include "Context.h"
14+
1215
namespace Ship {
1316
ControllerButton::ControllerButton(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask)
14-
: mPortIndex(portIndex), mBitmask(bitmask), mUseKeydownEventToCreateNewMapping(false),
15-
mKeyboardScancodeForNewMapping(LUS_KB_UNKNOWN) {
17+
: mPortIndex(portIndex), mBitmask(bitmask), mUseEventInputToCreateNewMapping(false),
18+
mKeyboardScancodeForNewMapping(LUS_KB_UNKNOWN), mMouseButtonForNewMapping(LUS_MOUSE_BTN_UNKNOWN) {
1619
}
1720

1821
ControllerButton::~ControllerButton() {
@@ -175,11 +178,20 @@ bool ControllerButton::HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex) {
175178
bool ControllerButton::AddOrEditButtonMappingFromRawPress(CONTROLLERBUTTONS_T bitmask, std::string id) {
176179
std::shared_ptr<ControllerButtonMapping> mapping = nullptr;
177180

178-
mUseKeydownEventToCreateNewMapping = true;
181+
mUseEventInputToCreateNewMapping = true;
179182
if (mKeyboardScancodeForNewMapping != LUS_KB_UNKNOWN) {
180183
mapping = std::make_shared<KeyboardKeyToButtonMapping>(mPortIndex, bitmask, mKeyboardScancodeForNewMapping);
181184
}
182185

186+
else if (!Context::GetInstance()->GetWindow()->GetGui()->IsMouseOverAnyGuiItem() &&
187+
Context::GetInstance()->GetWindow()->GetGui()->IsMouseOverActivePopup()) {
188+
if (mMouseButtonForNewMapping != LUS_MOUSE_BTN_UNKNOWN) {
189+
mapping = std::make_shared<MouseButtonToButtonMapping>(mPortIndex, bitmask, mMouseButtonForNewMapping);
190+
} else {
191+
mapping = ButtonMappingFactory::CreateButtonMappingFromMouseWheelInput(mPortIndex, bitmask);
192+
}
193+
}
194+
183195
if (mapping == nullptr) {
184196
mapping = ButtonMappingFactory::CreateButtonMappingFromSDLInput(mPortIndex, bitmask);
185197
}
@@ -189,7 +201,8 @@ bool ControllerButton::AddOrEditButtonMappingFromRawPress(CONTROLLERBUTTONS_T bi
189201
}
190202

191203
mKeyboardScancodeForNewMapping = LUS_KB_UNKNOWN;
192-
mUseKeydownEventToCreateNewMapping = false;
204+
mMouseButtonForNewMapping = LUS_MOUSE_BTN_UNKNOWN;
205+
mUseEventInputToCreateNewMapping = false;
193206

194207
if (id != "") {
195208
ClearButtonMapping(id);
@@ -206,7 +219,7 @@ bool ControllerButton::AddOrEditButtonMappingFromRawPress(CONTROLLERBUTTONS_T bi
206219
}
207220

208221
bool ControllerButton::ProcessKeyboardEvent(KbEventType eventType, KbScancode scancode) {
209-
if (mUseKeydownEventToCreateNewMapping && eventType == LUS_KB_EVENT_KEY_DOWN) {
222+
if (mUseEventInputToCreateNewMapping) {
210223
if (eventType == LUS_KB_EVENT_KEY_DOWN) {
211224
mKeyboardScancodeForNewMapping = scancode;
212225
return true;
@@ -228,6 +241,29 @@ bool ControllerButton::ProcessKeyboardEvent(KbEventType eventType, KbScancode sc
228241
return result;
229242
}
230243

244+
bool ControllerButton::ProcessMouseButtonEvent(bool isPressed, MouseBtn button) {
245+
if (mUseEventInputToCreateNewMapping) {
246+
if (isPressed) {
247+
mMouseButtonForNewMapping = button;
248+
return true;
249+
} else {
250+
mMouseButtonForNewMapping = LUS_MOUSE_BTN_UNKNOWN;
251+
}
252+
}
253+
254+
bool result = false;
255+
for (auto [id, mapping] : GetAllButtonMappings()) {
256+
if (mapping->GetMappingType() == MAPPING_TYPE_MOUSE) {
257+
std::shared_ptr<MouseButtonToButtonMapping> mtobMapping =
258+
std::dynamic_pointer_cast<MouseButtonToButtonMapping>(mapping);
259+
if (mtobMapping != nullptr) {
260+
result = result || mtobMapping->ProcessMouseButtonEvent(isPressed, button);
261+
}
262+
}
263+
}
264+
return result;
265+
}
266+
231267
void ControllerButton::AddDefaultMappings(ShipDeviceIndex shipDeviceIndex) {
232268
for (auto mapping : ButtonMappingFactory::CreateDefaultSDLButtonMappings(shipDeviceIndex, mPortIndex, mBitmask)) {
233269
AddButtonMapping(mapping);

src/controller/controldevice/controller/ControllerButton.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ControllerButton {
3737
void UpdatePad(CONTROLLERBUTTONS_T& padButtons);
3838

3939
bool ProcessKeyboardEvent(KbEventType eventType, KbScancode scancode);
40+
bool ProcessMouseButtonEvent(bool isPressed, Ship::MouseBtn button);
4041

4142
bool HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex);
4243

@@ -46,7 +47,8 @@ class ControllerButton {
4647
std::unordered_map<std::string, std::shared_ptr<ControllerButtonMapping>> mButtonMappings;
4748
std::string GetConfigNameFromBitmask(CONTROLLERBUTTONS_T bitmask);
4849

49-
bool mUseKeydownEventToCreateNewMapping;
50+
bool mUseEventInputToCreateNewMapping;
5051
KbScancode mKeyboardScancodeForNewMapping;
52+
MouseBtn mMouseButtonForNewMapping;
5153
};
5254
} // namespace Ship

src/controller/controldevice/controller/ControllerStick.cpp

+43-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <spdlog/spdlog.h>
33

44
#include "controller/controldevice/controller/mapping/keyboard/KeyboardKeyToAxisDirectionMapping.h"
5+
#include "controller/controldevice/controller/mapping/mouse/MouseButtonToAxisDirectionMapping.h"
56

67
#include "controller/controldevice/controller/mapping/factories/AxisDirectionMappingFactory.h"
78

@@ -11,6 +12,8 @@
1112
#include <sstream>
1213
#include <algorithm>
1314

15+
#include "Context.h"
16+
1417
// for some reason windows isn't seeing M_PI
1518
// this is copied from my system's math.h
1619
#ifndef M_PI
@@ -22,8 +25,8 @@
2225

2326
namespace Ship {
2427
ControllerStick::ControllerStick(uint8_t portIndex, StickIndex stickIndex)
25-
: mPortIndex(portIndex), mStickIndex(stickIndex), mUseKeydownEventToCreateNewMapping(false),
26-
mKeyboardScancodeForNewMapping(KbScancode::LUS_KB_UNKNOWN) {
28+
: mPortIndex(portIndex), mStickIndex(stickIndex), mUseEventInputToCreateNewMapping(false),
29+
mKeyboardScancodeForNewMapping(KbScancode::LUS_KB_UNKNOWN), mMouseButtonForNewMapping(LUS_MOUSE_BTN_UNKNOWN) {
2730
mSensitivityPercentage = DEFAULT_STICK_SENSITIVITY_PERCENTAGE;
2831
mSensitivity = 1.0f;
2932
mDeadzonePercentage = DEFAULT_STICK_DEADZONE_PERCENTAGE;
@@ -268,12 +271,20 @@ void ControllerStick::Process(int8_t& x, int8_t& y) {
268271
bool ControllerStick::AddOrEditAxisDirectionMappingFromRawPress(Direction direction, std::string id) {
269272
std::shared_ptr<ControllerAxisDirectionMapping> mapping = nullptr;
270273

271-
mUseKeydownEventToCreateNewMapping = true;
274+
mUseEventInputToCreateNewMapping = true;
272275
if (mKeyboardScancodeForNewMapping != LUS_KB_UNKNOWN) {
273276
mapping = std::make_shared<KeyboardKeyToAxisDirectionMapping>(mPortIndex, mStickIndex, direction,
274277
mKeyboardScancodeForNewMapping);
278+
} else if (!Context::GetInstance()->GetWindow()->GetGui()->IsMouseOverAnyGuiItem() &&
279+
Context::GetInstance()->GetWindow()->GetGui()->IsMouseOverActivePopup()) {
280+
if (mMouseButtonForNewMapping != LUS_MOUSE_BTN_UNKNOWN) {
281+
mapping = std::make_shared<MouseButtonToAxisDirectionMapping>(mPortIndex, mStickIndex, direction,
282+
mMouseButtonForNewMapping);
283+
} else {
284+
mapping = AxisDirectionMappingFactory::CreateAxisDirectionMappingFromMouseWheelInput(
285+
mPortIndex, mStickIndex, direction);
286+
}
275287
}
276-
277288
if (mapping == nullptr) {
278289
mapping =
279290
AxisDirectionMappingFactory::CreateAxisDirectionMappingFromSDLInput(mPortIndex, mStickIndex, direction);
@@ -284,7 +295,8 @@ bool ControllerStick::AddOrEditAxisDirectionMappingFromRawPress(Direction direct
284295
}
285296

286297
mKeyboardScancodeForNewMapping = LUS_KB_UNKNOWN;
287-
mUseKeydownEventToCreateNewMapping = false;
298+
mMouseButtonForNewMapping = LUS_MOUSE_BTN_UNKNOWN;
299+
mUseEventInputToCreateNewMapping = false;
288300

289301
if (id != "") {
290302
ClearAxisDirectionMapping(direction, id);
@@ -319,7 +331,7 @@ void ControllerStick::UpdatePad(int8_t& x, int8_t& y) {
319331
}
320332

321333
bool ControllerStick::ProcessKeyboardEvent(KbEventType eventType, KbScancode scancode) {
322-
if (mUseKeydownEventToCreateNewMapping) {
334+
if (mUseEventInputToCreateNewMapping) {
323335
if (eventType == LUS_KB_EVENT_KEY_DOWN) {
324336
mKeyboardScancodeForNewMapping = scancode;
325337
return true;
@@ -343,6 +355,31 @@ bool ControllerStick::ProcessKeyboardEvent(KbEventType eventType, KbScancode sca
343355
return result;
344356
}
345357

358+
bool ControllerStick::ProcessMouseButtonEvent(bool isPressed, MouseBtn button) {
359+
if (mUseEventInputToCreateNewMapping) {
360+
if (isPressed) {
361+
mMouseButtonForNewMapping = button;
362+
return true;
363+
} else {
364+
mMouseButtonForNewMapping = LUS_MOUSE_BTN_UNKNOWN;
365+
}
366+
}
367+
368+
bool result = false;
369+
for (auto [direction, mappings] : mAxisDirectionMappings) {
370+
for (auto [id, mapping] : mappings) {
371+
if (mapping->GetMappingType() == MAPPING_TYPE_MOUSE) {
372+
std::shared_ptr<MouseButtonToAxisDirectionMapping> mtoadMapping =
373+
std::dynamic_pointer_cast<MouseButtonToAxisDirectionMapping>(mapping);
374+
if (mtoadMapping != nullptr) {
375+
result = result || mtoadMapping->ProcessMouseButtonEvent(isPressed, button);
376+
}
377+
}
378+
}
379+
}
380+
return result;
381+
}
382+
346383
void ControllerStick::SetSensitivity(uint8_t sensitivityPercentage) {
347384
mSensitivityPercentage = sensitivityPercentage;
348385
mSensitivity = sensitivityPercentage / 100.0f;

src/controller/controldevice/controller/ControllerStick.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class ControllerStick {
5252
bool NotchSnapAngleIsDefault();
5353

5454
bool ProcessKeyboardEvent(KbEventType eventType, KbScancode scancode);
55+
bool ProcessMouseButtonEvent(bool isPressed, Ship::MouseBtn button);
5556

5657
bool HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex);
5758
StickIndex GetStickIndex();
@@ -75,7 +76,8 @@ class ControllerStick {
7576
std::unordered_map<Direction, std::unordered_map<std::string, std::shared_ptr<ControllerAxisDirectionMapping>>>
7677
mAxisDirectionMappings;
7778

78-
bool mUseKeydownEventToCreateNewMapping;
79+
bool mUseEventInputToCreateNewMapping;
7980
KbScancode mKeyboardScancodeForNewMapping;
81+
MouseBtn mMouseButtonForNewMapping;
8082
};
8183
} // namespace Ship

src/controller/controldevice/controller/mapping/ControllerAxisDirectionMapping.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ ControllerAxisDirectionMapping::ControllerAxisDirectionMapping(ShipDeviceIndex s
1212
ControllerAxisDirectionMapping::~ControllerAxisDirectionMapping() {
1313
}
1414

15-
uint8_t ControllerAxisDirectionMapping::GetMappingType() {
15+
int8_t ControllerAxisDirectionMapping::GetMappingType() {
1616
return MAPPING_TYPE_UNKNOWN;
1717
}
1818

src/controller/controldevice/controller/mapping/ControllerAxisDirectionMapping.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ControllerAxisDirectionMapping : virtual public ControllerInputMapping {
1717
Direction direction);
1818
~ControllerAxisDirectionMapping();
1919
virtual float GetNormalizedAxisDirectionValue() = 0;
20-
virtual uint8_t GetMappingType();
20+
virtual int8_t GetMappingType();
2121

2222
virtual std::string GetAxisDirectionMappingId() = 0;
2323
virtual void SaveToConfig() = 0;

src/controller/controldevice/controller/mapping/ControllerButtonMapping.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ CONTROLLERBUTTONS_T ControllerButtonMapping::GetBitmask() {
1818
return mBitmask;
1919
}
2020

21-
uint8_t ControllerButtonMapping::GetMappingType() {
21+
int8_t ControllerButtonMapping::GetMappingType() {
2222
return MAPPING_TYPE_UNKNOWN;
2323
}
2424

src/controller/controldevice/controller/mapping/ControllerButtonMapping.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class ControllerButtonMapping : virtual public ControllerInputMapping {
2020

2121
CONTROLLERBUTTONS_T GetBitmask();
2222
virtual void UpdatePad(CONTROLLERBUTTONS_T& padButtons) = 0;
23-
virtual uint8_t GetMappingType();
23+
virtual int8_t GetMappingType();
2424
void SetPortIndex(uint8_t portIndex);
2525

2626
virtual void SaveToConfig() = 0;

src/controller/controldevice/controller/mapping/ControllerMapping.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66
namespace Ship {
77

8+
#define MAPPING_TYPE_UNKNOWN -1
89
#define MAPPING_TYPE_GAMEPAD 0
910
#define MAPPING_TYPE_KEYBOARD 1
10-
#define MAPPING_TYPE_UNKNOWN 2
11+
#define MAPPING_TYPE_MOUSE 2
1112

1213
class ControllerMapping {
1314
public:

0 commit comments

Comments
 (0)