src/platform/qt/InputController.cpp (view raw)
1/* Copyright (c) 2013-2014 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "InputController.h"
7
8#include "ConfigController.h"
9
10extern "C" {
11#include "util/configuration.h"
12}
13
14using namespace QGBA;
15
16InputController::InputController() {
17 GBAInputMapInit(&m_inputMap);
18
19#ifdef BUILD_SDL
20 m_sdlEvents.bindings = &m_inputMap;
21 GBASDLInitEvents(&m_sdlEvents);
22 GBASDLInitBindings(&m_inputMap);
23 SDL_JoystickEventState(SDL_QUERY);
24#endif
25
26 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A);
27 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Z, GBA_KEY_B);
28 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_A, GBA_KEY_L);
29 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_S, GBA_KEY_R);
30 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Return, GBA_KEY_START);
31 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Backspace, GBA_KEY_SELECT);
32 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Up, GBA_KEY_UP);
33 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Down, GBA_KEY_DOWN);
34 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Left, GBA_KEY_LEFT);
35 GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Right, GBA_KEY_RIGHT);
36}
37
38InputController::~InputController() {
39 GBAInputMapDeinit(&m_inputMap);
40
41#ifdef BUILD_SDL
42 GBASDLDeinitEvents(&m_sdlEvents);
43#endif
44}
45
46void InputController::setConfiguration(ConfigController* config) {
47 m_config = config;
48 loadConfiguration(KEYBOARD);
49#ifdef BUILD_SDL
50 loadConfiguration(SDL_BINDING_BUTTON);
51#endif
52}
53
54void InputController::loadConfiguration(uint32_t type) {
55 GBAInputMapLoad(&m_inputMap, type, m_config->configuration());
56}
57
58void InputController::saveConfiguration(uint32_t type) {
59 GBAInputMapSave(&m_inputMap, type, m_config->configuration());
60 m_config->write();
61}
62
63GBAKey InputController::mapKeyboard(int key) const {
64 return GBAInputMapKey(&m_inputMap, KEYBOARD, key);
65}
66
67void InputController::bindKey(uint32_t type, int key, GBAKey gbaKey) {
68 return GBAInputBindKey(&m_inputMap, type, key, gbaKey);
69}
70
71#ifdef BUILD_SDL
72int InputController::testSDLEvents() {
73 SDL_Joystick* joystick = m_sdlEvents.joystick;
74 SDL_JoystickUpdate();
75 int numButtons = SDL_JoystickNumButtons(joystick);
76 int activeButtons = 0;
77 int i;
78 for (i = 0; i < numButtons; ++i) {
79 GBAKey key = GBAInputMapKey(&m_inputMap, SDL_BINDING_BUTTON, i);
80 if (key == GBA_KEY_NONE) {
81 continue;
82 }
83 if (SDL_JoystickGetButton(joystick, i)) {
84 activeButtons |= 1 << key;
85 }
86 }
87 int numHats = SDL_JoystickNumHats(joystick);
88 for (i = 0; i < numHats; ++i) {
89 int hat = SDL_JoystickGetHat(joystick, i);
90 if (hat & SDL_HAT_UP) {
91 activeButtons |= 1 << GBA_KEY_UP;
92 }
93 if (hat & SDL_HAT_LEFT) {
94 activeButtons |= 1 << GBA_KEY_LEFT;
95 }
96 if (hat & SDL_HAT_DOWN) {
97 activeButtons |= 1 << GBA_KEY_DOWN;
98 }
99 if (hat & SDL_HAT_RIGHT) {
100 activeButtons |= 1 << GBA_KEY_RIGHT;
101 }
102 }
103
104 int numAxes = SDL_JoystickNumAxes(joystick);
105 for (i = 0; i < numAxes; ++i) {
106 int value = SDL_JoystickGetAxis(joystick, i);
107
108 enum GBAKey key = GBAInputMapAxis(&m_inputMap, SDL_BINDING_BUTTON, i, value);
109 if (key != GBA_KEY_NONE) {
110 activeButtons |= 1 << key;
111 }
112 }
113 return activeButtons;
114}
115
116QSet<int> InputController::activeGamepadButtons() {
117 SDL_Joystick* joystick = m_sdlEvents.joystick;
118 SDL_JoystickUpdate();
119 int numButtons = SDL_JoystickNumButtons(joystick);
120 QSet<int> activeButtons;
121 int i;
122 for (i = 0; i < numButtons; ++i) {
123 if (SDL_JoystickGetButton(joystick, i)) {
124 activeButtons.insert(i);
125 }
126 }
127 return activeButtons;
128}
129
130QSet<QPair<int, int32_t>> InputController::activeGamepadAxes() {
131 SDL_Joystick* joystick = m_sdlEvents.joystick;
132 SDL_JoystickUpdate();
133 int numButtons = SDL_JoystickNumAxes(joystick);
134 QSet<QPair<int, int32_t>> activeAxes;
135 int i;
136 for (i = 0; i < numButtons; ++i) {
137 int32_t axis = SDL_JoystickGetAxis(joystick, i);
138 if (axis >= AXIS_THRESHOLD || axis <= -AXIS_THRESHOLD) {
139 activeAxes.insert(qMakePair(i, axis > 0 ? 1 : -1));
140 }
141 }
142 return activeAxes;
143}
144
145void InputController::bindAxis(uint32_t type, int axis, Direction direction, GBAKey key) {
146 const GBAAxis* old = GBAInputQueryAxis(&m_inputMap, SDL_BINDING_BUTTON, axis);
147 GBAAxis description = { GBA_KEY_NONE, GBA_KEY_NONE, -AXIS_THRESHOLD, AXIS_THRESHOLD };
148 if (old) {
149 description = *old;
150 }
151 switch (direction) {
152 case NEGATIVE:
153 description.lowDirection = key;
154 description.deadLow = -AXIS_THRESHOLD;
155 break;
156 case POSITIVE:
157 description.highDirection = key;
158 description.deadHigh = AXIS_THRESHOLD;
159 break;
160 default:
161 return;
162 }
163 GBAInputBindAxis(&m_inputMap, SDL_BINDING_BUTTON, axis, &description);
164}
165#endif