Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/libraries/core/input/JoyStick.cc @ 10561

Last change on this file since 10561 was 10561, checked in by landauf, 9 years ago

found some unregistered classes

  • Property svn:eol-style set to native
File size: 10.1 KB
RevLine 
[3270]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "JoyStick.h"
30
[3329]31#include <climits>
[3270]32#include <ois/OISJoyStick.h>
33#include <boost/foreach.hpp>
34
[6417]35#include "util/StringUtils.h"
[9667]36#include "core/config/ConfigFile.h"
37#include "core/config/ConfigFileManager.h"
38#include "core/config/ConfigValueIncludes.h"
[3270]39#include "core/CoreIncludes.h"
40#include "util/Convert.h"
41#include "InputState.h"
42
43namespace orxonox
44{
[3327]45    //! Helper function that loads the config value vector of one coefficient
[3270]46    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue);
47
[3327]48    std::vector<std::string> JoyStick::deviceNames_s;
49
[10561]50    RegisterAbstractClass(JoyStick).inheritsFrom<Configurable>();
51
[3327]52    JoyStick::JoyStick(unsigned int id, OIS::InputManager* oisInputManager)
53        : super(id, oisInputManager)
[3270]54    {
[9667]55        RegisterObject(JoyStick);
[3270]56        this->setConfigValues();
[3327]57        // Initialise POV and Slider states
58        this->clearBuffersImpl();
[3270]59
[3327]60        // Generate unique name
61        if (oisDevice_->vendor().empty())
62            deviceName_ = "Unknown_";
63        else
64        {
65            std::string name = oisDevice_->vendor();
66            replaceCharacters(name, ' ', '_');
[6417]67            deviceName_ = name + '_';
[3327]68        }
[6417]69        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + '_';
70        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + '_';
71        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + '_';
[3327]72        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV));
73        //deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3));
[3270]74
[3327]75        BOOST_FOREACH(std::string& idString, deviceNames_s)
[3270]76        {
[3327]77            if (deviceName_ == idString)
78            {
79                // Make the ID unique for this execution time.
[6417]80                deviceName_ += '_' + multi_cast<std::string>(this->getDeviceName());
[3327]81                break;
82            }
[3270]83        }
84
[8858]85        orxout(verbose, context::input) << "Created OIS joy stick with ID " << deviceName_ << endl;
[3270]86
87        // Load calibration
[3327]88        size_t axes = sliderAxes_s + static_cast<size_t>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis));
89        loadCalibration(configMinValues_,  deviceName_, "MinValue",  axes,  -32768);
90        loadCalibration(configMaxValues_,  deviceName_, "MaxValue",  axes,   32768);
91        loadCalibration(configZeroValues_, deviceName_, "ZeroValue", axes, 0);
[3270]92        this->evaluateCalibration();
93    }
94
[3327]95    //! Callback for the joy stick calibration config file.
[3270]96    void JoyStick::calibrationFileCallback()
97    {
98        ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
99    }
100
101    void JoyStick::setConfigValues()
102    {
103        SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
104            .description("Ini filename for the the joy stick calibration data.")
105            .callback(this, &JoyStick::calibrationFileCallback);
106    }
107
108    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
109    {
110        list.resize(size);
[6536]111        unsigned int configValueVectorSize = ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)->getVectorSize(sectionName, valueName);
[3270]112        if (configValueVectorSize > size)
113            configValueVectorSize = size;
114
115        for (unsigned int i = 0; i < configValueVectorSize; ++i)
116        {
[6536]117            list[i] = multi_cast<int>(ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)
118                ->getOrCreateValue(sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
[3270]119        }
120
121        // fill the rest with default values
122        for (unsigned int i = configValueVectorSize; i < size; ++i)
123            list[i] = defaultValue;
124    }
125
[3327]126    //! Called by InputDevice when calibration mode has started
127    void JoyStick::calibrationStarted()
[3270]128    {
129        // Set initial values
130        BOOST_FOREACH(int& minVal, configMinValues_)
131            minVal = INT_MAX;
132        BOOST_FOREACH(int& minVal, configMaxValues_)
133            minVal = INT_MIN;
134        BOOST_FOREACH(int& zeroVal, configZeroValues_)
135            zeroVal = 0;
136    }
137
[3327]138    //! Called by InputDevice when calibration mode has stopped
139    void JoyStick::calibrationStopped()
[3270]140    {
141        // Get the middle positions now
142        unsigned int iAxis = 0;
143        for (unsigned int i = 0; i < sliderAxes_s/2; ++i)
144        {
[3327]145            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abX;
146            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abY;
[3270]147        }
[3327]148        // Note: joyStickZeroValues_[iJoyStick] was already correctly resised in loadCalibration()
149        assert(oisDevice_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
[3270]150        for (unsigned int i = 0; i < configZeroValues_.size() - sliderAxes_s; ++i)
[3327]151            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mAxes[i].abs;
[3270]152
153        for (unsigned int i = 0; i < configMinValues_.size(); ++i)
154        {
155            // Minimum values
156            if (configMinValues_[i] == INT_MAX)
157                configMinValues_[i] = -32768;
[6536]158            ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)
159                ->getOrCreateValue(deviceName_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);
[3270]160
161            // Maximum values
162            if (configMaxValues_[i] == INT_MIN)
163                configMaxValues_[i] = 32767;
[6536]164            ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)
165                ->getOrCreateValue(deviceName_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);
[3270]166
167            // Middle values
[6536]168            ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)
169                ->getOrCreateValue(deviceName_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);
[3270]170        }
171
172        this->evaluateCalibration();
173    }
174
[3327]175    //! Evaluates the accumulated values during calibration
[3270]176    void JoyStick::evaluateCalibration()
177    {
178        for (unsigned int i = 0; i < configMinValues_.size(); i++)
179        {
180            zeroValues_[i] = configZeroValues_[i];
181            negativeCoeffs_[i] = - 1.0f / (configMinValues_[i] - configZeroValues_[i]);
182            positiveCoeffs_[i] =   1.0f / (configMaxValues_[i] - configZeroValues_[i]);
183        }
184    }
185
[3327]186    //! Resets the pov states
187    void JoyStick::clearBuffersImpl()
[3270]188    {
189        for (int j = 0; j < 4; ++j)
190            povStates_[j] = 0;
191    }
192
[3327]193    //! Generic method to forward axis events
[3270]194    void JoyStick::fireAxis(int axis, int value)
195    {
[3327]196        if (this->isCalibrating())
[3270]197        {
198            if (value < configMinValues_[axis])
199                configMinValues_[axis] = value;
200            if (value > configMaxValues_[axis])
201                configMaxValues_[axis] = value;
202        }
203        else
204        {
205            float fValue = static_cast<float>(value - zeroValues_[axis]);
206            if (fValue > 0.0f)
207                fValue *= positiveCoeffs_[axis];
208            else
209                fValue *= negativeCoeffs_[axis];
210
211            BOOST_FOREACH(InputState* state, inputStates_)
[3327]212                state->joyStickAxisMoved(this->getDeviceID(), axis, fValue);
[3270]213        }
214    }
215
[3327]216    //! OIS joy stick axis event handler
[3270]217    bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis)
218    {
219        // keep in mind that the first 8 axes are reserved for the sliders
220        this->fireAxis(axis + sliderAxes_s, arg.state.mAxes[axis].abs);
221
222        return true;
223    }
224
[3327]225    //! A Slider always has an X and an Y direction!
[3270]226    bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id)
227    {
228        if (sliderStates_[id][0] != arg.state.mSliders[id].abX)
229            fireAxis(id * 2, arg.state.mSliders[id].abX);
230        else if (sliderStates_[id][1] != arg.state.mSliders[id].abY)
231            fireAxis(id * 2 + 1, arg.state.mSliders[id].abY);
232
233        return true;
234    }
235
[3327]236    //! A POV is the big button that can point in all directions (but only in one at once)
[3270]237    bool JoyStick::povMoved(const OIS::JoyStickEvent &arg, int id)
238    {
239        // translate the POV into 8 simple buttons
240
241        int lastState = povStates_[id];
242        if (lastState & OIS::Pov::North)
243            buttonReleased(arg, 32 + id * 4 + 0);
244        if (lastState & OIS::Pov::South)
245            buttonReleased(arg, 32 + id * 4 + 1);
246        if (lastState & OIS::Pov::East)
247            buttonReleased(arg, 32 + id * 4 + 2);
248        if (lastState & OIS::Pov::West)
249            buttonReleased(arg, 32 + id * 4 + 3);
250
251        povStates_[id] = arg.state.mPOV[id].direction;
252
253        int currentState = povStates_[id];
254        if (currentState & OIS::Pov::North)
255            buttonPressed(arg, 32 + id * 4 + 0);
256        if (currentState & OIS::Pov::South)
257            buttonPressed(arg, 32 + id * 4 + 1);
258        if (currentState & OIS::Pov::East)
259            buttonPressed(arg, 32 + id * 4 + 2);
260        if (currentState & OIS::Pov::West)
261            buttonPressed(arg, 32 + id * 4 + 3);
262
263        return true;
264    }
265}
Note: See TracBrowser for help on using the repository browser.