all repos — mgba @ d15c4f4bfb2ee7fcb920a391812b72e746353208

mGBA Game Boy Advance Emulator

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