-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathGamepadBindingCollection.cpp
More file actions
112 lines (104 loc) · 4.54 KB
/
Copy pathGamepadBindingCollection.cpp
File metadata and controls
112 lines (104 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "GamepadBindingCollection.h"
#include "LogInput.h"
#include <cassert>
#include "KeyBindings.h"
GamepadBindingCollection::GamepadBindingCollection() {
}
GamepadBindingCollection::~GamepadBindingCollection() {
}
bool GamepadBindingCollection::AddMappingWithName( const rString& keyName, ActionIdentifier action, bool overwrite, bool clearConflicting,
rString* errorString ) {
SDL_GameControllerButton button = SDL_GameControllerGetButtonFromString( keyName.c_str() );
if ( button != SDL_CONTROLLER_BUTTON_INVALID ) {
return AddMappingWithButton( button, action, overwrite, clearConflicting, errorString );
} else {
LogInput( "Failed to get scancode from name: " + keyName, "GamepadBindings", LogSeverity::WARNING_MSG );
if ( errorString != nullptr ) {
*errorString = "Failed to get scancode from name: " + keyName;
}
return false;
}
}
bool GamepadBindingCollection::AddMappingWithButton( SDL_GameControllerButton button, ActionIdentifier action, bool overwrite,
bool clearConflicting, rString* errorString ) {
FillTheVoid( action );
auto buttonIt = m_ButtonToAction.find( button );
// Warn about overwriting duplicate gamepad bindings
if ( buttonIt != m_ButtonToAction.end() && !clearConflicting ) {
LogInput( "Can't bind button: \"" + rString( SDL_GameControllerGetStringForButton( button ) ) + "\" to action " +
g_KeyBindings.GetDescription( action ) + " because it is already bound to action \"" +
g_KeyBindings.GetDescription( buttonIt->second ) + "\"",
"KeyBindings", LogSeverity::WARNING_MSG );
if ( errorString != nullptr ) {
*errorString = "Can't bind key: \"" + rString( SDL_GameControllerGetStringForButton( button ) ) + "\" to action " +
g_KeyBindings.GetDescription( action ) + " because it is already bound to action \"" +
g_KeyBindings.GetDescription( buttonIt->second ) + "\"";
}
return false;
} else {
if ( BindAction( action, button, overwrite ) ) {
// Bound button
LogInput( "Bound button \"" + rString( SDL_GameControllerGetStringForButton( button ) ) + "\" to action \"" +
g_KeyBindings.GetDescription( action ) + "\"",
"KeyBindings", LogSeverity::DEBUG_MSG );
if ( errorString != nullptr ) {
*errorString = "Bound button \"" + rString( SDL_GameControllerGetStringForButton( button ) ) + "\" to action \"" +
g_KeyBindings.GetDescription( action ) + "\"";
}
return true;
} else {
// Failed to bind button
LogInput( "Can't bind button: \"" + rString( SDL_GameControllerGetStringForButton( button ) ) + "\" to action \"" +
g_KeyBindings.GetDescription( action ) + "\" because no free bind slots are avaliable",
"KeyBindings", LogSeverity::WARNING_MSG );
if ( errorString != nullptr ) {
*errorString = "Can't bind button: \"" + rString( SDL_GameControllerGetStringForButton( button ) ) + "\" to action \"" +
g_KeyBindings.GetDescription( action ) + "\" because no free bind slots are avaliable";
}
return false;
}
}
}
void GamepadBindingCollection::FillTheVoid( ActionIdentifier action ) {
if ( static_cast<int>( action ) >= static_cast<int>( m_ActionToButton.size() ) ) {
size_t prevSize = m_ActionToButton.size();
m_ActionToButton.resize( static_cast<int>( action ) + 1 );
std::fill( m_ActionToButton.begin() + prevSize, m_ActionToButton.end(), SDL_CONTROLLER_BUTTON_INVALID );
}
}
bool GamepadBindingCollection::BindAction( ActionIdentifier action, SDL_GameControllerButton button, bool overwrite ) {
FillTheVoid( action );
auto freePrevious = [this, action, button]() {
SDL_GameControllerButton prevButton = m_ActionToButton[static_cast<int>( action )];
if ( prevButton != SDL_CONTROLLER_BUTTON_INVALID ) {
auto it = m_ButtonToAction.find( prevButton );
if ( it != m_ButtonToAction.end() ) {
m_ButtonToAction.erase( it );
}
}
};
auto addBinding = [this, action, button, &freePrevious]() {
freePrevious();
m_ActionToButton.at( static_cast<int>( action ) ) = button;
m_ButtonToAction[button] = action;
};
if ( overwrite ) {
addBinding();
return true;
} else {
// No overwriting
// Only bind unbound action
if ( m_ActionToButton[static_cast<int>( action )] == SDL_CONTROLLER_BUTTON_INVALID ) {
addBinding();
return true;
}
// Failed to bind
return false;
}
}
SDL_GameControllerButton GamepadBindingCollection::GetButtonFromAction( ActionIdentifier action ) const {
if ( static_cast<size_t>( static_cast<int>( action ) ) >= m_ActionToButton.size( ) ) {
return SDL_CONTROLLER_BUTTON_INVALID;
}
return m_ActionToButton.at( static_cast<int>( action ) );
}