forked from Mirrors/openclonk
Remove gamepad ids from key codes
We want one gamepad key mapping to work with multiple gamepads, so including the id there doesn't make sense. Additionally, the gamepad id may change during the game (controller hot-plugging).liquid_container
parent
9f69c650d6
commit
9e0143b998
|
@ -24,6 +24,7 @@
|
|||
#include "C4PlayerList.h"
|
||||
#include "C4Control.h"
|
||||
#include "C4Game.h"
|
||||
#include "C4GamePadCon.h"
|
||||
#include "C4Log.h"
|
||||
#include "C4GraphicsResource.h"
|
||||
#include "C4MouseControl.h"
|
||||
|
@ -1011,6 +1012,13 @@ void C4PlayerControl::CompileFunc(StdCompiler *pComp)
|
|||
|
||||
bool C4PlayerControl::ProcessKeyEvent(const C4KeyCodeEx &pressed_key, const C4KeyCodeEx &matched_key, ControlState state, const C4KeyEventData &rKeyExtraData, bool reset_down_states_only, bool *clear_recent_keys)
|
||||
{
|
||||
if (Key_IsGamepad(pressed_key.Key))
|
||||
{
|
||||
// We have to filter gamepad events here.
|
||||
C4Player *plr = ::Players.Get(iPlr);
|
||||
if (!plr || !plr->pGamepad || plr->pGamepad->GetID() != pressed_key.deviceId)
|
||||
return false;
|
||||
}
|
||||
// collect all matching keys
|
||||
C4PlayerControlAssignmentPVec Matches;
|
||||
assert(pControlSet); // shouldn't get this callback for players without control set
|
||||
|
|
|
@ -1891,6 +1891,12 @@ bool C4Game::DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType eEventType, bool
|
|||
#endif
|
||||
// compose key
|
||||
C4KeyCodeEx Key(vk_code, C4KeyShiftState(fAlt*KEYS_Alt + fCtrl*KEYS_Control + fShift*KEYS_Shift), fRepeated);
|
||||
return DoKeyboardInput(Key, eEventType, pForDialog, fPlrCtrlOnly, iStrength);
|
||||
}
|
||||
|
||||
|
||||
bool C4Game::DoKeyboardInput(C4KeyCodeEx Key, C4KeyEventType eEventType, class C4GUI::Dialog *pForDialog, bool fPlrCtrlOnly, int32_t iStrength)
|
||||
{
|
||||
Key.FixShiftKeys();
|
||||
// compose keyboard scope
|
||||
DWORD InScope = 0;
|
||||
|
|
|
@ -146,6 +146,7 @@ public:
|
|||
void Evaluate();
|
||||
void ShowGameOverDlg();
|
||||
bool DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType eEventType, bool fAlt, bool fCtrl, bool fShift, bool fRepeated, class C4GUI::Dialog *pForDialog=NULL, bool fPlrCtrlOnly=false, int32_t iStrength=-1);
|
||||
bool DoKeyboardInput(C4KeyCodeEx Key, C4KeyEventType eEventType, class C4GUI::Dialog *pForDialog=NULL, bool fPlrCtrlOnly=false, int32_t iStrength=-1);
|
||||
void DrawCrewOverheadText(C4TargetFacet &cgo, int32_t iPlayer);
|
||||
void FixRandom(int32_t iSeed);
|
||||
bool Init();
|
||||
|
|
|
@ -193,6 +193,11 @@ const C4KeyCodeMapEntry KeyCodeMap[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
C4KeyCodeEx::C4KeyCodeEx(C4KeyCode key, C4KeyShiftState Shift, bool fIsRepeated, int32_t deviceId)
|
||||
: Key(key), dwShift(Shift), fRepeated(fIsRepeated), deviceId(deviceId)
|
||||
{
|
||||
}
|
||||
|
||||
void C4KeyCodeEx::FixShiftKeys()
|
||||
{
|
||||
// reduce stuff like Ctrl+RightCtrl to simply RightCtrl
|
||||
|
@ -252,10 +257,9 @@ C4KeyCode C4KeyCodeEx::String2KeyCode(const StdStrBuf &sName)
|
|||
std::cmatch matches;
|
||||
if (std::regex_match(sName.getData(), matches, controller_re))
|
||||
{
|
||||
int iGamepad = 0; // TODO: Gamepad code selected later on.
|
||||
auto keycode_it = controllercodes.find(matches[1].str());
|
||||
if (keycode_it != controllercodes.end())
|
||||
return KEY_Gamepad(iGamepad, keycode_it->second);
|
||||
return KEY_Gamepad(keycode_it->second);
|
||||
else
|
||||
return KEY_Undefined;
|
||||
|
||||
|
@ -622,6 +626,15 @@ C4CustomKey::~C4CustomKey()
|
|||
(*i)->Deref();
|
||||
}
|
||||
|
||||
bool C4CustomKey::IsCodeMatched(const C4KeyCodeEx &key) const
|
||||
{
|
||||
const CodeList &codes = GetCodes();
|
||||
for (const auto &code : codes)
|
||||
if (code == key)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void C4CustomKey::Update(const C4CustomKey *pByKey)
|
||||
{
|
||||
assert(pByKey);
|
||||
|
@ -832,9 +845,8 @@ bool C4KeyboardInput::DoInput(const C4KeyCodeEx &InKey, C4KeyEventType InEvent,
|
|||
FallbackKeys[iKeyRangeCnt++] = InKey.Key;
|
||||
if (Key_IsGamepadButton(InKey.Key))
|
||||
{
|
||||
uint8_t byGamepad = Key_GetGamepad(InKey.Key);
|
||||
// "any gamepad button"-event
|
||||
FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_CONTROLLER_AnyButton);
|
||||
FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(KEY_CONTROLLER_AnyButton);
|
||||
}
|
||||
else if (Key_IsGamepadAxis(InKey.Key))
|
||||
{
|
||||
|
|
|
@ -110,10 +110,10 @@ const C4KeyCode
|
|||
inline uint8_t KEY_CONTROLLER_Button(uint8_t idx) { return KEY_CONTROLLER_ButtonMin+idx; }
|
||||
inline uint8_t KEY_CONTROLLER_Axis(uint8_t idx, bool fMax) { return KEY_CONTROLLER_AxisMin+2*idx+fMax; }
|
||||
|
||||
inline C4KeyCode KEY_Gamepad(uint8_t idGamepad, uint8_t idButton) // convert gamepad key to Clonk-gamepad-keycode
|
||||
inline C4KeyCode KEY_Gamepad(uint8_t idButton) // convert gamepad key to Clonk-gamepad-keycode
|
||||
{
|
||||
// mask key as 0x0042ggbb, where gg is gamepad ID and bb is button ID.
|
||||
return KEY_CONTROLLER_Mask + (idGamepad<<8) + idButton;
|
||||
// mask key as 0x004200bb, where 00 used to be the gamepad ID and bb is button ID.
|
||||
return KEY_CONTROLLER_Mask + idButton;
|
||||
}
|
||||
|
||||
inline bool Key_IsGamepad(C4KeyCode key)
|
||||
|
@ -205,6 +205,8 @@ struct C4KeyCodeEx
|
|||
C4KeyCode Key; // the key
|
||||
DWORD dwShift; // the status of Alt, Shift, Control
|
||||
|
||||
int32_t deviceId;
|
||||
|
||||
// if set, the keycode was generated by a key that has been held down
|
||||
// this flag is ignored in comparison operations
|
||||
bool fRepeated;
|
||||
|
@ -229,8 +231,7 @@ struct C4KeyCodeEx
|
|||
|
||||
void CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBuf=NULL);
|
||||
|
||||
C4KeyCodeEx(C4KeyCode Key = KEY_Default, C4KeyShiftState Shift = KEYS_None, bool fIsRepeated = false)
|
||||
: Key(Key), dwShift(Shift), fRepeated(fIsRepeated) {}
|
||||
C4KeyCodeEx(C4KeyCode Key = KEY_Default, C4KeyShiftState Shift = KEYS_None, bool fIsRepeated = false, int32_t deviceId = -1);
|
||||
|
||||
bool IsRepeated() const { return fRepeated; }
|
||||
|
||||
|
@ -253,17 +254,17 @@ struct C4KeyEventData
|
|||
|
||||
// Helper functions for high-level GUI control mappings.
|
||||
namespace ControllerKeys {
|
||||
template<class T> void Any(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_AnyButton))); }
|
||||
template<class T> void Cancel(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_ButtonB))); }
|
||||
template<class T> void Ok(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_ButtonA))); }
|
||||
template<class T> void Left(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_AxisLeftXLeft)));
|
||||
keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_ButtonDpadLeft))); }
|
||||
template<class T> void Right(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_AxisLeftXRight)));
|
||||
keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_ButtonDpadRight))); }
|
||||
template<class T> void Up(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_AxisLeftYUp)));
|
||||
keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_ButtonDpadUp))); }
|
||||
template<class T> void Down(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_AxisLeftYDown)));
|
||||
keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_CONTROLLER_ButtonDpadDown))); }
|
||||
template<class T> void Any(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_AnyButton))); }
|
||||
template<class T> void Cancel(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_ButtonB))); }
|
||||
template<class T> void Ok(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_ButtonA))); }
|
||||
template<class T> void Left(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_AxisLeftXLeft)));
|
||||
keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_ButtonDpadLeft))); }
|
||||
template<class T> void Right(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_AxisLeftXRight)));
|
||||
keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_ButtonDpadRight))); }
|
||||
template<class T> void Up(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_AxisLeftYUp)));
|
||||
keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_ButtonDpadUp))); }
|
||||
template<class T> void Down(T &keys) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_AxisLeftYDown)));
|
||||
keys.push_back(C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_ButtonDpadDown))); }
|
||||
}
|
||||
|
||||
// callback interface
|
||||
|
@ -460,7 +461,7 @@ public:
|
|||
const StdStrBuf &GetName() const { return Name; }
|
||||
C4KeyScope GetScope() const { return Scope; }
|
||||
unsigned int GetPriority() const { return uiPriority; }
|
||||
bool IsCodeMatched(const C4KeyCodeEx &key) const { const CodeList &codes = GetCodes(); return (std::find(codes.begin(),codes.end(),key) != codes.end()); }
|
||||
bool IsCodeMatched(const C4KeyCodeEx &key) const;
|
||||
|
||||
void Update(const C4CustomKey *pByKey); // merge given key into this
|
||||
bool Execute(C4KeyEventType eEv, C4KeyCodeEx key);
|
||||
|
|
|
@ -39,6 +39,8 @@ C4GamePadControl::C4GamePadControl()
|
|||
|
||||
C4GamePadControl::~C4GamePadControl()
|
||||
{
|
||||
// All gamepads have to be released before quitting SDL.
|
||||
Gamepads.clear();
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS);
|
||||
}
|
||||
|
||||
|
@ -71,8 +73,8 @@ void C4GamePadControl::FeedEvent(const SDL_Event& event, int feed)
|
|||
{
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
{
|
||||
C4KeyCode minCode = KEY_Gamepad(event.caxis.which, KEY_CONTROLLER_Axis(event.caxis.axis, false));
|
||||
C4KeyCode maxCode = KEY_Gamepad(event.caxis.which, KEY_CONTROLLER_Axis(event.caxis.axis, true));
|
||||
C4KeyCode minCode = KEY_Gamepad(KEY_CONTROLLER_Axis(event.caxis.axis, false));
|
||||
C4KeyCode maxCode = KEY_Gamepad(KEY_CONTROLLER_Axis(event.caxis.axis, true));
|
||||
int32_t value = std::abs(event.caxis.value);
|
||||
uint8_t which = event.caxis.which;
|
||||
C4KeyCode keyCode = event.caxis.value >= 0 ? maxCode : minCode;
|
||||
|
@ -80,8 +82,8 @@ void C4GamePadControl::FeedEvent(const SDL_Event& event, int feed)
|
|||
auto doInput = [&](C4KeyEventType event, int32_t strength)
|
||||
{
|
||||
Game.DoKeyboardInput(
|
||||
KEY_Gamepad(which, keyCode), event,
|
||||
false, false, false, false, NULL, false, strength);
|
||||
C4KeyCodeEx(KEY_Gamepad(keyCode), KEYS_None, false, which),
|
||||
event, NULL, false, strength);
|
||||
};
|
||||
|
||||
if (feed & FEED_BUTTONS)
|
||||
|
@ -108,14 +110,14 @@ void C4GamePadControl::FeedEvent(const SDL_Event& event, int feed)
|
|||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
if (feed & FEED_BUTTONS)
|
||||
Game.DoKeyboardInput(
|
||||
KEY_Gamepad(event.cbutton.which, KEY_CONTROLLER_Button(event.cbutton.button)),
|
||||
KEYEV_Down, false, false, false, false);
|
||||
C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_Button(event.cbutton.button)), KEYS_None, false, event.cbutton.which),
|
||||
KEYEV_Down);
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
if (feed & FEED_BUTTONS)
|
||||
Game.DoKeyboardInput(
|
||||
KEY_Gamepad(event.cbutton.which, KEY_CONTROLLER_Button(event.cbutton.button)),
|
||||
KEYEV_Up, false, false, false, false);
|
||||
C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_Button(event.cbutton.button)), KEYS_None, false, event.cbutton.which),
|
||||
KEYEV_Up);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue