Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
SceneInput.cpp
Go to the documentation of this file.
1
2
3#include "Headers/Scene.h"
5
7
8namespace Divide
9{
10
11 namespace
12 {
13 constexpr bool g_recordInput = true;
14 }
15
16 void PressReleaseActionCbks::from( const PressReleaseActions& actions, const InputActionList& actionList )
17 {
18
19 _entries.reserve( actions.entries().size() );
20 for ( const PressReleaseActions::Entry& entry : actions.entries() )
21 {
22 Entry& newEntry = _entries.emplace_back();
23 newEntry._actions[to_base( PressReleaseActions::Action::PRESS )].reserve( entry.pressIDs().size() );
24 newEntry._actions[to_base( PressReleaseActions::Action::RELEASE )].reserve( entry.releaseIDs().size() );
25 newEntry._modifiers = entry.modifiers();
26
27 for ( const U16 id : entry.pressIDs() )
28 {
29 newEntry._actions[to_base( PressReleaseActions::Action::PRESS )].push_back( actionList.getInputAction( id )._action );
30 }
31 for ( const U16 id : entry.releaseIDs() )
32 {
33 newEntry._actions[to_base( PressReleaseActions::Action::RELEASE )].push_back( actionList.getInputAction( id )._action );
34 }
35 }
36 }
37
39 : _parentScene( parentScene )
40 {
41 }
42
43
45 {
46
47 }
48
50 {
51
52 }
53
54 void SceneInput::onPlayerAdd( const U8 index )
55 {
56 insert( _keyLog, index, KeyLog() );
57 insert( _mouseBtnLog, index, MouseBtnLog() );
58 }
59
60 void SceneInput::onPlayerRemove( const U8 index )
61 {
62 _keyLog.find( index )->second.clear();
63 _mouseBtnLog.find( index )->second.clear();
64 }
65
66 U8 SceneInput::getPlayerIndexForDevice( const U8 deviceIndex ) const
67 {
68 return deviceIndex;
69 }
70
72 const InputParams& params,
73 const bool onPress )
74 {
75 for ( const PressReleaseActionCbks::Entry& entry : cbks._entries )
76 {
77 //Check modifiers
78 for ( const Input::KeyCode modifier : entry._modifiers )
79 {
80 if ( GetKeyState( params._deviceIndex, modifier ) != Input::InputState::PRESSED )
81 {
82 goto next;
83 }
84 }
85
86 {
87 const auto& actions = entry._actions[to_base( onPress ? PressReleaseActions::Action::PRESS
89 if ( !actions.empty() )
90 {
91 for ( const auto& action : actions )
92 {
93 action( params );
94 }
95
96 return true;
97 }
98 }
99
100 next:
101 //Failed modifier test
102 NOP();
103 }
104
105 return false;
106 }
107
109 {
110 if ( g_recordInput )
111 {
112 _keyLog[arg._deviceIndex].emplace_back(
114 arg._key,
116 }
117 );
118 }
119
121 if ( getKeyMapping( arg._key, cbks ) )
122 {
123 return handleCallbacks( cbks,
125 to_base(arg._key),
126 {{
127 arg._modMask,
128 -1,
129 -1,
130 -1,
131 -1,
132 -1
133 }}),
134 true );
135 }
136
137 return false;
138 }
139
140 bool SceneInput::onKeyUp( const Input::KeyEvent& arg )
141 {
142 if ( g_recordInput )
143 {
144 _keyLog[arg._deviceIndex].emplace_back(
146 arg._key,
147 Input::InputState::RELEASED
148 }
149 );
150 }
151
153 if ( getKeyMapping( arg._key, cbks ) )
154 {
155 return handleCallbacks( cbks,
157 to_base( arg._key ),
158 {{
159 arg._modMask,
160 -1,
161 -1,
162 -1,
163 -1,
164 -1
165 }}),
166 false );
167 }
168
169 return false;
170 }
171
172 bool SceneInput::joystickButtonPressed( const Input::JoystickEvent& arg )
173 {
174 const Input::Joystick joy = static_cast<Input::Joystick>(arg._deviceIndex);
176
177
178 if ( getJoystickMapping( joy, arg._element._type, arg._element._elementIndex, cbks ) )
179 {
180 return handleCallbacks( cbks, InputParams( arg._deviceIndex, arg._element._elementIndex), true );
181 }
182
183 return false;
184 }
185
186 bool SceneInput::joystickButtonReleased( const Input::JoystickEvent& arg )
187 {
188 const Input::Joystick joy = static_cast<Input::Joystick>(arg._deviceIndex);
189
191 if ( getJoystickMapping( joy, arg._element._type, arg._element._elementIndex, cbks ) )
192 {
193 return handleCallbacks( cbks, InputParams( arg._deviceIndex, arg._element._elementIndex ), false );
194 }
195
196 return false;
197 }
198
199 bool SceneInput::joystickAxisMoved( const Input::JoystickEvent& arg )
200 {
201 const Input::Joystick joy = static_cast<Input::Joystick>(arg._deviceIndex);
202
204 if ( getJoystickMapping( joy, arg._element._type, arg._element._elementIndex, cbks ) )
205 {
206 const InputParams params( arg._deviceIndex,
207 arg._element._elementIndex, // axis index
208 {{
209 arg._element._data._gamePad ? 1 : 0, // is gamepad
210 arg._element._data._deadZone, // dead zone
211 arg._element._data._dataSigned, // move value
212 -1, // not used
213 -1, // not used
214 -1 // not used
215 }});
216 return handleCallbacks( cbks, params, true );
217 }
218
219 return false;
220 }
221
222 bool SceneInput::joystickPovMoved( const Input::JoystickEvent& arg )
223 {
224 const Input::Joystick joy = static_cast<Input::Joystick>(arg._deviceIndex);
225
227 if ( getJoystickMapping( joy, arg._element._type, arg._element._elementIndex, cbks ) )
228 {
229 const InputParams params( arg._deviceIndex,
231 {{
232 to_I32(arg._element._data._data), //explicit cast for reference
233 -1,
234 -1,
235 -1,
236 -1,
237 -1
238 }});
239 return handleCallbacks( cbks, params, true );
240 }
241
242 return false;
243 }
244
245 bool SceneInput::joystickBallMoved( const Input::JoystickEvent& arg )
246 {
247 const Input::Joystick joy = static_cast<Input::Joystick>(arg._deviceIndex);
248
250 if ( getJoystickMapping( joy, arg._element._type, arg._element._elementIndex, cbks ) )
251 {
252 const InputParams params( arg._deviceIndex,
254 {{
255 arg._element._data._gamePad ? 1 : 0,
256 arg._element._data._smallDataSigned[0],
257 arg._element._data._smallDataSigned[1],
258 -1,
259 -1,
260 -1
261 }});
262 return handleCallbacks( cbks, params, true );
263 }
264
265 return false;
266 }
267
268 bool SceneInput::joystickAddRemove( [[maybe_unused]] const Input::JoystickEvent& arg )
269 {
270 return false;
271 }
272
273 bool SceneInput::joystickRemap( [[maybe_unused]] const Input::JoystickEvent& arg )
274 {
275 return false;
276 }
277
278 bool SceneInput::mouseMoved( const Input::MouseMoveEvent& arg )
279 {
280 const PlayerIndex idx = getPlayerIndexForDevice( arg._deviceIndex );
281 SceneStatePerPlayer& state = _parentScene.state()->playerState( idx );
282
283 if ( arg._wheelEvent )
284 {
285 const I32 wheel = arg.state().VWheel;
286 if ( wheel == 0 )
287 {
288 state._zoom.reset();
289 }
290 else
291 {
292 const U8 speed = std::abs(wheel) > 1 ? 255u : 128u;
293 state._zoom.push( { speed, wheel > 0 ? MoveDirection::POSITIVE : MoveDirection::NEGATIVE} );
294 }
295 }
296 else if ( state.cameraLockedToMouse() )
297 {
298 const I32 xRel = arg.state().X.rel;
299 const I32 yRel = arg.state().Y.rel;
300
301 if ( xRel == 0 )
302 {
303 state._angleLR.reset();
304 }
305 else
306 {
307 const U8 speed = std::abs(xRel) > 1 ? 255u : 192u;
308 state._angleLR.push( {speed, xRel > 0 ? MoveDirection::POSITIVE : MoveDirection::NEGATIVE} );
309 }
310
311 if ( yRel == 0 )
312 {
313 state._angleUD.reset();
314 }
315 else
316 {
317 const U8 speed = std::abs( yRel ) > 1 ? 255u : 192u;
318 state._angleUD.push( {speed, yRel > 0 ? MoveDirection::POSITIVE : MoveDirection::NEGATIVE} );
319 }
320 }
321
322 return Attorney::SceneInput::mouseMoved( &_parentScene, arg );
323 }
324
325 bool SceneInput::mouseButtonPressed( const Input::MouseButtonEvent& arg )
326 {
327 if ( g_recordInput )
328 {
329 _mouseBtnLog[arg._deviceIndex].emplace_back(
331 ._position = {arg.state().X.abs, arg.state().Y.abs},
332 ._button = arg.button(),
333 ._state = Input::InputState::PRESSED
334 }
335 );
336 }
337
338 PressReleaseActionCbks cbks = {};
339 if ( getMouseMapping( arg.button(), cbks ) )
340 {
341 InputParams params( arg._deviceIndex,
342 to_base( arg.button() ),
343 {{
344 arg.state().X.abs,
345 arg.state().Y.abs,
346 -1,
347 -1,
348 -1,
349 -1
350 }});
351
352 return handleCallbacks( cbks, params, true );
353 }
354
355 return false;
356 }
357
358 bool SceneInput::mouseButtonReleased( const Input::MouseButtonEvent& arg )
359 {
360 if ( g_recordInput )
361 {
362 _mouseBtnLog[arg._deviceIndex].emplace_back(
364 ._position = {arg.state().X.abs, arg.state().Y.abs},
365 ._button = arg.button(),
366 ._state = Input::InputState::RELEASED
367 }
368 );
369 }
370
371 PressReleaseActionCbks cbks = {};
372 if ( getMouseMapping( arg.button(), cbks ) )
373 {
374 InputParams params( arg._deviceIndex,
375 to_base( arg.button() ),
376 {{
377 arg.state().X.abs,
378 arg.state().Y.abs,
379 -1,
380 -1,
381 -1,
382 -1
383 }});
384 return handleCallbacks( cbks, params, false );
385 }
386
387 return false;
388 }
389
390 bool SceneInput::onTextEvent( [[maybe_unused]] const Input::TextEvent& arg )
391 {
392 if ( g_recordInput )
393 {
394 NOP();
395 }
396
397 return false;
398 }
399
400 bool SceneInput::addKeyMapping( const Input::KeyCode key, const PressReleaseActions::Entry& keyCbks )
401 {
402 return _keyMap[key].add( keyCbks );
403 }
404
405 bool SceneInput::removeKeyMapping( const Input::KeyCode key )
406 {
407 const KeyMap::iterator it = _keyMap.find( key );
408 if ( it != std::end( _keyMap ) )
409 {
410 _keyMap.erase( it );
411 return false;
412 }
413
414 return false;
415 }
416
417 bool SceneInput::getKeyMapping( const Input::KeyCode key, PressReleaseActionCbks& keyCbksOut )
418 {
419 const KeyMapCache::const_iterator itCache = _keyMapCache.find( key );
420 if ( itCache != std::cend(_keyMapCache) )
421 {
422 keyCbksOut = itCache->second;
423 return true;
424 }
425
426 const KeyMap::const_iterator it = _keyMap.find( key );
427 if ( it != std::cend( _keyMap ) )
428 {
429 const PressReleaseActions& actions = it->second;
430 keyCbksOut.from( actions, _actionList );
431 insert( _keyMapCache, key, keyCbksOut );
432
433 return true;
434 }
435
436 return false;
437 }
438
439 bool SceneInput::addMouseMapping( const Input::MouseButton button, const PressReleaseActions::Entry& btnCbks )
440 {
441 return _mouseMap[button].add( btnCbks );
442 }
443
444 bool SceneInput::removeMouseMapping( const Input::MouseButton button )
445 {
446 const MouseMap::iterator it = _mouseMap.find( button );
447 if ( it != std::end( _mouseMap ) )
448 {
449 _mouseMap.erase( it );
450 return false;
451 }
452
453 return false;
454 }
455
456 bool SceneInput::getMouseMapping( const Input::MouseButton button, PressReleaseActionCbks& btnCbksOut )
457 {
458 const MouseMapCache::const_iterator itCache = _mouseMapCache.find( button );
459 if ( itCache != std::cend( _mouseMapCache ) )
460 {
461 btnCbksOut = itCache->second;
462 return true;
463 }
464
465
466 const MouseMap::const_iterator it = _mouseMap.find( button );
467 if ( it != std::cend( _mouseMap ) )
468 {
469 const PressReleaseActions& actions = it->second;
470 btnCbksOut.from( actions, _actionList );
471 insert( _mouseMapCache, button, btnCbksOut );
472 return true;
473 }
474
475 return false;
476 }
477
478 bool SceneInput::addJoystickMapping( const Input::Joystick device, const Input::JoystickElementType elementType, const U32 id, const PressReleaseActions::Entry& btnCbks )
479 {
480 const JoystickMapKey key{
481 ._id = id,
482 ._element = elementType
483 };
484
485 return _joystickMap[to_base( device )][key].add( btnCbks );
486 }
487
488 bool SceneInput::removeJoystickMapping( const Input::Joystick device, const Input::JoystickElementType elementType, const U32 id )
489 {
490 JoystickMapEntry& entry = _joystickMap[to_base( device )];
491
492 const JoystickMapEntry::iterator it = entry.find(
493 {
494 ._id = id,
495 ._element = elementType
496 }
497 );
498 if ( it != std::end( entry ) )
499 {
500 entry.erase( it );
501 return false;
502 }
503
504 return false;
505 }
506
507 bool SceneInput::getJoystickMapping( const Input::Joystick device, const Input::JoystickElementType elementType, U32 id, PressReleaseActionCbks& btnCbksOut )
508 {
509 JoystickMapCacheEntry& entry = _joystickMapCache[to_base( device )];
510
511 const JoystickMapCacheEntry::const_iterator itCache = entry.find(
512 {
513 ._id = id,
514 ._element = elementType
515 } );
516 if ( itCache != std::cend( entry ) )
517 {
518 btnCbksOut = itCache->second;
519 return true;
520 }
521
522 JoystickMapEntry& entry2 = _joystickMap[to_base( device )];
523 const JoystickMapEntry::const_iterator it = entry2.find(
524 {
525 ._id = id,
526 ._element = elementType
527 } );
528 if ( it != std::cend( entry2 ) )
529 {
530 const PressReleaseActions& actions = it->second;
531 btnCbksOut.from( actions, _actionList );
532 entry[JoystickMapKey{ ._id = id, ._element = elementType }] = btnCbksOut;
533 return true;
534 }
535
536 return false;
537 }
538
539 InputActionList& SceneInput::actionList() noexcept
540 {
541 return _actionList;
542 }
543
544 void SceneInput::flushCache()
545 {
546 _keyMapCache.clear();
547 _mouseMapCache.clear();
548 _joystickMapCache.clear();
549 }
550} //namespace Divide
#define NOP()
InputAction & getInputAction(U16 id)
SceneInput(Scene &parentScene)
Definition: SceneInput.cpp:38
hashMap< U8, MouseBtnLog > _mouseBtnLog
Definition: SceneInput.h:179
hashMap< U8, KeyLog > _keyLog
Definition: SceneInput.h:178
ska::bytell_hash_map< JoystickMapKey, PressReleaseActions, JoystickMapKeyHash > JoystickMapEntry
Definition: SceneInput.h:84
bool handleCallbacks(const PressReleaseActionCbks &cbks, const InputParams &params, bool onPress)
Definition: SceneInput.cpp:71
bool getKeyMapping(Input::KeyCode key, PressReleaseActionCbks &keyCbksOut)
Definition: SceneInput.cpp:417
void onPlayerAdd(U8 index)
Definition: SceneInput.cpp:54
ska::bytell_hash_map< JoystickMapKey, PressReleaseActionCbks, JoystickMapKeyHash > JoystickMapCacheEntry
Definition: SceneInput.h:79
bool onKeyDown(const Input::KeyEvent &arg) override
Keyboard: return true if input was consumed.
Definition: SceneInput.cpp:108
void onPlayerRemove(U8 index)
Definition: SceneInput.cpp:60
vector< KeyLogState > KeyLog
Definition: SceneInput.h:100
vector< MouseLogState > MouseBtnLog
Definition: SceneInput.h:101
U8 getPlayerIndexForDevice(U8 deviceIndex) const
Definition: SceneInput.cpp:66
JoystickElementType
Definition: Input.h:53
Joystick
Points to the position of said joystick in the vector.
Definition: Input.h:39
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
void insert(eastl::vector< T, A1 > &target, const eastl::vector< T, A2 > &source)
Definition: Vector.h:97
int32_t I32
uint8_t U8
uint16_t U16
uint32_t U32
Project const SceneEntry & entry
Definition: DefaultScene.h:41
constexpr auto to_base(const Type value) -> Type
JoystickElementType _type
Definition: Input.h:85
const MouseState & state() const noexcept
DELEGATE< void, InputParams > _action
void reset() noexcept
Definition: SceneState.h:180
void push(const MoveDirectionRequest direction) noexcept
Definition: SceneState.h:168
Definition: SceneInput.h:64
std::array< vector< DELEGATE< void, InputParams > >, to_base(PressReleaseActions::Action::COUNT)> _actions
Definition: SceneInput.h:66
eastl::set< Input::KeyCode > _modifiers
Definition: SceneInput.h:65
void from(const PressReleaseActions &actions, const InputActionList &actionList)
Definition: SceneInput.cpp:16