Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core4/src/core/input/JoyStick.cc @ 3276

Last change on this file since 3276 was 3274, checked in by rgrieder, 15 years ago

Added a few more generic parts to the input library:

  • Created Mouse and Keyboard to join JoyStick and provided them with a templated base class (InputDeviceTemplated) that does most of the work (reduces quite some redundancy)
  • Created InputPrereqs.h from InputInterfaces.h and destroyed the latter
  • Exported InputHandler to its own file and replaced KeyHandler, MouseHandler and JoyStickHandler with the single InputHandler.
  • Deleted the SimpleInputState: There is only one class now which fulfills all our needs.

In general there is now less code and the code itself has more 'pluses'. However I haven't really thrown away any feature at all.

  • Property svn:eol-style set to native
File size: 9.7 KB
Line 
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
31#include <ois/OISJoyStick.h>
32#include <ois/OISInputManager.h>
33#include <boost/foreach.hpp>
34
35#include "core/ConfigFileManager.h"
36#include "core/ConfigValueIncludes.h"
37#include "core/CoreIncludes.h"
38#include "util/Convert.h"
39#include "InputState.h"
40#include "InputManager.h"
41
42namespace orxonox
43{
44    /**
45    @brief
46        Helper function that loads the config value vector of one coefficient
47    */
48    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue);
49
50    JoyStick::JoyStick(unsigned int id)
51        : super(id)
52    {
53        RegisterRootObject(JoyStick);
54        this->setConfigValues();
55        // Initialise POV and Slider states
56        this->clearBuffersImpl();
57
58        idString_ = "JoyStick_";
59        std::string name = oisDevice_->vendor();
60        replaceCharacters(name, ' ', '_');
61        idString_ += name + "_";
62        idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + "_";
63        idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
64        idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
65        idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV));
66        //idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3));
67
68        if (InputManager::getInstance().checkJoyStickID(idString_) == false)
69        {
70            // Make the ID unique for this execution time.
71            idString_ += "_" + multi_cast<std::string>(this->getDeviceID());
72        }
73
74        COUT(4) << "Created OIS joy stick with ID " << idString_ << std::endl;
75
76        // Load calibration
77        size_t axes = sliderAxes_s + static_cast<size_t>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis));
78        loadCalibration(configMinValues_,  idString_, "MinValue",  axes,  -32768);
79        loadCalibration(configMaxValues_,  idString_, "MaxValue",  axes,   32768);
80        loadCalibration(configZeroValues_, idString_, "ZeroValue", axes, 0);
81        this->evaluateCalibration();
82    }
83
84    //!< Callback for the joy stick calibration config file.
85    void JoyStick::calibrationFileCallback()
86    {
87        ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
88    }
89
90    void JoyStick::setConfigValues()
91    {
92        SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
93            .description("Ini filename for the the joy stick calibration data.")
94            .callback(this, &JoyStick::calibrationFileCallback);
95    }
96
97    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
98    {
99        list.resize(size);
100        unsigned int configValueVectorSize = ConfigFileManager::getInstance().getVectorSize(ConfigFileType::JoyStickCalibration, sectionName, valueName);
101        if (configValueVectorSize > size)
102            configValueVectorSize = size;
103
104        for (unsigned int i = 0; i < configValueVectorSize; ++i)
105        {
106            list[i] = multi_cast<int>(ConfigFileManager::getInstance().getValue(
107                ConfigFileType::JoyStickCalibration, sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
108        }
109
110        // fill the rest with default values
111        for (unsigned int i = configValueVectorSize; i < size; ++i)
112            list[i] = defaultValue;
113    }
114
115    //! Called by InputDevice when calibration mode has started
116    void JoyStick::calibrationStarted()
117    {
118        // Set initial values
119        BOOST_FOREACH(int& minVal, configMinValues_)
120            minVal = INT_MAX;
121        BOOST_FOREACH(int& minVal, configMaxValues_)
122            minVal = INT_MIN;
123        BOOST_FOREACH(int& zeroVal, configZeroValues_)
124            zeroVal = 0;
125    }
126
127    //! Called by InputDevice when calibration mode has stopped
128    void JoyStick::calibrationStopped()
129    {
130        // Get the middle positions now
131        unsigned int iAxis = 0;
132        for (unsigned int i = 0; i < sliderAxes_s/2; ++i)
133        {
134            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abX;
135            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abY;
136        }
137        // Note: joyStickZeroValues_[iJoyStick] was already correctly resised in loadCalibration()
138        assert(oisDevice_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
139        for (unsigned int i = 0; i < configZeroValues_.size() - sliderAxes_s; ++i)
140            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mAxes[i].abs;
141
142        for (unsigned int i = 0; i < configMinValues_.size(); ++i)
143        {
144            // Minimum values
145            if (configMinValues_[i] == INT_MAX)
146                configMinValues_[i] = -32768;
147            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
148                idString_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);
149
150            // Maximum values
151            if (configMaxValues_[i] == INT_MIN)
152                configMaxValues_[i] = 32767;
153            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
154                idString_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);
155
156            // Middle values
157            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
158                idString_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);
159        }
160
161        this->evaluateCalibration();
162    }
163
164    //! Evaluates the accumulated values during calibration
165    void JoyStick::evaluateCalibration()
166    {
167        for (unsigned int i = 0; i < configMinValues_.size(); i++)
168        {
169            zeroValues_[i] = configZeroValues_[i];
170            negativeCoeffs_[i] = - 1.0f / (configMinValues_[i] - configZeroValues_[i]);
171            positiveCoeffs_[i] =   1.0f / (configMaxValues_[i] - configZeroValues_[i]);
172        }
173    }
174
175    // TODO: What do we really need to reset here?
176    void JoyStick::clearBuffersImpl()
177    {
178        for (int j = 0; j < 4; ++j)
179        {
180            povStates_[j] = 0;
181            sliderStates_[j][0] = 0;
182            sliderStates_[j][1] = 0;
183        }
184    }
185
186    //! Generic method to forward axis events
187    void JoyStick::fireAxis(int axis, int value)
188    {
189        if (this->isCalibrating())
190        {
191            if (value < configMinValues_[axis])
192                configMinValues_[axis] = value;
193            if (value > configMaxValues_[axis])
194                configMaxValues_[axis] = value;
195        }
196        else
197        {
198            float fValue = static_cast<float>(value - zeroValues_[axis]);
199            if (fValue > 0.0f)
200                fValue *= positiveCoeffs_[axis];
201            else
202                fValue *= negativeCoeffs_[axis];
203
204            BOOST_FOREACH(InputState* state, inputStates_)
205                state->joyStickAxisMoved(this->getDeviceID(), axis, fValue);
206        }
207    }
208
209    //! OIS joy stick axis event handler
210    bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis)
211    {
212        // keep in mind that the first 8 axes are reserved for the sliders
213        this->fireAxis(axis + sliderAxes_s, arg.state.mAxes[axis].abs);
214
215        return true;
216    }
217
218    //! A Slider always has an X and an Y direction!
219    bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id)
220    {
221        if (sliderStates_[id][0] != arg.state.mSliders[id].abX)
222            fireAxis(id * 2, arg.state.mSliders[id].abX);
223        else if (sliderStates_[id][1] != arg.state.mSliders[id].abY)
224            fireAxis(id * 2 + 1, arg.state.mSliders[id].abY);
225
226        return true;
227    }
228
229    //! A POV is the big button that can point in all directions (but only in one at once)
230    bool JoyStick::povMoved(const OIS::JoyStickEvent &arg, int id)
231    {
232        // translate the POV into 8 simple buttons
233
234        int lastState = povStates_[id];
235        if (lastState & OIS::Pov::North)
236            buttonReleased(arg, 32 + id * 4 + 0);
237        if (lastState & OIS::Pov::South)
238            buttonReleased(arg, 32 + id * 4 + 1);
239        if (lastState & OIS::Pov::East)
240            buttonReleased(arg, 32 + id * 4 + 2);
241        if (lastState & OIS::Pov::West)
242            buttonReleased(arg, 32 + id * 4 + 3);
243
244        povStates_[id] = arg.state.mPOV[id].direction;
245
246        int currentState = povStates_[id];
247        if (currentState & OIS::Pov::North)
248            buttonPressed(arg, 32 + id * 4 + 0);
249        if (currentState & OIS::Pov::South)
250            buttonPressed(arg, 32 + id * 4 + 1);
251        if (currentState & OIS::Pov::East)
252            buttonPressed(arg, 32 + id * 4 + 2);
253        if (currentState & OIS::Pov::West)
254            buttonPressed(arg, 32 + id * 4 + 3);
255
256        return true;
257    }
258}
Note: See TracBrowser for help on using the repository browser.