File: UwpInputManager.h

package info (click to toggle)
jazz2-native 3.5.0-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky
  • size: 16,912 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (171 lines) | stat: -rw-r--r-- 5,566 bytes parent folder | download | duplicates (2)
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);
	};
}