mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-13 19:49:36 +00:00
XInput support
This commit is contained in:
@@ -13,13 +13,18 @@ namespace PortabilityLayer
|
||||
InputManagerImpl();
|
||||
|
||||
void GetKeys(KeyMap &keyMap) const override;
|
||||
void ApplyEvent(const GpKeyboardInputEvent &vosEvent) override;
|
||||
void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) override;
|
||||
void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) override;
|
||||
int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) override;
|
||||
|
||||
static InputManagerImpl *GetInstance();
|
||||
|
||||
private:
|
||||
void ApplyEventAsKey(const GpKeyboardInputEvent &vosEvent, bool bit);
|
||||
void ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent);
|
||||
|
||||
KeyMap m_keyMap;
|
||||
int16_t m_axisStates[PL_INPUT_MAX_PLAYERS][GpGamepadAxes::kCount];
|
||||
|
||||
static InputManagerImpl ms_instance;
|
||||
};
|
||||
@@ -29,7 +34,7 @@ namespace PortabilityLayer
|
||||
keyMap = m_keyMap;
|
||||
}
|
||||
|
||||
void InputManagerImpl::ApplyEvent(const GpKeyboardInputEvent &vosEvent)
|
||||
void InputManagerImpl::ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent)
|
||||
{
|
||||
if (vosEvent.m_eventType == GpKeyboardInputEventTypes::kDown)
|
||||
ApplyEventAsKey(vosEvent, true);
|
||||
@@ -37,6 +42,19 @@ namespace PortabilityLayer
|
||||
ApplyEventAsKey(vosEvent, false);
|
||||
}
|
||||
|
||||
void InputManagerImpl::ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent)
|
||||
{
|
||||
if (vosEvent.m_eventType == GpGamepadInputEventTypes::kAnalogAxisChanged)
|
||||
ApplyAnalogAxisEvent(vosEvent.m_event.m_analogAxisEvent);
|
||||
}
|
||||
|
||||
int16_t InputManagerImpl::GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis)
|
||||
{
|
||||
assert(playerNum < PL_INPUT_MAX_PLAYERS);
|
||||
|
||||
return m_axisStates[playerNum][gamepadAxis];
|
||||
}
|
||||
|
||||
void InputManagerImpl::ApplyEventAsKey(const GpKeyboardInputEvent &vosEvent, bool bit)
|
||||
{
|
||||
switch (vosEvent.m_keyIDSubset)
|
||||
@@ -70,12 +88,22 @@ namespace PortabilityLayer
|
||||
case GpKeyIDSubsets::kFKey:
|
||||
m_keyMap.m_fKey.Set(vosEvent.m_key.m_fKey - 1, bit);
|
||||
break;
|
||||
case GpKeyIDSubsets::kGamepadButton:
|
||||
if (vosEvent.m_key.m_gamepadKey.m_player < PL_INPUT_MAX_PLAYERS)
|
||||
m_keyMap.m_gamepadButtons[vosEvent.m_key.m_gamepadKey.m_player].Set(vosEvent.m_key.m_gamepadKey.m_button, bit);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InputManagerImpl::ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent)
|
||||
{
|
||||
if (axisEvent.m_player < PL_INPUT_MAX_PLAYERS)
|
||||
m_axisStates[axisEvent.m_player][axisEvent.m_axis] = axisEvent.m_state;
|
||||
}
|
||||
|
||||
InputManagerImpl *InputManagerImpl::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
@@ -83,6 +111,7 @@ namespace PortabilityLayer
|
||||
|
||||
InputManagerImpl::InputManagerImpl()
|
||||
{
|
||||
memset(m_axisStates, 0, sizeof(m_axisStates));
|
||||
}
|
||||
|
||||
InputManagerImpl InputManagerImpl::ms_instance;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "GpVOSEvent.h"
|
||||
|
||||
struct GpKeyboardInputEvent;
|
||||
struct GpGamepadInputEvent;
|
||||
struct KeyMap;
|
||||
|
||||
namespace PortabilityLayer
|
||||
@@ -9,7 +12,9 @@ namespace PortabilityLayer
|
||||
{
|
||||
public:
|
||||
virtual void GetKeys(KeyMap &keys16) const = 0;
|
||||
virtual void ApplyEvent(const GpKeyboardInputEvent &vosEvent) = 0;
|
||||
virtual void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) = 0;
|
||||
virtual void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) = 0;
|
||||
virtual int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) = 0;
|
||||
|
||||
static InputManager *GetInstance();
|
||||
};
|
||||
|
||||
@@ -98,12 +98,24 @@ static void TranslateMouseInputEvent(const GpMouseInputEvent &vosEvent, Portabil
|
||||
}
|
||||
}
|
||||
|
||||
static void TranslateKeyboardInputEvent(const GpKeyboardInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)
|
||||
static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)
|
||||
{
|
||||
PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance();
|
||||
|
||||
inputManager->ApplyGamepadEvent(vosEvent);
|
||||
|
||||
PL_DEAD(queue);
|
||||
}
|
||||
|
||||
static void TranslateKeyboardInputEvent(const GpKeyboardInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)
|
||||
{
|
||||
PL_STATIC_ASSERT((1 << PL_INPUT_PLAYER_INDEX_BITS) >= PL_INPUT_MAX_PLAYERS);
|
||||
PL_STATIC_ASSERT((1 << PL_INPUT_TYPE_CODE_BITS) >= KeyEventType_Count);
|
||||
|
||||
PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance();
|
||||
|
||||
if (vosEvent.m_eventType == GpKeyboardInputEventTypes::kUp || vosEvent.m_eventType == GpKeyboardInputEventTypes::kDown)
|
||||
inputManager->ApplyEvent(vosEvent);
|
||||
inputManager->ApplyKeyboardEvent(vosEvent);
|
||||
|
||||
intptr_t msg = 0;
|
||||
|
||||
@@ -134,6 +146,9 @@ static void TranslateKeyboardInputEvent(const GpKeyboardInputEvent &vosEvent, Po
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GpKeyIDSubsets::kGamepadButton:
|
||||
msg = PL_KEY_GAMEPAD_BUTTON_ENCODE(vosEvent.m_key.m_gamepadKey.m_button, vosEvent.m_key.m_gamepadKey.m_player);
|
||||
break;
|
||||
default:
|
||||
PL_NotYetImplemented();
|
||||
}
|
||||
@@ -171,6 +186,9 @@ static void TranslateVOSEvent(const GpVOSEvent *vosEvent, PortabilityLayer::Even
|
||||
case GpVOSEventTypes::kKeyboardInput:
|
||||
TranslateKeyboardInputEvent(vosEvent->m_event.m_keyboardInputEvent, queue);
|
||||
break;
|
||||
case GpVOSEventTypes::kGamepadInput:
|
||||
TranslateGamepadInputEvent(vosEvent->m_event.m_gamepadInputEvent, queue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,6 +539,15 @@ bool BitTst(const KeyMap &keyMap, int encodedKey)
|
||||
return keyMap.m_fKey.Get(evtValue - 1);
|
||||
case KeyEventType_EitherSpecial:
|
||||
return BitTestEitherSpecial(keyMap, evtValue);
|
||||
case KeyEventType_GamepadButton:
|
||||
{
|
||||
unsigned int playerNum = evtValue & ((1 << PL_INPUT_PLAYER_INDEX_BITS) - 1);
|
||||
assert(playerNum < PL_INPUT_MAX_PLAYERS);
|
||||
unsigned int button = evtValue >> PL_INPUT_PLAYER_INDEX_BITS;
|
||||
|
||||
return keyMap.m_gamepadButtons[playerNum].Get(button);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
return false;
|
||||
|
||||
@@ -11,8 +11,10 @@ enum KeyEventType
|
||||
KeyEventType_NumPadNumber,
|
||||
KeyEventType_NumPadSpecial,
|
||||
KeyEventType_FKey,
|
||||
|
||||
KeyEventType_EitherSpecial,
|
||||
KeyEventType_GamepadButton,
|
||||
|
||||
KeyEventType_Count,
|
||||
};
|
||||
|
||||
namespace KeyEventEitherSpecialCategories
|
||||
@@ -25,18 +27,25 @@ namespace KeyEventEitherSpecialCategories
|
||||
};
|
||||
}
|
||||
|
||||
#define PL_KEY_SPECIAL(k) ((KeyEventType_Special) | (GpKeySpecials::k) << 3)
|
||||
#define PL_KEY_SPECIAL_ENCODE(k) ((KeyEventType_Special) | (k) << 3)
|
||||
#define PL_KEY_ASCII(k) ((KeyEventType_ASCII) | (k) << 3)
|
||||
#define PL_KEY_MACROMAN(k) ((KeyEventType_MacRoman) | (k) << 3)
|
||||
#define PL_KEY_NUMPAD_NUMBER(k) ((KeyEventType_NumPadNumber) | (k) << 3)
|
||||
#define PL_KEY_NUMPAD_SPECIAL(k) ((KeyEventType_NumPadSpecial) | (GpKeySpecials::k) << 3)
|
||||
#define PL_KEY_NUMPAD_SPECIAL_ENCODE(k) ((KeyEventType_NumPadSpecial) | (k) << 3)
|
||||
#define PL_KEY_FKEY(k) ((KeyEventType_FKey) | (k) << 3)
|
||||
#define PL_KEY_EITHER_SPECIAL(k) ((KeyEventType_EitherSpecial) | (KeyEventEitherSpecialCategories::k) << 3)
|
||||
#define PL_INPUT_MAX_PLAYERS 2
|
||||
#define PL_INPUT_PLAYER_INDEX_BITS 1
|
||||
|
||||
#define PL_KEY_GET_EVENT_TYPE(k) (static_cast<KeyEventType>(k & 7))
|
||||
#define PL_KEY_GET_VALUE(k) ((k) >> 3)
|
||||
#define PL_INPUT_TYPE_CODE_BITS 3
|
||||
|
||||
#define PL_KEY_SPECIAL(k) ((KeyEventType_Special) | ((GpKeySpecials::k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_SPECIAL_ENCODE(k) ((KeyEventType_Special) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_ASCII(k) ((KeyEventType_ASCII) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_MACROMAN(k) ((KeyEventType_MacRoman) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_NUMPAD_NUMBER(k) ((KeyEventType_NumPadNumber) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_NUMPAD_SPECIAL(k) ((KeyEventType_NumPadSpecial) | ((GpKeySpecials::k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_NUMPAD_SPECIAL_ENCODE(k) ((KeyEventType_NumPadSpecial) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_FKEY(k) ((KeyEventType_FKey) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_EITHER_SPECIAL(k) ((KeyEventType_EitherSpecial) | ((KeyEventEitherSpecialCategories::k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_GAMEPAD_BUTTON(k, pl) ((KeyEventType_GamepadButton) | (pl << PL_INPUT_TYPE_CODE_BITS) | ((GpGamepadButtons::k) << (PL_INPUT_TYPE_CODE_BITS + PL_INPUT_PLAYER_INDEX_BITS)))
|
||||
#define PL_KEY_GAMEPAD_BUTTON_ENCODE(k, pl) ((KeyEventType_GamepadButton) | (pl << PL_INPUT_TYPE_CODE_BITS) | ((k) << (PL_INPUT_TYPE_CODE_BITS + PL_INPUT_PLAYER_INDEX_BITS)))
|
||||
|
||||
#define PL_KEY_GET_EVENT_TYPE(k) (static_cast<KeyEventType>(k & ((1 << PL_INPUT_TYPE_CODE_BITS) - 1)))
|
||||
#define PL_KEY_GET_VALUE(k) ((k) >> PL_INPUT_TYPE_CODE_BITS)
|
||||
|
||||
struct KeyMap
|
||||
{
|
||||
@@ -45,5 +54,6 @@ struct KeyMap
|
||||
GpBitfield<128> m_macRoman;
|
||||
GpBitfield<10> m_numPadNumber;
|
||||
GpBitfield<GpNumPadSpecials::kCount> m_numPadSpecial;
|
||||
GpBitfield<GpFKeyMaximumInclusive> m_fKey;
|
||||
GpBitfield<GpFKeyMaximumInclusive> m_fKey;
|
||||
GpBitfield<GpGamepadButtons::kCount> m_gamepadButtons[PL_INPUT_MAX_PLAYERS];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user