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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
#pragma once
#include "../../Input/IInputManager.h"
#include "../../Threading/ThreadSync.h"
#include <Containers/SmallVector.h>
using namespace Death::Containers;
#include <winrt/Windows.Gaming.Input.h>
#include <winrt/Windows.System.h>
#include <winrt/Windows.UI.Core.h>
#include <winrt/Windows.UI.Text.Core.h>
namespace winrtWF = winrt::Windows::Foundation;
namespace winrtWGI = winrt::Windows::Gaming::Input;
namespace winrtWS = winrt::Windows::System;
namespace winrtWUC = winrt::Windows::UI::Core;
namespace winrtWUTC = winrt::Windows::UI::Text::Core;
namespace nCine::Backends
{
/// Information about UWP mouse state
class UwpMouseState : public MouseState
{
public:
bool isButtonDown(MouseButton button) const override
{
// TODO
return false;
}
};
/// Information about UWP keyboard state
class UwpKeyboardState : public KeyboardState
{
friend class UwpInputManager;
public:
UwpKeyboardState() {
std::memset(_pressedKeys, 0, sizeof(_pressedKeys));
}
inline bool isKeyDown(Keys key) const override {
return (key >= (Keys)0 && key < Keys::Count ? _pressedKeys[(int)key] : false);
}
private:
bool _pressedKeys[(int)Keys::Count];
};
/// Information about UWP joystick state
class UwpJoystickState : public JoystickState
{
public:
static constexpr unsigned int MaxNumButtons = 11;
static constexpr unsigned int MaxNumHats = 1;
static constexpr unsigned int MaxNumAxes = 6;
UwpJoystickState();
bool isButtonPressed(int buttonId) const override;
unsigned char hatState(int hatId) const override;
float axisValue(int axisId) const override;
void resetJoystickState(int joyId);
void simulateButtonsEvents(winrtWGI::GamepadButtons buttons);
void simulateHatsEvents(winrtWGI::GamepadButtons buttons);
void simulateAxisEvent(int axisId, float value);
private:
/// Minimum difference between two axis readings in order to trigger an event
static constexpr float AxisEventTolerance = 0.001f;
static JoyButtonEvent joyButtonEvent_;
static JoyHatEvent joyHatEvent_;
static JoyAxisEvent joyAxisEvent_;
int joyId_;
/// Old state used to simulate joystick buttons events
bool buttonsState_[MaxNumButtons];
/// Old state used to simulate joystick hats events
unsigned char hatsState_[MaxNumHats];
/// Old state used to simulate joystick axes events
float axesValuesState_[MaxNumAxes];
};
/// Class for dispatching UWP input events
class UwpInputManager : public IInputManager
{
friend class UwpJoystickState;
public:
UwpInputManager(winrtWUC::CoreWindow window);
~UwpInputManager() override;
/// Updates joystick state structures and simulates events
static void updateJoystickStates();
const MouseState& mouseState() const override { return mouseState_; }
inline const KeyboardState& keyboardState() const override { return keyboardState_; }
bool isJoyPresent(int joyId) const override
{
DEATH_ASSERT(joyId >= 0);
return (joyId < MaxNumJoysticks && _gamepads[joyId].Connected);
}
const char* joyName(int joyId) const override { return "Windows.Gaming.Input"; }
const JoystickGuid joyGuid(int joyId) const override { return JoystickGuidType::Xinput; }
int joyNumButtons(int joyId) const override { return UwpJoystickState::MaxNumButtons; }
int joyNumHats(int joyId) const override { return UwpJoystickState::MaxNumHats; }
int joyNumAxes(int joyId) const override { return UwpJoystickState::MaxNumAxes; }
const JoystickState& joystickState(int joyId) const override
{
if (isJoyPresent(joyId)) {
return _gamepads[joyId].State;
} else {
return nullJoystickState_;
}
}
bool joystickRumble(int joyId, float lowFrequency, float highFrequency, uint32_t durationMs) override;
bool joystickRumbleTriggers(int joyId, float left, float right, uint32_t durationMs) override;
void setCursor(Cursor cursor) override;
private:
static const int MaxNumJoysticks = 8;
#ifndef DOXYGEN_GENERATING_OUTPUT
// Doxygen 1.12.0 outputs also private structs/unions even if it shouldn't
struct UwpGamepadInfo
{
UwpGamepadInfo() : Gamepad(nullptr), Connected(false),
RumbleLowFrequency(0.0f), RumbleHighFrequency(0.0f), RumbleLeftTrigger(0.0f), RumbleRightTrigger(0.0f),
RumbleExpiration(0), RumbleTriggersExpiration(0) { }
winrtWGI::Gamepad Gamepad;
UwpJoystickState State;
bool Connected;
float RumbleLowFrequency;
float RumbleHighFrequency;
float RumbleLeftTrigger;
float RumbleRightTrigger;
std::uint64_t RumbleExpiration;
std::uint64_t RumbleTriggersExpiration;
};
#endif
static UwpMouseState mouseState_;
static UwpKeyboardState keyboardState_;
static KeyboardEvent keyboardEvent_;
static TextInputEvent textInputEvent_;
static UwpJoystickState nullJoystickState_;
static JoyConnectionEvent joyConnectionEvent_;
//static winrtWUTC::CoreTextEditContext _editContext;
static UwpGamepadInfo _gamepads[MaxNumJoysticks];
static ReadWriteLock _gamepadsSync;
static Keys keySymValueToEnum(winrtWS::VirtualKey virtualKey);
void OnKey(const winrtWUC::CoreWindow& sender, const winrtWUC::KeyEventArgs& args);
void OnCharacterReceived(const winrtWUC::CoreWindow& sender, const winrtWUC::CharacterReceivedEventArgs& args);
void OnAcceleratorKeyActivated(const winrtWUC::CoreDispatcher& sender, const winrtWUC::AcceleratorKeyEventArgs& args);
void OnGamepadAdded(const winrtWF::IInspectable& sender, const winrtWGI::Gamepad& gamepad);
void OnGamepadRemoved(const winrtWF::IInspectable& sender, const winrtWGI::Gamepad& gamepad);
};
}
|