diff --git a/examples/xbox.js b/examples/xbox.js index 03378995bf..9190ee23ac 100644 --- a/examples/xbox.js +++ b/examples/xbox.js @@ -10,15 +10,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -gamepad = Controller.joystick(); -print("THE GAMEPAD NAME is " + gamepad.name); -print("THE GAMEPAD HAS " + gamepad.numAxes + " AXES") +joysticks = Joysticks.availableJoystickNames; -function printValues() { - controllerAxes = gamepad.axes; - for (i = 0; i < controllerAxes.size; i++) { - // print("The value for axis " + i + " is " + controllerAxes[i]); - } -} - -Script.update.connect(printValues); \ No newline at end of file +for (i = 0; i < joysticks.length; i++) { + print("Joystick " + i + " is " + joysticks[i]); +} \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 105fb6a973..c49a1e234a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -82,6 +82,7 @@ #include "scripting/AccountScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h" +#include "scripting/JoystickScriptingInterface.h" #include "scripting/GlobalServicesScriptingInterface.h" #include "scripting/LocationScriptingInterface.h" #include "scripting/MenuScriptingInterface.h" @@ -2155,7 +2156,7 @@ void Application::update(float deltaTime) { updateFaceshift(); updateVisage(); _sixenseManager.update(deltaTime); - _joystickManager.update(); + JoystickScriptingInterface::getInstance().update(); _prioVR.update(deltaTime); } @@ -3847,6 +3848,8 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser scriptEngine->registerGlobalObject("GlobalServices", GlobalServicesScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("AvatarManager", &_avatarManager); + + scriptEngine->registerGlobalObject("Joysticks", &JoystickScriptingInterface::getInstance()); #ifdef HAVE_RTMIDI scriptEngine->registerGlobalObject("MIDI", &MIDIManager::getInstance()); diff --git a/interface/src/Application.h b/interface/src/Application.h index d17bacd413..7c644b61ea 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -59,7 +59,6 @@ #include "avatar/MyAvatar.h" #include "devices/Faceplus.h" #include "devices/Faceshift.h" -#include "devices/JoystickManager.h" #include "devices/PrioVR.h" #include "devices/SixenseManager.h" #include "devices/Visage.h" @@ -221,7 +220,6 @@ public: FaceTracker* getActiveFaceTracker(); SixenseManager* getSixenseManager() { return &_sixenseManager; } PrioVR* getPrioVR() { return &_prioVR; } - JoystickManager* getJoystickManager() { return &_joystickManager; } BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; } QUndoStack* getUndoStack() { return &_undoStack; } QSystemTrayIcon* getTrayIcon() { return _trayIcon; } @@ -511,7 +509,6 @@ private: SixenseManager _sixenseManager; PrioVR _prioVR; - JoystickManager _joystickManager; Camera _myCamera; // My view onto the world Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp new file mode 100644 index 0000000000..d220a827f1 --- /dev/null +++ b/interface/src/devices/Joystick.cpp @@ -0,0 +1,60 @@ +// +// Joystick.cpp +// interface/src/devices +// +// Created by Stephen Birarda on 2014-09-23. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include + +#include "Joystick.h" + +#ifdef HAVE_SDL + +Joystick::Joystick(const QString& name, SDL_Joystick* sdlJoystick) : + _name(name), + _axes(QVector(SDL_JoystickNumAxes(sdlJoystick))), + _buttons(QVector(SDL_JoystickNumButtons(sdlJoystick))), + _sdlJoystick(sdlJoystick) +{ + +} + +#endif + +Joystick::~Joystick() { +#ifdef HAVE_SDL + SDL_JoystickClose(_sdlJoystick); +#endif +} + +void Joystick::update() { +#ifdef HAVE_SDL + // update our current values, emit a signal when there is a change + for (int j = 0; j < getNumAxes(); j++) { + float value = glm::round(SDL_JoystickGetAxis(_sdlJoystick, j) + 0.5f) / std::numeric_limits::max(); + const float DEAD_ZONE = 0.1f; + float cleanValue = glm::abs(value) < DEAD_ZONE ? 0.0f : value; + + if (_axes[j] != cleanValue) { + float oldValue = _axes[j]; + _axes[j] = cleanValue; + emit axisValueChanged(j, cleanValue, oldValue); + } + } + for (int j = 0; j < getNumButtons(); j++) { + bool newValue = SDL_JoystickGetButton(_sdlJoystick, j); + if (_buttons[j] != newValue) { + bool oldValue = _buttons[j]; + _buttons[j] = newValue; + emit buttonStateChanged(j, newValue, oldValue); + } + } +#endif +} \ No newline at end of file diff --git a/libraries/script-engine/src/JoystickInputController.h b/interface/src/devices/Joystick.h similarity index 50% rename from libraries/script-engine/src/JoystickInputController.h rename to interface/src/devices/Joystick.h index 27166c47fd..c1e9acaff0 100644 --- a/libraries/script-engine/src/JoystickInputController.h +++ b/interface/src/devices/Joystick.h @@ -1,5 +1,5 @@ // -// JoystickInputController.h +// Joystick.h // interface/src/devices // // Created by Stephen Birarda on 2014-09-23. @@ -9,13 +9,18 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_JoystickInputController_h -#define hifi_JoystickInputController_h +#ifndef hifi_Joystick_h +#define hifi_Joystick_h #include #include -class JoystickInputController : public QObject { +#ifdef HAVE_SDL +#include +#undef main +#endif + +class Joystick : public QObject { Q_OBJECT Q_PROPERTY(QString name READ getName) @@ -23,28 +28,31 @@ class JoystickInputController : public QObject { Q_PROPERTY(int numAxes READ getNumAxes) Q_PROPERTY(QVector axes READ getAxes) public: - JoystickInputController(); - JoystickInputController(const QString& name, int numAxes, int numButtons); - JoystickInputController(const JoystickInputController& otherJoystickController); - JoystickInputController& operator=(const JoystickInputController& otherJoystickController); + Joystick(); + ~Joystick(); + +#ifdef HAVE_SDL + Joystick(const QString& name, SDL_Joystick* sdlJoystick); +#endif + + void update(); const QString& getName() const { return _name; } - void updateAxis(int index, float value) { _axes[index] = value; } - void updateButton(int index, bool isActive) { _buttons[index] = isActive; } - - const QVector& getAxes() const { return _axes; } - const QVector& getButtons() const { return _buttons; } - int getNumAxes() const { return _axes.size(); } int getNumButtons() const { return _buttons.size(); } +signals: + void axisValueChanged(int axis, float newValue, float oldValue); + void buttonStateChanged(int button, float newValue, float oldValue); private: - void swap(JoystickInputController& otherJoystickController); - QString _name; QVector _axes; QVector _buttons; + +#ifdef HAVE_SDL + SDL_Joystick* _sdlJoystick; +#endif }; #endif // hifi_JoystickTracker_h \ No newline at end of file diff --git a/interface/src/devices/JoystickManager.cpp b/interface/src/devices/JoystickManager.cpp deleted file mode 100644 index afcc2823ac..0000000000 --- a/interface/src/devices/JoystickManager.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// -// JoystickManager.cpp -// interface/src/devices -// -// Created by Andrzej Kapolka on 5/15/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include -#include - -#include - -#include "JoystickManager.h" - -using namespace std; - -JoystickManager::JoystickManager() { -#ifdef HAVE_SDL - SDL_Init(SDL_INIT_JOYSTICK); - int joystickCount = SDL_NumJoysticks(); - for (int i = 0; i < joystickCount; i++) { - SDL_Joystick* sdlJoystick = SDL_JoystickOpen(i); - if (sdlJoystick) { - _sdlJoysticks.append(sdlJoystick); - - JoystickInputController controller(SDL_JoystickName(i), - SDL_JoystickNumAxes(sdlJoystick), SDL_JoystickNumButtons(sdlJoystick)); - _joysticks.append(controller); - } - } -#endif -} - -JoystickManager::~JoystickManager() { -#ifdef HAVE_SDL - foreach (SDL_Joystick* sdlJoystick, _sdlJoysticks) { - SDL_JoystickClose(sdlJoystick); - } - SDL_Quit(); -#endif -} - -void JoystickManager::update() { -#ifdef HAVE_SDL - PerformanceTimer perfTimer("joystick"); - SDL_JoystickUpdate(); - - for (int i = 0; i < _joysticks.size(); i++) { - SDL_Joystick* sdlJoystick = _sdlJoysticks.at(i); - JoystickInputController& joystick = _joysticks[i]; - for (int j = 0; j < joystick.getNumAxes(); j++) { - float value = glm::round(SDL_JoystickGetAxis(sdlJoystick, j) + 0.5f) / numeric_limits::max(); - const float DEAD_ZONE = 0.1f; - joystick.updateAxis(j, glm::abs(value) < DEAD_ZONE ? 0.0f : value); - } - for (int j = 0; j < joystick.getNumButtons(); j++) { - joystick.updateButton(j, SDL_JoystickGetButton(sdlJoystick, j)); - } - } -#endif -} diff --git a/interface/src/devices/JoystickManager.h b/interface/src/devices/JoystickManager.h deleted file mode 100644 index 31c2dc934b..0000000000 --- a/interface/src/devices/JoystickManager.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// JoystickManager.h -// interface/src/devices -// -// Created by Andrzej Kapolka on 5/15/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_JoystickManager_h -#define hifi_JoystickManager_h - -#include -#include - -#ifdef HAVE_SDL -#include -#undef main -#endif - -#include "JoystickInputController.h" - -class JoystickState; - -/// Handles joystick input through SDL. -class JoystickManager : public QObject { - Q_OBJECT - -public: - JoystickManager(); - virtual ~JoystickManager(); - - QVector& getJoysticks() { return _joysticks; } - - void update(); - -private: - QVector _joysticks; - -#ifdef HAVE_SDL - QVector _sdlJoysticks; -#endif -}; - -#endif // hifi_JoystickManager_h diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index e8047b1ceb..f2e65a6e28 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -297,17 +297,6 @@ AbstractInputController* ControllerScriptingInterface::createInputController(con } } -JoystickInputController* ControllerScriptingInterface::joystick() const { - // stub to just return the first joystick - assume we only have one connected - QVector& activeJoysticks = Application::getInstance()->getJoystickManager()->getJoysticks(); - - if (activeJoysticks.size() > 0) { - return &activeJoysticks[0]; - } else { - return NULL; - } -} - void ControllerScriptingInterface::releaseInputController(AbstractInputController* input) { _inputControllers.erase(input->getKey()); } diff --git a/interface/src/scripting/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h index ada79e95cd..62ef2e9b24 100644 --- a/interface/src/scripting/ControllerScriptingInterface.h +++ b/interface/src/scripting/ControllerScriptingInterface.h @@ -113,7 +113,6 @@ public slots: /// Factory to create an InputController virtual AbstractInputController* createInputController(const QString& deviceName, const QString& tracker); - JoystickInputController* joystick() const; virtual void releaseInputController(AbstractInputController* input); diff --git a/interface/src/scripting/JoystickScriptingInterface.cpp b/interface/src/scripting/JoystickScriptingInterface.cpp new file mode 100644 index 0000000000..cf370cf0e9 --- /dev/null +++ b/interface/src/scripting/JoystickScriptingInterface.cpp @@ -0,0 +1,82 @@ +// +// JoystickManager.cpp +// interface/src/devices +// +// Created by Andrzej Kapolka on 5/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#ifdef HAVE_SDL +#include +#undef main +#endif + +#include + +#include "JoystickScriptingInterface.h" + +JoystickScriptingInterface& JoystickScriptingInterface::getInstance() { + static JoystickScriptingInterface sharedInstance; + return sharedInstance; +} + +JoystickScriptingInterface::JoystickScriptingInterface() : + _openJoysticks(), + _availableDeviceNames() +{ +#ifdef HAVE_SDL + SDL_Init(SDL_INIT_JOYSTICK); + + int joystickCount = SDL_NumJoysticks(); + + for (int i = 0; i < joystickCount; i++) { + _availableDeviceNames << SDL_JoystickName(i); + } +#endif +} + +JoystickScriptingInterface::~JoystickScriptingInterface() { + qDeleteAll(_openJoysticks); + +#ifdef HAVE_SDL + SDL_Quit(); +#endif +} + +void JoystickScriptingInterface::update() { +#ifdef HAVE_SDL + PerformanceTimer perfTimer("JoystickScriptingInterface::update"); + SDL_JoystickUpdate(); + + foreach(Joystick* joystick, _openJoysticks) { + joystick->update(); + } + +#endif +} + +Joystick* JoystickScriptingInterface::joystickWithName(const QString& name) { + Joystick* matchingJoystick = _openJoysticks.value(name); + if (!matchingJoystick) { + // we haven't opened a joystick with this name yet - enumerate our SDL devices and see if it exists + int joystickCount = SDL_NumJoysticks(); + + for (int i = 0; i < joystickCount; i++) { + if (SDL_JoystickName(i) == name) { + matchingJoystick = _openJoysticks.insert(name, new Joystick(name, SDL_JoystickOpen(i))).value(); + break; + } + } + + qDebug() << "No matching joystick found with name" << name << "- returning NULL pointer."; + } + + return matchingJoystick; +} + + diff --git a/interface/src/scripting/JoystickScriptingInterface.h b/interface/src/scripting/JoystickScriptingInterface.h new file mode 100644 index 0000000000..98e38f5698 --- /dev/null +++ b/interface/src/scripting/JoystickScriptingInterface.h @@ -0,0 +1,43 @@ +// +// JoystickScriptingInterface.h +// interface/src/devices +// +// Created by Andrzej Kapolka on 5/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_JoystickScriptingInterface_h +#define hifi_JoystickScriptingInterface_h + +#include +#include + +#include "devices/Joystick.h" + +/// Handles joystick input through SDL. +class JoystickScriptingInterface : public QObject { + Q_OBJECT + + Q_PROPERTY(QStringList availableJoystickNames READ getAvailableJoystickNames) +public: + static JoystickScriptingInterface& getInstance(); + + const QStringList& getAvailableJoystickNames() const { return _availableDeviceNames; } + + void update(); + +public slots: + Joystick* joystickWithName(const QString& name); + +private: + JoystickScriptingInterface(); + ~JoystickScriptingInterface(); + + QMap _openJoysticks; + QStringList _availableDeviceNames; +}; + +#endif // hifi_JoystickScriptingInterface_h diff --git a/libraries/script-engine/src/JoystickInputController.cpp b/libraries/script-engine/src/JoystickInputController.cpp deleted file mode 100644 index fedb3a7643..0000000000 --- a/libraries/script-engine/src/JoystickInputController.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// JoystickInputController.cpp -// interface/src/devices -// -// Created by Stephen Birarda on 2014-09-23. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include "JoystickInputController.h" - -JoystickInputController::JoystickInputController() : - _name(), - _axes(0), - _buttons(0) -{ - -} - -JoystickInputController::JoystickInputController(const QString& name, int numAxes, int numButtons) : - _name(name), - _axes(numAxes), - _buttons(numButtons) -{ - -} - -JoystickInputController::JoystickInputController(const JoystickInputController& otherJoystickController) : - _name(otherJoystickController._name), - _axes(otherJoystickController._axes), - _buttons(otherJoystickController._buttons) -{ - -} - -JoystickInputController& JoystickInputController::operator=(const JoystickInputController& otherJoystickController) { - JoystickInputController temp(otherJoystickController); - swap(temp); - return *this; -} - -void JoystickInputController::swap(JoystickInputController& otherJoystickController) { - using std::swap; - - swap(_name, otherJoystickController._name); - swap(_axes, otherJoystickController._axes); - swap(_buttons, otherJoystickController._buttons); -} diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 0ab5f37f29..545e4709f9 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -35,7 +35,6 @@ #include "AnimationObject.h" #include "ArrayBufferViewClass.h" #include "DataViewClass.h" -#include "JoystickInputController.h" #include "MenuItemProperties.h" #include "MIDIEvent.h" #include "LocalVoxels.h" @@ -81,14 +80,6 @@ void inputControllerFromScriptValue(const QScriptValue &object, AbstractInputCon out = qobject_cast(object.toQObject()); } -QScriptValue joystickToScriptValue(QScriptEngine *engine, JoystickInputController* const &in) { - return engine->newQObject(in); -} - -void joystickFromScriptValue(const QScriptValue &object, JoystickInputController* &out) { - out = qobject_cast(object.toQObject()); -} - ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNameString, AbstractControllerScriptingInterface* controllerScriptingInterface) : @@ -287,7 +278,6 @@ void ScriptEngine::init() { qScriptRegisterMetaType(this, injectorToScriptValue, injectorFromScriptValue); qScriptRegisterMetaType(this, inputControllerToScriptValue, inputControllerFromScriptValue); - qScriptRegisterMetaType(this, joystickToScriptValue, joystickFromScriptValue); qScriptRegisterMetaType(this, animationDetailsToScriptValue, animationDetailsFromScriptValue);