diff options
author | Andy Nichols <andy.nichols@theqtcompany.com> | 2015-08-12 16:32:15 +0200 |
---|---|---|
committer | Andy Nichols <andy.nichols@theqtcompany.com> | 2015-08-14 08:57:21 +0000 |
commit | 758834d36923faf31bc056f6825a09676c2de262 (patch) | |
tree | 6d9d561146cee8a84c47f13657d8763f772141f1 | |
parent | 3a41635e27b4f3202a9d47797590d37e92ba4c5e (diff) |
iOS Gamepad support
Initial support for using the iOS GameController API to provide a
gamepad backend on iOS. Not all buttons are supported, and for some
reason the Pause button is inteded to behave as a toggle button.
Change-Id: Ibe6a3011a85ecf29731f9ac890efdac36b43e446
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
-rw-r--r-- | src/plugins/gamepads/gamepads.pro | 1 | ||||
-rw-r--r-- | src/plugins/gamepads/ios/ios.json | 3 | ||||
-rw-r--r-- | src/plugins/gamepads/ios/ios.pro | 21 | ||||
-rw-r--r-- | src/plugins/gamepads/ios/main.cpp | 61 | ||||
-rw-r--r-- | src/plugins/gamepads/ios/qiosgamepadbackend.mm | 528 | ||||
-rw-r--r-- | src/plugins/gamepads/ios/qiosgamepadbackend_p.h | 77 |
6 files changed, 691 insertions, 0 deletions
diff --git a/src/plugins/gamepads/gamepads.pro b/src/plugins/gamepads/gamepads.pro index 928b288..30347bb 100644 --- a/src/plugins/gamepads/gamepads.pro +++ b/src/plugins/gamepads/gamepads.pro @@ -2,3 +2,4 @@ TEMPLATE = subdirs config_sdl:SUBDIRS += sdl2 contains(QT_CONFIG, evdev): SUBDIRS += evdev win32: !wince*: SUBDIRS += xinput +ios: SUBDIRS += ios diff --git a/src/plugins/gamepads/ios/ios.json b/src/plugins/gamepads/ios/ios.json new file mode 100644 index 0000000..f0b766d --- /dev/null +++ b/src/plugins/gamepads/ios/ios.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "ios" ] +} diff --git a/src/plugins/gamepads/ios/ios.pro b/src/plugins/gamepads/ios/ios.pro new file mode 100644 index 0000000..2fa1f2f --- /dev/null +++ b/src/plugins/gamepads/ios/ios.pro @@ -0,0 +1,21 @@ +TARGET = iosgamepad +QT += gamepad gamepad-private + +PLUGIN_TYPE = gamepads +PLUGIN_EXTENDS = gamepad +PLUGIN_CLASS_NAME = QIosGamepadBackendPlugin +load(qt_plugin) + +LIBS += -framework GameController -framework Foundation + +HEADERS += qiosgamepadbackend_p.h +OBJECTIVE_SOURCES += \ + qiosgamepadbackend.mm + +SOURCES += \ + main.cpp + +OTHER_FILES += \ + ios.json + + diff --git a/src/plugins/gamepads/ios/main.cpp b/src/plugins/gamepads/ios/main.cpp new file mode 100644 index 0000000..d6ab9c7 --- /dev/null +++ b/src/plugins/gamepads/ios/main.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGamepad/private/qgamepadbackendfactory_p.h> +#include <QtGamepad/private/qgamepadbackendplugin_p.h> + +#include "qiosgamepadbackend_p.h" + +QT_BEGIN_NAMESPACE + +class QIosGamepadBackendPlugin : public QGamepadBackendPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QtGamepadBackendFactoryInterface_iid FILE "ios.json") +public: + QGamepadBackend *create(const QString &key, const QStringList ¶mList) Q_DECL_OVERRIDE; +}; + +QGamepadBackend *QIosGamepadBackendPlugin::create(const QString &key, const QStringList ¶mList) { + Q_UNUSED(key) + Q_UNUSED(paramList) + + return new QIosGamepadBackend(); +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/gamepads/ios/qiosgamepadbackend.mm b/src/plugins/gamepads/ios/qiosgamepadbackend.mm new file mode 100644 index 0000000..361c70a --- /dev/null +++ b/src/plugins/gamepads/ios/qiosgamepadbackend.mm @@ -0,0 +1,528 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qiosgamepadbackend_p.h" + +#include <QtCore/QDebug> + +#import <GameController/GameController.h> + +@interface QT_MANGLE_NAMESPACE(IosGamepadManager) : NSObject +{ + QIosGamepadBackend *backend; + NSMutableArray *connectedControllers; +} + +@property (nonatomic, strong) id connectObserver; +@property (nonatomic, strong) id disconnectObserver; + +-(void)addMonitoredController:(GCController *)controller; +-(void)removeMonitoredController:(GCController *)controller; + +@end + +@implementation QT_MANGLE_NAMESPACE(IosGamepadManager) + +-(id)initWithBackend:(QIosGamepadBackend *)iosGamepadBackend { + if (self = [super init]) { + backend = iosGamepadBackend; + connectedControllers = [[NSMutableArray alloc] init]; + //Setup observers for monitoring controller connections/disconnections + self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification + object:nil + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification *note) { + GCController *controller = (GCController*)note.object; + [self addMonitoredController:controller]; + + }]; + self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification + object:nil + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification *note) { + GCController *controller = (GCController*)note.object; + [self removeMonitoredController:controller]; + }]; + //Set initial controller values + for (int i = 0; i < 4; ++i) + [connectedControllers addObject:[NSNull null]]; + + //Add monitoring for any alrready connected controllers + for (int i = 0; i < [[GCController controllers] count]; ++i) { + addMonitoredController:[GCController controllers][i]; + } + } + return self; +} + +-(void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self.connectObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:self.disconnectObserver]; + [connectedControllers release]; + [super dealloc]; +} + +-(void)addMonitoredController:(GCController *)controller +{ + int index = -1; + for (int i = 0; i < 4; ++i) { + if (connectedControllers[i] == [NSNull null]) { + [connectedControllers replaceObjectAtIndex: i withObject: controller]; + index = i; + break; + } + } + controller.playerIndex = index; + + QMetaObject::invokeMethod(backend, "iosGamepadAdded", Qt::AutoConnection, Q_ARG(int, index)); + + //Pause button handler + [controller setControllerPausedHandler:^(GCController *controller) { + Q_UNUSED(controller) + QMetaObject::invokeMethod(backend, "handlePauseButton", Qt::AutoConnection, Q_ARG(int, index)); + }]; + + if (controller.extendedGamepad) { + //leftShoulder + [controller.extendedGamepad.leftShoulder setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonL1), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonL1)); + } + }]; + //rightShoulder + [controller.extendedGamepad.rightShoulder setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonR1), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonR1)); + } + }]; + //dpad + [controller.extendedGamepad.dpad setValueChangedHandler:^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + Q_UNUSED(dpad) + if (xValue > 0) { + //right + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonRight), + Q_ARG(double, 1)); + } else if (xValue < 0) { + //left + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonLeft), + Q_ARG(double, 1)); + } else { + //released + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonRight)); + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonLeft)); + } + if (yValue > 0) { + //up + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonUp), + Q_ARG(double, 1)); + } else if (yValue < 0) { + //down + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonDown), + Q_ARG(double, 1)); + } else { + //released + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonUp)); + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonDown)); + } + }]; + //buttonA + [controller.extendedGamepad.buttonA setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonA), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonA)); + } + }]; + //buttonB + [controller.extendedGamepad.buttonB setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonB), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonB)); + } + }]; + //buttonX + [controller.extendedGamepad.buttonX setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonX), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonX)); + } + }]; + //buttonY + [controller.extendedGamepad.buttonY setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + //Invoke slot + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonY), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonY)); + } + }]; + + //leftThumbstick + [controller.extendedGamepad.leftThumbstick setValueChangedHandler:^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + Q_UNUSED(dpad) + QMetaObject::invokeMethod(backend, "iosGamepadAxisMoved", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadAxis, QGamepadManager::AxisLeftX), + Q_ARG(double, xValue)); + QMetaObject::invokeMethod(backend, "iosGamepadAxisMoved", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadAxis, QGamepadManager::AxisLeftY), + Q_ARG(double, -yValue)); + }]; + //rightTumbstick + [controller.extendedGamepad.rightThumbstick setValueChangedHandler:^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + Q_UNUSED(dpad) + QMetaObject::invokeMethod(backend, "iosGamepadAxisMoved", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadAxis, QGamepadManager::AxisRightX), + Q_ARG(double, xValue)); + QMetaObject::invokeMethod(backend, "iosGamepadAxisMoved", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadAxis, QGamepadManager::AxisRightY), + Q_ARG(double, -yValue)); + }]; + //leftTrigger + [controller.extendedGamepad.leftTrigger setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonL2), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonL2)); + } + }]; + //rightTrigger + [controller.extendedGamepad.rightTrigger setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonR2), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonR2)); + } + + }]; + } else if (controller.gamepad) { + //leftShoulder + [controller.gamepad.leftShoulder setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonL1), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonL1)); + } + }]; + //rightShoulder + [controller.gamepad.rightShoulder setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonR1), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonR1)); + } + }]; + //dpad + [controller.gamepad.dpad setValueChangedHandler:^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + Q_UNUSED(dpad) + if (xValue > 0) { + //right + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonRight), + Q_ARG(double, 1)); + } else if (xValue < 0) { + //left + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonLeft), + Q_ARG(double, 1)); + } else { + //released + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonRight)); + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonLeft)); + } + if (yValue > 0) { + //up + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonUp), + Q_ARG(double, 1)); + } else if (yValue < 0) { + //down + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonDown), + Q_ARG(double, 1)); + } else { + //released + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonUp)); + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonDown)); + } + }]; + //buttonA + [controller.gamepad.buttonA setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonA), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonA)); + } + }]; + //buttonB + [controller.gamepad.buttonB setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonB), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonB)); + } + }]; + //buttonX + [controller.gamepad.buttonX setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonX), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonX)); + } + }]; + //buttonY + [controller.gamepad.buttonY setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) { + Q_UNUSED(button) + if (pressed) { + QMetaObject::invokeMethod(backend, "iosGamepadButtonPressed", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonY), + Q_ARG(double, value)); + } else { + QMetaObject::invokeMethod(backend, "iosGamepadButtonReleased", Qt::AutoConnection, + Q_ARG(int, index), + Q_ARG(QGamepadManager::GamepadButton, QGamepadManager::ButtonY)); + } + }]; + + } +} + +-(void)removeMonitoredController:(GCController *)controller +{ + int index = -1; + for (int i = 0; i < 4; ++i) { + if (connectedControllers[i] == controller) { + [connectedControllers replaceObjectAtIndex: i withObject: [NSNull null]]; + index = i; + break; + } + } + + QMetaObject::invokeMethod(backend, "iosGamepadRemoved", Qt::AutoConnection, Q_ARG(int, index)); +} + +@end + +QT_BEGIN_NAMESPACE + +QIosGamepadBackend::QIosGamepadBackend(QObject *parent) + : QGamepadBackend(parent) + , m_iosGamepadManager(Q_NULLPTR) + , m_isMonitoringActive(false) +{ + m_iosGamepadManager = [[IosGamepadManager alloc] initWithBackend:this]; +} + +QIosGamepadBackend::~QIosGamepadBackend() +{ + [m_iosGamepadManager release]; +} + +bool QIosGamepadBackend::start() +{ + m_isMonitoringActive = true; + return true; +} + +void QIosGamepadBackend::stop() +{ + m_isMonitoringActive = false; +} + +void QIosGamepadBackend::iosGamepadAdded(int index) +{ + if (m_isMonitoringActive) { + emit gamepadAdded(index); + m_pauseButtonMap.insert(index, false); + } +} + +void QIosGamepadBackend::iosGamepadRemoved(int index) +{ + if (m_isMonitoringActive) { + emit gamepadRemoved(index); + m_pauseButtonMap.remove(index); + } +} + +void QIosGamepadBackend::iosGamepadAxisMoved(int index, QGamepadManager::GamepadAxis axis, double value) +{ + if (m_isMonitoringActive) + emit gamepadAxisMoved(index, axis, value); +} + +void QIosGamepadBackend::iosGamepadButtonPressed(int index, QGamepadManager::GamepadButton button, double value) +{ + if (m_isMonitoringActive) + emit gamepadButtonPressed(index, button, value); +} + +void QIosGamepadBackend::iosGamepadButtonReleased(int index, QGamepadManager::GamepadButton button) +{ + if (m_isMonitoringActive) + emit gamepadButtonReleased(index, button); +} + +void QIosGamepadBackend::handlePauseButton(int index) +{ + //If already pressed + if (m_pauseButtonMap.value(index)) { + emit gamepadButtonReleased(index, QGamepadManager::ButtonStart); + m_pauseButtonMap[index] = false; + } else { + //If not currently pressed + emit gamepadButtonPressed(index, QGamepadManager::ButtonStart, 1.0); + m_pauseButtonMap[index] = true; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/gamepads/ios/qiosgamepadbackend_p.h b/src/plugins/gamepads/ios/qiosgamepadbackend_p.h new file mode 100644 index 0000000..a5486cc --- /dev/null +++ b/src/plugins/gamepads/ios/qiosgamepadbackend_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSGAMEPADCONTROLLER_H +#define QIOSGAMEPADCONTROLLER_H + +#include <QtCore/QTimer> +#include <QtCore/QMap> + +#include <QtGamepad/QGamepadManager> +#include <QtGamepad/private/qgamepadbackend_p.h> + +Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(IosGamepadManager)); + +QT_BEGIN_NAMESPACE + +class QIosGamepadBackend : public QGamepadBackend +{ + Q_OBJECT +public: + explicit QIosGamepadBackend(QObject *parent = 0); + ~QIosGamepadBackend(); + +protected: + bool start(); + void stop(); + +public slots: + void iosGamepadAdded(int index); + void iosGamepadRemoved(int index); + void iosGamepadAxisMoved(int index, QGamepadManager::GamepadAxis axis, double value); + void iosGamepadButtonPressed(int index, QGamepadManager::GamepadButton button, double value); + void iosGamepadButtonReleased(int index, QGamepadManager::GamepadButton button); + void handlePauseButton(int index); + +private: + QT_MANGLE_NAMESPACE(IosGamepadManager) *m_iosGamepadManager; + bool m_isMonitoringActive; + QMap<int, bool> m_pauseButtonMap; +}; + +QT_END_NAMESPACE + +#endif // QIOSGAMEPADCONTROLLER_H |