From 274737b8d9b46dfcf6fc696123e869bbf6adaaf6 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 9 Nov 2011 02:51:52 +0300 Subject: Add support for joystick selection. Fix enable/disable joystick support. Increase max joystick buttons number to 64. Prevent joystick usage without calibration. --- src/client.cpp | 3 ++ src/defaults.cpp | 1 + src/game.cpp | 6 --- src/gui/setup_joystick.cpp | 104 +++++++++++++++++++++++++++++++++++++++------ src/gui/setup_joystick.h | 10 +++++ src/joystick.cpp | 101 +++++++++++++++++++++++++++++++++---------- src/joystick.h | 25 +++++++++-- 7 files changed, 206 insertions(+), 44 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 9c7c8c9a2..c842d0d00 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -34,6 +34,7 @@ #include "guildmanager.h" #include "graphicsvertexes.h" #include "itemshortcut.h" +#include "joystick.h" #include "keyboardconfig.h" #ifdef USE_OPENGL #include "openglgraphics.h" @@ -561,6 +562,8 @@ Client::Client(const Options &options): // Initialise player relations player_relations.init(); + Joystick::init(); + userPalette = new UserPalette; setupWindow = new Setup; diff --git a/src/defaults.cpp b/src/defaults.cpp index 8d5907f05..76438a1e2 100644 --- a/src/defaults.cpp +++ b/src/defaults.cpp @@ -222,6 +222,7 @@ DefaultsData* getConfigDefaults() AddDEF(configData, "showMVP", false); AddDEF(configData, "pvpAttackType", 0); AddDEF(configData, "lang", ""); + AddDEF(configData, "selectedJoystick", 0); return configData; } diff --git a/src/game.cpp b/src/game.cpp index f0964bbb4..d5cfad13a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -403,12 +403,6 @@ Game::Game(): */ Net::getGameHandler()->ping(tick_time); - Joystick::init(); - // TODO: The user should be able to choose which one to use - // Open the first device - if (Joystick::getNumberOfJoysticks() > 0) - joystick = new Joystick(0); - if (setupWindow) setupWindow->setInGame(true); clearKeysArray(); diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp index aadfc11e3..a1f3c8cea 100644 --- a/src/gui/setup_joystick.cpp +++ b/src/gui/setup_joystick.cpp @@ -24,54 +24,114 @@ #include "configuration.h" #include "joystick.h" +#include "logger.h" #include "gui/widgets/button.h" #include "gui/widgets/checkbox.h" +#include "gui/widgets/dropdown.h" #include "gui/widgets/label.h" #include "gui/widgets/layouthelper.h" #include "utils/gettext.h" +#include + #include "debug.h" extern Joystick *joystick; +class NamesModel : public gcn::ListModel +{ + public: + NamesModel() + { } + + virtual ~NamesModel() + { } + + virtual int getNumberOfElements() + { + return static_cast(mNames.size()); + } + + virtual std::string getElementAt(int i) + { + if (i >= getNumberOfElements() || i < 0) + return _("???"); + + return mNames[i]; + } + + std::vector mNames; +}; + + Setup_Joystick::Setup_Joystick(): mCalibrateLabel(new Label(_("Press the button to start calibration"))), mCalibrateButton(new Button(_("Calibrate"), "calibrate", this)), - mJoystickEnabled(new CheckBox(_("Enable joystick"))) + mJoystickEnabled(new CheckBox(_("Enable joystick"))), + mNamesModel(new NamesModel()) { setName(_("Joystick")); - mOriginalJoystickEnabled = !config.getBoolValue("joystickEnabled"); - mJoystickEnabled->setSelected(mOriginalJoystickEnabled); + Joystick::getNames(mNamesModel->mNames); + mOriginalJoystickEnabled = config.getBoolValue("joystickEnabled"); + mJoystickEnabled->setSelected(mOriginalJoystickEnabled); + mJoystickEnabled->setActionEventId("joystick"); mJoystickEnabled->addActionListener(this); + mCalibrateButton->setEnabled(mOriginalJoystickEnabled); + + mNamesDropDown = new DropDown(mNamesModel); + mNamesDropDown->setActionEventId("name"); + mNamesDropDown->addActionListener(this); + + if (joystick) + { + mNamesDropDown->setSelected(joystick->getNumber()); + } + else + { + unsigned sel = config.getIntValue("selectedJoystick"); + if (sel >= mNamesModel->mNames.size()) + sel = 0; + mNamesDropDown->setSelected(sel); + } // Do the layout LayoutHelper h(this); ContainerPlacer place = h.getPlacer(0, 0); place(0, 0, mJoystickEnabled); - place(0, 1, mCalibrateLabel); - place.getCell().matchColWidth(0, 0); - place = h.getPlacer(0, 1); - place(0, 0, mCalibrateButton); + place(0, 1, mNamesDropDown); + place(0, 2, mCalibrateLabel); + place(0, 3, mCalibrateButton); setDimension(gcn::Rectangle(0, 0, 365, 75)); } -void Setup_Joystick::action(const gcn::ActionEvent &event) +Setup_Joystick::~Setup_Joystick() { - if (!joystick) - return; + delete mNamesModel; + mNamesModel = nullptr; +} +void Setup_Joystick::action(const gcn::ActionEvent &event) +{ if (event.getSource() == mJoystickEnabled) { - joystick->setEnabled(mJoystickEnabled->isSelected()); + setTempEnabled(mJoystickEnabled->isSelected()); + } + else if (event.getSource() == mNamesDropDown) + { + if (joystick) + joystick->setNumber(mNamesDropDown->getSelected()); } else { + if (!joystick) + return; + if (joystick->isCalibrating()) { mCalibrateButton->setCaption(_("Calibrate")); @@ -88,17 +148,35 @@ void Setup_Joystick::action(const gcn::ActionEvent &event) } } +void Setup_Joystick::setTempEnabled(bool sel) +{ + Joystick::setEnabled(sel); + mCalibrateButton->setEnabled(sel); + if (joystick) + { + if (sel) + joystick->open(); + else + joystick->close(); + } +} + void Setup_Joystick::cancel() { if (joystick) joystick->setEnabled(mOriginalJoystickEnabled); + if (mOriginalJoystickEnabled != mJoystickEnabled->isSelected()) + setTempEnabled(mOriginalJoystickEnabled); + mJoystickEnabled->setSelected(mOriginalJoystickEnabled); } void Setup_Joystick::apply() { + if (!joystick) + return; + config.setValue("joystickEnabled", - joystick ? joystick->isEnabled() : false); + joystick ? joystick->isEnabled() : false); } - diff --git a/src/gui/setup_joystick.h b/src/gui/setup_joystick.h index d18d5a7fb..e0a3a143f 100644 --- a/src/gui/setup_joystick.h +++ b/src/gui/setup_joystick.h @@ -29,21 +29,31 @@ #include +class DropDown; +class NamesModel; + class Setup_Joystick : public SetupTab { public: Setup_Joystick(); + ~Setup_Joystick(); + void apply(); + void cancel(); void action(const gcn::ActionEvent &event); + void setTempEnabled(bool sel); + private: gcn::Label *mCalibrateLabel; gcn::Button *mCalibrateButton; bool mOriginalJoystickEnabled; gcn::CheckBox *mJoystickEnabled; + NamesModel *mNamesModel; + DropDown *mNamesDropDown; }; #endif diff --git a/src/joystick.cpp b/src/joystick.cpp index f45729351..29e2c31cc 100644 --- a/src/joystick.cpp +++ b/src/joystick.cpp @@ -27,55 +27,103 @@ #include "debug.h" int Joystick::joystickCount = 0; +bool Joystick::mEnabled = false; void Joystick::init() { SDL_InitSubSystem(SDL_INIT_JOYSTICK); - - // Have SDL call SDL_JoystickUpdate() automatically SDL_JoystickEventState(SDL_ENABLE); - joystickCount = SDL_NumJoysticks(); logger->log("%i joysticks/gamepads found", joystickCount); for (int i = 0; i < joystickCount; i++) logger->log("- %s", SDL_JoystickName(i)); + + mEnabled = config.getBoolValue("joystickEnabled"); + + if (Joystick::getNumberOfJoysticks() > 0) + { + joystick = new Joystick(config.getIntValue("selectedJoystick")); + if (mEnabled) + joystick->open(); + } } Joystick::Joystick(int no): mDirection(0), + mJoystick(nullptr), mCalibrating(false), - mEnabled(false) + mCalibrated(false), + mButtonsNumber(MAX_BUTTONS) { if (no >= joystickCount) no = joystickCount; - mJoystick = SDL_JoystickOpen(no); + mNumber = no; + + for (int i = 0; i < MAX_BUTTONS; i++) + mButtons[i] = false; +} + +Joystick::~Joystick() +{ + close(); +} + +bool Joystick::open() +{ + logger->log("open joystick %d", mNumber); + + mJoystick = SDL_JoystickOpen(mNumber); // TODO Bail out! if (!mJoystick) { logger->log("Couldn't open joystick: %s", SDL_GetError()); - return; + return false; } + mButtonsNumber = SDL_JoystickNumButtons(mJoystick); + logger->log("Joystick: %i ", mNumber); logger->log("Axes: %i ", SDL_JoystickNumAxes(mJoystick)); logger->log("Balls: %i", SDL_JoystickNumBalls(mJoystick)); logger->log("Hats: %i", SDL_JoystickNumHats(mJoystick)); - logger->log("Buttons: %i", SDL_JoystickNumButtons(mJoystick)); + logger->log("Buttons: %i", mButtonsNumber); - mEnabled = config.getBoolValue("joystickEnabled"); - mUpTolerance = config.getIntValue("upTolerance"); - mDownTolerance = config.getIntValue("downTolerance"); - mLeftTolerance = config.getIntValue("leftTolerance"); - mRightTolerance = config.getIntValue("rightTolerance"); + if (mButtonsNumber > MAX_BUTTONS) + mButtonsNumber = MAX_BUTTONS; - for (int i = 0; i < MAX_BUTTONS; i++) - mButtons[i] = false; + mCalibrated = config.getValueBool("joystick" + + toString(mNumber) + "calibrated", false); + mUpTolerance = config.getIntValue("upTolerance" + toString(mNumber)); + mDownTolerance = config.getIntValue("downTolerance" + toString(mNumber)); + mLeftTolerance = config.getIntValue("leftTolerance" + toString(mNumber)); + mRightTolerance = config.getIntValue("rightTolerance" + toString(mNumber)); + + return true; } -Joystick::~Joystick() +void Joystick::close() { - SDL_JoystickClose(mJoystick); + logger->log("close joystick %d", mNumber); + if (mJoystick) + { + SDL_JoystickClose(mJoystick); + mJoystick = nullptr; + } +} + +void Joystick::setNumber(int n) +{ + if (mJoystick) + { + SDL_JoystickClose(mJoystick); + mNumber = n; + } + else + { + mNumber = n; + } + open(); } void Joystick::update() @@ -89,7 +137,7 @@ void Joystick::update() return; }; - if (!mEnabled) + if (!mEnabled || !mCalibrated) return; // X-Axis @@ -107,7 +155,7 @@ void Joystick::update() mDirection |= DOWN; // Buttons - for (int i = 0; i < MAX_BUTTONS; i++) + for (int i = 0; i < mButtonsNumber; i++) mButtons[i] = (SDL_JoystickGetButton(mJoystick, i) == 1); } @@ -139,14 +187,23 @@ void Joystick::doCalibration() void Joystick::finishCalibration() { - config.setValue("leftTolerance", mLeftTolerance); - config.setValue("rightTolerance", mRightTolerance); - config.setValue("upTolerance", mUpTolerance); - config.setValue("downTolerance", mDownTolerance); + mCalibrated = true; mCalibrating = false; + config.setValue("joystick" + toString(mNumber) + "calibrated", true); + config.setValue("leftTolerance" + toString(mNumber), mLeftTolerance); + config.setValue("rightTolerance" + toString(mNumber), mRightTolerance); + config.setValue("upTolerance" + toString(mNumber), mUpTolerance); + config.setValue("downTolerance" + toString(mNumber), mDownTolerance); } bool Joystick::buttonPressed(unsigned char no) const { return (mEnabled && no < MAX_BUTTONS) ? mButtons[no] : false; } + +void Joystick::getNames(std::vector &names) +{ + names.clear(); + for (int i = 0; i < joystickCount; i++) + names.push_back(SDL_JoystickName(i)); +} diff --git a/src/joystick.h b/src/joystick.h index 32efc5bff..3a2258cd5 100644 --- a/src/joystick.h +++ b/src/joystick.h @@ -33,7 +33,7 @@ class Joystick */ enum { - MAX_BUTTONS = 6 + MAX_BUTTONS = 64 }; /** @@ -66,12 +66,20 @@ class Joystick ~Joystick(); + bool open(); + + void close(); + bool isEnabled() const { return mEnabled; } - void setEnabled(bool enabled) + void setNumber(int n); + + static void setEnabled(bool enabled) { mEnabled = enabled; } + static void getNames(std::vector &names); + /** * Updates the direction and button information. */ @@ -98,6 +106,9 @@ class Joystick bool isRight() const { return mEnabled && (mDirection & RIGHT); }; + int getNumber() const + { return mNumber; } + protected: unsigned char mDirection; bool mButtons[MAX_BUTTONS]; @@ -105,11 +116,19 @@ class Joystick int mUpTolerance, mDownTolerance, mLeftTolerance, mRightTolerance; bool mCalibrating; - bool mEnabled; + int mNumber; + bool mCalibrated; + int mButtonsNumber; + /** + * Is joystick support enabled. + */ + static bool mEnabled; static int joystickCount; void doCalibration(); }; +extern Joystick *joystick; + #endif // JOYSTICK_H -- cgit v1.2.3-60-g2f50