aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@theqtcompany.com>2015-08-12 16:32:15 +0200
committerAndy Nichols <andy.nichols@theqtcompany.com>2015-08-14 08:57:21 +0000
commit758834d36923faf31bc056f6825a09676c2de262 (patch)
tree6d9d561146cee8a84c47f13657d8763f772141f1
parent3a41635e27b4f3202a9d47797590d37e92ba4c5e (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.pro1
-rw-r--r--src/plugins/gamepads/ios/ios.json3
-rw-r--r--src/plugins/gamepads/ios/ios.pro21
-rw-r--r--src/plugins/gamepads/ios/main.cpp61
-rw-r--r--src/plugins/gamepads/ios/qiosgamepadbackend.mm528
-rw-r--r--src/plugins/gamepads/ios/qiosgamepadbackend_p.h77
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 &paramList) Q_DECL_OVERRIDE;
+};
+
+QGamepadBackend *QIosGamepadBackendPlugin::create(const QString &key, const QStringList &paramList) {
+ 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