Commit b408932f authored by Ben Hymers's avatar Ben Hymers
Browse files

Add .gitattributes to control line endings, and normalise all existing files

parent c50bad3f
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by OIS.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by OIS.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
#include "OIS.h"
#include <math.h>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <ios>
#include <sstream>
#include <vector>
using namespace std;
////////////////////////////////////Needed Windows Headers////////////
#if defined OIS_WIN32_PLATFORM
# define WIN32_LEAN_AND_MEAN
# include "windows.h"
# include "resource.h"
////////////////////////////////////Needed Linux Headers//////////////
#elif defined OIS_LINUX_PLATFORM
# include <X11/Xlib.h>
#else
# error Sorry, not yet implemented on this platform.
#endif
using namespace OIS;
#if defined OIS_WIN32_PLATFORM
// The dialog proc we have to give to CreateDialog
LRESULT DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
return FALSE;
}
#endif
//////////// Event handler class declaration ////////////////////////////////////////////////
class Application;
class JoystickManager;
class EffectManager;
class EventHandler : public KeyListener, public JoyStickListener
{
protected:
Application* _pApplication;
JoystickManager* _pJoystickMgr;
EffectManager* _pEffectMgr;
public:
EventHandler(Application* pApp);
void initialize(JoystickManager* pJoystickMgr, EffectManager* pEffectMgr);
bool keyPressed( const KeyEvent &arg );
bool keyReleased( const KeyEvent &arg );
bool buttonPressed( const JoyStickEvent &arg, int button );
bool buttonReleased( const JoyStickEvent &arg, int button );
bool axisMoved( const JoyStickEvent &arg, int axis );
bool povMoved( const JoyStickEvent &arg, int pov );
};
//////////// Variable classes ////////////////////////////////////////////////////////
class Variable
{
protected:
double _dInitValue;
double _dValue;
public:
Variable(double dInitValue) : _dInitValue(dInitValue) { reset(); }
double getValue() const { return _dValue; }
void reset() { _dValue = _dInitValue; }
virtual void setValue(double dValue) { _dValue = dValue; }
virtual string toString() const
{
ostringstream oss;
oss << _dValue;
return oss.str();
}
virtual void update() {};
};
class Constant : public Variable
{
public:
Constant(double dInitValue) : Variable(dInitValue) {}
virtual void setValue(double dValue) { }
};
class LimitedVariable : public Variable
{
protected:
double _dMinValue;
double _dMaxValue;
public:
LimitedVariable(double dInitValue, double dMinValue, double dMaxValue)
: _dMinValue(dMinValue), _dMaxValue(dMaxValue), Variable(dInitValue)
{}
virtual void setValue(double dValue)
{
_dValue = dValue;
if (_dValue > _dMaxValue)
_dValue = _dMaxValue;
else if (_dValue < _dMinValue)
_dValue = _dMinValue;
}
/* virtual string toString() const
{
ostringstream oss;
oss << setiosflags(ios_base::right) << setw(4)
<< (int)(200.0 * getValue()/(_dMaxValue - _dMinValue)); // [-100%, +100%]
return oss.str();
}*/
};
class TriangleVariable : public LimitedVariable
{
protected:
double _dDeltaValue;
public:
TriangleVariable(double dInitValue, double dDeltaValue, double dMinValue, double dMaxValue)
: LimitedVariable(dInitValue, dMinValue, dMaxValue), _dDeltaValue(dDeltaValue) {};
virtual void update()
{
double dValue = getValue() + _dDeltaValue;
if (dValue > _dMaxValue)
{
dValue = _dMaxValue;
_dDeltaValue = -_dDeltaValue;
//cout << "Decreasing variable towards " << _dMinValue << endl;
}
else if (dValue < _dMinValue)
{
dValue = _dMinValue;
_dDeltaValue = -_dDeltaValue;
//cout << "Increasing variable towards " << _dMaxValue << endl;
}
setValue(dValue);
//cout << "TriangleVariable::update : delta=" << _dDeltaValue << ", value=" << dValue << endl;
}
};
//////////// Variable effect class //////////////////////////////////////////////////////////
typedef map<string, Variable*> MapVariables;
typedef void (*EffectVariablesApplier)(MapVariables& mapVars, Effect* pEffect);
class VariableEffect
{
protected:
// Effect description
const char* _pszDesc;
// The associate OIS effect
Effect* _pEffect;
// The effect variables.
MapVariables _mapVariables;
// The effect variables applier function.
EffectVariablesApplier _pfApplyVariables;
// True if the effect is currently being played.
bool _bActive;
public:
VariableEffect(const char* pszDesc, Effect* pEffect,
const MapVariables& mapVars, const EffectVariablesApplier pfApplyVars)
: _pszDesc(pszDesc), _pEffect(pEffect),
_mapVariables(mapVars), _pfApplyVariables(pfApplyVars), _bActive(false)
{}
~VariableEffect()
{
if (_pEffect)
delete _pEffect;
MapVariables::iterator iterVars;
for (iterVars = _mapVariables.begin(); iterVars != _mapVariables.end(); iterVars++)
if (iterVars->second)
delete iterVars->second;
}
void setActive(bool bActive = true)
{
reset();
_bActive = bActive;
}
bool isActive()
{
return _bActive;
}
Effect* getFFEffect()
{
return _pEffect;
}
const char* getDescription() const
{
return _pszDesc;
}
void update()
{
if (isActive())
{
// Update the variables.
MapVariables::iterator iterVars;
for (iterVars = _mapVariables.begin(); iterVars != _mapVariables.end(); iterVars++)
iterVars->second->update();
// Apply the updated variable values to the effect.
_pfApplyVariables(_mapVariables, _pEffect);
}
}
void reset()
{
MapVariables::iterator iterVars;
for (iterVars = _mapVariables.begin(); iterVars != _mapVariables.end(); iterVars++)
iterVars->second->reset();
_pfApplyVariables(_mapVariables, _pEffect);
}
string toString() const
{
string str;
MapVariables::const_iterator iterVars;
for (iterVars = _mapVariables.begin(); iterVars != _mapVariables.end(); iterVars++)
str += iterVars->first + ":" + iterVars->second->toString() + " ";
return str;
}
};
//////////// Joystick manager class ////////////////////////////////////////////////////////
class JoystickManager
{
protected:
// Input manager.
InputManager* _pInputMgr;
// Vectors to hold joysticks and associated force feedback devices
vector<JoyStick*> _vecJoys;
vector<ForceFeedback*> _vecFFDev;
// Selected joystick
int _nCurrJoyInd;
// Force feedback detected ?
bool _bFFFound;
// Selected joystick master gain.
float _dMasterGain;
// Selected joystick auto-center mode.
bool _bAutoCenter;
public:
JoystickManager(InputManager* pInputMgr, EventHandler* pEventHdlr)
: _pInputMgr(pInputMgr), _nCurrJoyInd(-1), _dMasterGain(0.5), _bAutoCenter(true)
{
_bFFFound = false;
for( int nJoyInd = 0; nJoyInd < pInputMgr->getNumberOfDevices(OISJoyStick); ++nJoyInd )
{
//Create the stick
JoyStick* pJoy = (JoyStick*)pInputMgr->createInputObject( OISJoyStick, true );
cout << endl << "Created buffered joystick #" << nJoyInd << " '" << pJoy->vendor()
<< "' (Id=" << pJoy->getID() << ")";
// Check for FF, and if so, keep the joy and dump FF info
ForceFeedback* pFFDev = (ForceFeedback*)pJoy->queryInterface(Interface::ForceFeedback );
if( pFFDev )
{
_bFFFound = true;
// Keep the joy to play with it.
pJoy->setEventCallback(pEventHdlr);
_vecJoys.push_back(pJoy);
// Keep also the associated FF device
_vecFFDev.push_back(pFFDev);
// Dump FF supported effects and other info.
cout << endl << " * Number of force feedback axes : "
<< pFFDev->getFFAxesNumber() << endl;
const ForceFeedback::SupportedEffectList &lstFFEffects =
pFFDev->getSupportedEffects();
if (lstFFEffects.size() > 0)
{
cout << " * Supported effects :";
ForceFeedback::SupportedEffectList::const_iterator itFFEff;
for(itFFEff = lstFFEffects.begin(); itFFEff != lstFFEffects.end(); ++itFFEff)
cout << " " << Effect::getEffectTypeName(itFFEff->second);
cout << endl << endl;
}
else
cout << "Warning: no supported effect found !" << endl;
}
else
{
cout << " (no force feedback support detected) => ignored." << endl << endl;
_pInputMgr->destroyInputObject(pJoy);
}
}
}
~JoystickManager()
{
for(size_t nJoyInd = 0; nJoyInd < _vecJoys.size(); ++nJoyInd)
_pInputMgr->destroyInputObject( _vecJoys[nJoyInd] );
}
size_t getNumberOfJoysticks() const
{
return _vecJoys.size();
}
bool wasFFDetected() const
{
return _bFFFound;
}
enum EWhichJoystick { ePrevious=-1, eNext=+1 };
void selectJoystick(EWhichJoystick eWhich)
{
// Note: Reset the master gain to half the maximum and autocenter mode to Off,
// when really selecting a new joystick.
if (_nCurrJoyInd < 0)
{
_nCurrJoyInd = 0;
_dMasterGain = 0.5; // Half the maximum.
changeMasterGain(0.0);
}
else
{
_nCurrJoyInd += eWhich;
if (_nCurrJoyInd < -1 || _nCurrJoyInd >= (int)_vecJoys.size())
_nCurrJoyInd = -1;
if (_vecJoys.size() > 1 && _nCurrJoyInd >= 0)
{
_dMasterGain = 0.5; // Half the maximum.
changeMasterGain(0.0);
}
}
}
ForceFeedback* getCurrentFFDevice()
{
return (_nCurrJoyInd >= 0) ? _vecFFDev[_nCurrJoyInd] : 0;
}
void changeMasterGain(float dDeltaPercent)
{
if (_nCurrJoyInd >= 0)
{
_dMasterGain += dDeltaPercent / 100;
if (_dMasterGain > 1.0)
_dMasterGain = 1.0;
else if (_dMasterGain < 0.0)
_dMasterGain = 0.0;
_vecFFDev[_nCurrJoyInd]->setMasterGain(_dMasterGain);
}
}
enum EAutoCenterHow { eOff, eOn, eToggle };
void changeAutoCenter(EAutoCenterHow eHow = eToggle)
{
if (_nCurrJoyInd >= 0)
{
if (eHow == eToggle)
_bAutoCenter = !_bAutoCenter;
else
_bAutoCenter = (eHow == eOn ? true : false);
_vecFFDev[_nCurrJoyInd]->setAutoCenterMode(_bAutoCenter);
}
}
void captureEvents()
{
// This fires off buffered events for each joystick we have
for(size_t nJoyInd = 0; nJoyInd < _vecJoys.size(); ++nJoyInd)
if( _vecJoys[nJoyInd] )
_vecJoys[nJoyInd]->capture();
}
string toString() const
{
// Warning: Wrong result if more than 10 joysticks ...
ostringstream oss;
oss << "Joy:" << (_nCurrJoyInd >= 0 ? (char)('0' + _nCurrJoyInd) : '-');
oss << " Gain:" << setiosflags(ios_base::right) << setw(3) << (int)(_dMasterGain*100);
oss << "% Center:" << (_bAutoCenter ? " On " : "Off");
return oss.str();
}
};
//////////// Effect variables applier functions /////////////////////////////////////////////
// These functions apply the given Variables to the given OIS::Effect
// Variable force "Force" + optional "AttackFactor" constant, on a OIS::ConstantEffect
void forceVariableApplier(MapVariables& mapVars, Effect* pEffect)
{
double dForce = mapVars["Force"]->getValue();
double dAttackFactor = 1.0;
if (mapVars.find("AttackFactor") != mapVars.end())
dAttackFactor = mapVars["AttackFactor"]->getValue();
ConstantEffect* pConstForce = dynamic_cast<ConstantEffect*>(pEffect->getForceEffect());
pConstForce->level = (int)dForce;
pConstForce->envelope.attackLevel = (unsigned short)fabs(dForce*dAttackFactor);
pConstForce->envelope.fadeLevel = (unsigned short)fabs(dForce); // Fade never reached, in fact.
}
// Variable "Period" on an OIS::PeriodicEffect
void periodVariableApplier(MapVariables& mapVars, Effect* pEffect)
{
double dPeriod = mapVars["Period"]->getValue();
PeriodicEffect* pPeriodForce = dynamic_cast<PeriodicEffect*>(pEffect->getForceEffect());
pPeriodForce->period = (unsigned int)dPeriod;
}
//////////// Effect manager class //////////////////////////////////////////////////////////
class EffectManager
{
protected:
// The joystick manager
JoystickManager* _pJoystickMgr;
// Vector to hold variable effects
vector<VariableEffect*> _vecEffects;
// Selected effect
int _nCurrEffectInd;
// Update frequency (Hz)
unsigned int _nUpdateFreq;
// Indexes (in _vecEffects) of the variable effects that are playable by the selected joystick.
vector<size_t> _vecPlayableEffectInd;
public:
EffectManager(JoystickManager* pJoystickMgr, unsigned int nUpdateFreq)
: _pJoystickMgr(pJoystickMgr), _nUpdateFreq(nUpdateFreq), _nCurrEffectInd(-1)
{
Effect* pEffect;
MapVariables mapVars;
ConstantEffect* pConstForce;
PeriodicEffect* pPeriodForce;
// Please don't modify or remove effects (unless there is some bug ...) :
// add new ones to enhance the test repository.
// And feel free to add any tested device, even when the test failed !
// Tested devices capabilities :
// - Logitech G25 Racing wheel :
// * Only 1 axis => no directional 2D effect (only left and right)
// * Full support for constant force under WinXPSP2DX9 and Linux 2.6.22.9
// * Full support for periodic forces under WinXPSP2DX9
// (but poor rendering under 20ms period), and no support under Linux 2.6.22.9
// * Full support reported (not tested) for all other forces under WinXPSP2DX9,
// and no support under Linux 2.6.22.9
// - Logitech Rumble pad 2 :
// * Only 1 axis => no directional 2D effect (only left and right)
// * Forces amplitude is rendered through the inertia motors rotation frequency
// (stronger force => quicker rotation)
// * 2 inertia motors : 1 with small inertia, 1 with "heavy" one.
// => poor force feedback rendering ...
// * Support (poor) for all OIS forces under WinXPSP2DX9,
// and only for Triangle, Square and Sine periodic forces under Linux 2.6.22.9
// (reported by enumeration, but does not seem to work actually)
// Master gain setting tests:
// - Logitech G25 Racing wheel : WinXPSP2DX9=OK, Linux2.6.22.9=OK.
// - Logitech Rumble pad 2 : WinXPSP2DX9=OK, Linux2.6.22.9=OK.
// Auto-center mode setting tests:
// - Logitech G25 Racing wheel : WinXPSP2DX9=Failed (DINPUT?), Linux2.6.22.9=Reported as not supported.
// - Logitech Rumble pad 2 : WinXPSP2DX9=Failed (DINPUT?), Linux2.6.22.9=Reported as not supported.
// 1) Constant force on 1 axis with 20s-period triangle oscillations in [-10K, +10K].
// Notes: Linux: replay_length: no way to get it to work if not 0 or Effect::OIS_INFINITE
// Tested devices :
// - Logitech G25 Racing wheel : WinXPSP2DX9=OK, Linux2.6.22.9=OK.
// - Logitech Rumble pad 2 : WinXPSP2DX9=OK (but only light motor involved),
// Linux2.6.22.9=Not supported
pEffect = new Effect(Effect::ConstantForce, Effect::Constant);
pEffect->direction = Effect::North;
pEffect->trigger_button = 0;
pEffect->trigger_interval = 0;
pEffect->replay_length = Effect::OIS_INFINITE; // Linux/Win32: Same behaviour as 0.
pEffect->replay_delay = 0;
pEffect->setNumAxes(1);
pConstForce = dynamic_cast<ConstantEffect*>(pEffect->getForceEffect());
pConstForce->level = 5000; //-10K to +10k
pConstForce->envelope.attackLength = 0;
pConstForce->envelope.attackLevel = (unsigned short)pConstForce->level;
pConstForce->envelope.fadeLength = 0;
pConstForce->envelope.fadeLevel = (unsigned short)pConstForce->level;
mapVars.clear();
mapVars["Force"] =
new TriangleVariable(0.0, // F0
4*10000/_nUpdateFreq / 20.0, // dF for a 20s-period triangle
-10000.0, // Fmin
10000.0); // Fmax
mapVars["AttackFactor"] = new Constant(1.0);
_vecEffects.push_back
(new VariableEffect
("Constant force on 1 axis with 20s-period triangle oscillations "
"of its signed amplitude in [-10K, +10K]",
pEffect, mapVars, forceVariableApplier));
// 2) Constant force on 1 axis with noticeable attack
// with 20s-period triangle oscillations in [-10K, +10K].
// Tested devices :
// - Logitech G25 Racing wheel : WinXPSP2DX9=OK, Linux=OK.
// - Logitech Rumble pad 2 : WinXPSP2DX9=OK (including attack, but only light motor involved),
// Linux2.6.22.9=Not supported.
pEffect = new Effect(Effect::ConstantForce, Effect::Constant);
pEffect->direction = Effect::North;
pEffect->trigger_button = 0;
pEffect->trigger_interval = 0;
pEffect->replay_length = Effect::OIS_INFINITE; //(unsigned int)(1000000.0/_nUpdateFreq); // Linux: Does not work.
pEffect->replay_delay = 0;
pEffect->setNumAxes(1);
pConstForce = dynamic_cast<ConstantEffect*>(pEffect->getForceEffect());
pConstForce->level = 5000; //-10K to +10k
pConstForce->envelope.attackLength = (unsigned int)(1000000.0/_nUpdateFreq/2);
pConstForce->envelope.attackLevel = (unsigned short)(pConstForce->level*0.1);
pConstForce->envelope.fadeLength = 0; // Never reached, actually.
pConstForce->envelope.fadeLevel = (unsigned short)pConstForce->level; // Idem
mapVars.clear();
mapVars["Force"] =
new TriangleVariable(0.0, // F0
4*10000/_nUpdateFreq / 20.0, // dF for a 20s-period triangle
-10000.0, // Fmin
10000.0); // Fmax
mapVars["AttackFactor"] = new Constant(0.1);
_vecEffects.push_back
(new VariableEffect
("Constant force on 1 axis with noticeable attack (app update period / 2)"
"and 20s-period triangle oscillations of its signed amplitude in [-10K, +10K]",
pEffect, mapVars, forceVariableApplier));
// 3) Triangle periodic force on 1 axis with 40s-period triangle oscillations
// of its period in [10, 400] ms, and constant amplitude
// Tested devices :
// - Logitech G25 Racing wheel : WinXPSP2DX9=OK, Linux=OK.
// - Logitech Rumble pad 2 : WinXPSP2DX9=OK but only light motor involved,
// Linux2.6.22.9=Failed.
pEffect = new Effect(Effect::PeriodicForce, Effect::Triangle);
pEffect->direction = Effect::North;
pEffect->trigger_button = 0;
pEffect->trigger_interval = 0;
pEffect->replay_length = Effect::OIS_INFINITE;
pEffect->replay_delay = 0;
pEffect->setNumAxes(1);
pPeriodForce = dynamic_cast<PeriodicEffect*>(pEffect->getForceEffect());
pPeriodForce->magnitude = 10000; // 0 to +10k
pPeriodForce->offset = 0;
pPeriodForce->phase = 0; // 0 to 35599
pPeriodForce->period = 10000; // Micro-seconds
pPeriodForce->envelope.attackLength = 0;
pPeriodForce->envelope.attackLevel = (unsigned short)pPeriodForce->magnitude;
pPeriodForce->envelope.fadeLength = 0;
pPeriodForce->envelope.fadeLevel = (unsigned short)pPeriodForce->magnitude;
mapVars.clear();
mapVars["Period"] =
new TriangleVariable(1*1000.0, // P0
4*(400-10)*1000.0/_nUpdateFreq / 40.0, // dP for a 40s-period triangle
10*1000.0, // Pmin
400*1000.0); // Pmax
_vecEffects.push_back
(new VariableEffect
("Periodic force on 1 axis with 40s-period triangle oscillations "
"of its period in [10, 400] ms, and constant amplitude",
pEffect, mapVars, periodVariableApplier));
}
~EffectManager()
{
vector<VariableEffect*>::iterator iterEffs;
for (iterEffs = _vecEffects.begin(); iterEffs != _vecEffects.end(); iterEffs++)
delete *iterEffs;
}
void updateActiveEffects()
{
vector<VariableEffect*>::iterator iterEffs;
for (iterEffs = _vecEffects.begin(); iterEffs != _vecEffects.end(); iterEffs++)
if ((*iterEffs)->isActive())
{
(*iterEffs)->update();
_pJoystickMgr->getCurrentFFDevice()->modify((*iterEffs)->getFFEffect());
}
}
void checkPlayableEffects()
{
// Nothing to do if no joystick currently selected
if (!_pJoystickMgr->getCurrentFFDevice())
return;
// Get the list of indexes of effects that the selected device can play
_vecPlayableEffectInd.clear();
for (size_t nEffInd = 0; nEffInd < _vecEffects.size(); nEffInd++)
{
const Effect::EForce eForce = _vecEffects[nEffInd]->getFFEffect()->force;
const Effect::EType eType = _vecEffects[nEffInd]->getFFEffect()->type;
if (_pJoystickMgr->getCurrentFFDevice()->supportsEffect(eForce, eType))
{
_vecPlayableEffectInd.push_back(nEffInd);
}
}
// Print details about playable effects
if (_vecPlayableEffectInd.empty())
{
cout << endl << endl << "The device can't play any effect of the test set" << endl;
}
else
{
cout << endl << endl << "Selected device can play the following effects :" << endl;
for (size_t nEffIndInd = 0; nEffIndInd < _vecPlayableEffectInd.size(); nEffIndInd++)
printEffect(_vecPlayableEffectInd[nEffIndInd]);
cout << endl;
}
}
enum EWhichEffect { ePrevious=-1, eNone=0, eNext=+1 };
void selectEffect(EWhichEffect eWhich)
{
// Nothing to do if no joystick currently selected
if (!_pJoystickMgr->getCurrentFFDevice())
{
cout << "\nNo Joystick selected.\n";
return;
}
// Nothing to do if joystick cannot play any effect
if (_vecPlayableEffectInd.empty())
{
cout << "\nNo playable effects.\n";
return;
}
// If no effect selected, and next or previous requested, select the first one.
if (eWhich != eNone && _nCurrEffectInd < 0)
_nCurrEffectInd = 0;
// Otherwise, remove the current one from the device,
// and then select the requested one if any.
else if (_nCurrEffectInd >= 0)
{
_pJoystickMgr->getCurrentFFDevice()
->remove(_vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->getFFEffect());
_vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->setActive(false);
_nCurrEffectInd += eWhich;
if (_nCurrEffectInd < -1 || _nCurrEffectInd >= (int)_vecPlayableEffectInd.size())
_nCurrEffectInd = -1;
}
// If no effect must be selected, reset the selection index
if (eWhich == eNone)
{
_nCurrEffectInd = -1;
}
// Otherwise, upload the new selected effect to the device if any.
else if (_nCurrEffectInd >= 0)
{
_vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->setActive(true);
_pJoystickMgr->getCurrentFFDevice()
->upload(_vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->getFFEffect());
}
}
void printEffect(size_t nEffInd)
{
cout << "* #" << nEffInd << " : " << _vecEffects[nEffInd]->getDescription() << endl;
}
void printEffects()
{
for (size_t nEffInd = 0; nEffInd < _vecEffects.size(); nEffInd++)
printEffect(nEffInd);
}
string toString() const
{
ostringstream oss;
oss << "DevMem: " << setiosflags(ios_base::right) << setw(3);
//This causes constant exceptions with my device. Not needed for anything other than debugging
//if (_pJoystickMgr->getCurrentFFDevice())
// oss << _pJoystickMgr->getCurrentFFDevice()->getFFMemoryLoad() << "%";
//else
// oss << "----";
oss << " Effect:" << setw(2);
if (_nCurrEffectInd >= 0)
oss << _vecPlayableEffectInd[_nCurrEffectInd]
<< " " << _vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->toString();
else
oss << "--";
return oss.str();
}
};
//////////// Application class ////////////////////////////////////////////////////////
class Application
{
protected:
InputManager* _pInputMgr;
EventHandler* _pEventHdlr;
Keyboard* _pKeyboard;
JoystickManager* _pJoystickMgr;
EffectManager* _pEffectMgr;
#if defined OIS_WIN32_PLATFORM
HWND _hWnd;
#elif defined OIS_LINUX_PLATFORM
Display* _pXDisp;
Window _xWin;
#endif
bool _bMustStop;
bool _bIsInitialized;
int _nStatus;
// App. hart beat frequency.
static const unsigned int _nHartBeatFreq = 20; // Hz
// Effects update frequency (Hz) : Needs to be quite lower than app. hart beat frequency,
// if we want to be able to calmly study effect changes ...
static const unsigned int _nEffectUpdateFreq = 1; // Hz
public:
Application(int argc, const char* argv[])
{
_pInputMgr = 0;
_pEventHdlr = 0;
_pKeyboard = 0;
_pJoystickMgr = 0;
_pEffectMgr = 0;
#if defined OIS_WIN32_PLATFORM
_hWnd = 0;
#elif defined OIS_LINUX_PLATFORM
_pXDisp = 0;
_xWin = 0;
#endif
_bMustStop = false;
_bIsInitialized = false;
_nStatus = 0;
}
int initialize()
{
ostringstream wnd;
#if defined OIS_WIN32_PLATFORM
//Create a capture window for Input Grabbing
_hWnd = CreateDialog( 0, MAKEINTRESOURCE(IDD_DIALOG1), 0,(DLGPROC)DlgProc);
if( _hWnd == NULL )
OIS_EXCEPT(E_General, "Failed to create Win32 Window Dialog!");
ShowWindow(_hWnd, SW_SHOW);
wnd << (size_t)_hWnd;
#elif defined OIS_LINUX_PLATFORM
//Connects to default X window
if( !(_pXDisp = XOpenDisplay(0)) )
OIS_EXCEPT(E_General, "Error opening X!");
//Create a window
_xWin = XCreateSimpleWindow(_pXDisp,DefaultRootWindow(_pXDisp), 0,0, 100,100, 0, 0, 0);
//bind our connection to that window
XMapWindow(_pXDisp, _xWin);
//Select what events we want to listen to locally
XSelectInput(_pXDisp, _xWin, StructureNotifyMask);
//Wait for Window to show up
XEvent event;
do { XNextEvent(_pXDisp, &event); } while(event.type != MapNotify);
wnd << _xWin;
#endif
// Create OIS input manager
ParamList pl;
pl.insert(make_pair(string("WINDOW"), wnd.str()));
_pInputMgr = InputManager::createInputSystem(pl);
cout << _pInputMgr->inputSystemName() << " created." << endl;
// Create the event handler.
_pEventHdlr = new EventHandler(this);
// Create a simple keyboard
_pKeyboard = (Keyboard*)_pInputMgr->createInputObject( OISKeyboard, true );
_pKeyboard->setEventCallback( _pEventHdlr );
// Create the joystick manager.
_pJoystickMgr = new JoystickManager(_pInputMgr, _pEventHdlr);
if( !_pJoystickMgr->wasFFDetected() )
{
cout << "No Force Feedback device detected." << endl;
_nStatus = 1;
return _nStatus;
}
// Create force feedback effect manager.
_pEffectMgr = new EffectManager(_pJoystickMgr, _nEffectUpdateFreq);
// Initialize the event handler.
_pEventHdlr->initialize(_pJoystickMgr, _pEffectMgr);
_bIsInitialized = true;
return _nStatus;
}
#if defined OIS_LINUX_PLATFORM
// This is just here to show that you still receive x11 events,
// as the lib only needs mouse/key events
void checkX11Events()
{
XEvent event;
//Poll x11 for events
while( XPending(_pXDisp) > 0 )
{
XNextEvent(_pXDisp, &event);
}
}
#endif
int run()
{
const unsigned int nMaxEffectUpdateCnt = _nHartBeatFreq / _nEffectUpdateFreq;
unsigned int nEffectUpdateCnt = 0;
// Initailize app. if not already done, and exit if something went wrong.
if (!_bIsInitialized)
initialize();
if (!_bIsInitialized)
return _nStatus;
try
{
//Main polling loop
while(!_bMustStop)
{
// This fires off buffered events for keyboards
_pKeyboard->capture();
// This fires off buffered events for each joystick we have
_pJoystickMgr->captureEvents();
// Update currently selected effects if time has come to.
if (!nEffectUpdateCnt)
{
_pEffectMgr->updateActiveEffects();
nEffectUpdateCnt = nMaxEffectUpdateCnt;
}
else
nEffectUpdateCnt--;
// Update state line.
cout << "\r" << _pJoystickMgr->toString() << " " << _pEffectMgr->toString()
<< " ";
//Throttle down CPU usage & handle OS events
#if defined OIS_WIN32_PLATFORM
Sleep( (DWORD)(1000.0/_nHartBeatFreq) );
MSG msg;
while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
#elif defined OIS_LINUX_PLATFORM
checkX11Events();
usleep(1000000.0/_nHartBeatFreq);
#endif
}
}
catch( const Exception &ex )
{
#if defined OIS_WIN32_PLATFORM
MessageBox(0, ex.eText, "Exception Raised!", MB_OK);
#else
cout << endl << "OIS Exception Caught!" << endl
<< "\t" << ex.eText << "[Line " << ex.eLine << " in " << ex.eFile << "]" << endl;
#endif
}
terminate();
return _nStatus;
}
void stop()
{
_bMustStop = true;
}
void terminate()
{
if (_pInputMgr)
{
_pInputMgr->destroyInputObject( _pKeyboard );
_pKeyboard = 0;
if (_pJoystickMgr)
{
delete _pJoystickMgr;
_pJoystickMgr = 0;
}
InputManager::destroyInputSystem(_pInputMgr);
_pInputMgr = 0;
}
if (_pEffectMgr)
{
delete _pEffectMgr;
_pEffectMgr = 0;
}
if (_pEventHdlr)
{
delete _pEventHdlr;
_pEventHdlr = 0;
}
#if defined OIS_LINUX_PLATFORM
// Be nice to X and clean up the x window
XDestroyWindow(_pXDisp, _xWin);
XCloseDisplay(_pXDisp);
#endif
}
JoystickManager* getJoystickManager()
{
return _pJoystickMgr;
}
EffectManager* getEffectManager()
{
return _pEffectMgr;
}
void printHelp()
{
cout << endl
<< "Keyboard actions :" << endl
<< "* Escape : Exit App" << endl
<< "* H : This help menu" << endl
<< "* Right/Left : Select next/previous joystick among the FF capable detected ones" << endl
<< "* Up/Down : Select next/previous effect for the selected joystick" << endl
<< "* PgUp/PgDn : Increase/decrease from 5% the master gain "
<< "for all the joysticks" << endl
<< "* Space : Toggle auto-centering on all the joysticks" << endl;
if (_bIsInitialized)
{
cout << endl << "Implemented effects :" << endl << endl;
_pEffectMgr->printEffects();
cout << endl;
}
}
};
//////////// Event handler class definition ////////////////////////////////////////////////
EventHandler::EventHandler(Application* pApp)
: _pApplication(pApp)
{}
void EventHandler::initialize(JoystickManager* pJoystickMgr, EffectManager* pEffectMgr)
{
_pJoystickMgr = pJoystickMgr;
_pEffectMgr = pEffectMgr;
}
bool EventHandler::keyPressed( const KeyEvent &arg )
{
switch (arg.key)
{
// Quit.
case KC_ESCAPE:
_pApplication->stop();
break;
// Help.
case KC_H:
_pApplication->printHelp();
break;
// Change current joystick.
case KC_RIGHT:
_pEffectMgr->selectEffect(EffectManager::eNone);
_pJoystickMgr->selectJoystick(JoystickManager::eNext);
_pEffectMgr->checkPlayableEffects();
break;
case KC_LEFT:
_pEffectMgr->selectEffect(EffectManager::eNone);
_pJoystickMgr->selectJoystick(JoystickManager::ePrevious);
_pEffectMgr->checkPlayableEffects();
break;
// Change current effect.
case KC_UP:
_pEffectMgr->selectEffect(EffectManager::eNext);
break;
case KC_DOWN:
_pEffectMgr->selectEffect(EffectManager::ePrevious);
break;
// Change current master gain.
case KC_PGUP:
_pJoystickMgr->changeMasterGain(5.0); // Percent
break;
case KC_PGDOWN:
_pJoystickMgr->changeMasterGain(-5.0); // Percent
break;
// Toggle auto-center mode.
case KC_SPACE:
_pJoystickMgr->changeAutoCenter();
break;
default:
cout << "Non mapped key: " << arg.key << endl;
}
return true;
}
bool EventHandler::keyReleased( const KeyEvent &arg )
{
return true;
}
bool EventHandler::buttonPressed( const JoyStickEvent &arg, int button )
{
return true;
}
bool EventHandler::buttonReleased( const JoyStickEvent &arg, int button )
{
return true;
}
bool EventHandler::axisMoved( const JoyStickEvent &arg, int axis )
{
return true;
}
bool EventHandler::povMoved( const JoyStickEvent &arg, int pov )
{
return true;
}
//==========================================================================================
int main(int argc, const char* argv[])
{
cout << endl
<< "This is a simple command line Force Feedback testing demo ..." << endl
<< "All connected joystick devices will be created and if FF Support is found," << endl
<< "you'll be able to play some predefined variable effects on them." << endl << endl
<< "Note: 1 effect can be played on 1 joystick at a time for the moment." << endl << endl;
Application app(argc, argv);
int status = app.initialize();
if (!status)
{
app.printHelp();
status = app.run();
}
cout << endl << endl << "Exiting ..." << endl << endl;
#if defined OIS_WIN32_PLATFORM && _DEBUG
cout << "Click on this window and ..." << endl;
system("pause");
#endif
exit(status);
}
#include "OIS.h"
#include <math.h>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <ios>
#include <sstream>
#include <vector>
using namespace std;
////////////////////////////////////Needed Windows Headers////////////
#if defined OIS_WIN32_PLATFORM
# define WIN32_LEAN_AND_MEAN
# include "windows.h"
# include "resource.h"
////////////////////////////////////Needed Linux Headers//////////////
#elif defined OIS_LINUX_PLATFORM
# include <X11/Xlib.h>
#else
# error Sorry, not yet implemented on this platform.
#endif
using namespace OIS;
#if defined OIS_WIN32_PLATFORM
// The dialog proc we have to give to CreateDialog
LRESULT DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
return FALSE;
}
#endif
//////////// Event handler class declaration ////////////////////////////////////////////////
class Application;
class JoystickManager;
class EffectManager;
class EventHandler : public KeyListener, public JoyStickListener
{
protected:
Application* _pApplication;
JoystickManager* _pJoystickMgr;
EffectManager* _pEffectMgr;
public:
EventHandler(Application* pApp);
void initialize(JoystickManager* pJoystickMgr, EffectManager* pEffectMgr);
bool keyPressed( const KeyEvent &arg );
bool keyReleased( const KeyEvent &arg );
bool buttonPressed( const JoyStickEvent &arg, int button );
bool buttonReleased( const JoyStickEvent &arg, int button );
bool axisMoved( const JoyStickEvent &arg, int axis );
bool povMoved( const JoyStickEvent &arg, int pov );
};
//////////// Variable classes ////////////////////////////////////////////////////////
class Variable
{
protected:
double _dInitValue;
double _dValue;
public:
Variable(double dInitValue) : _dInitValue(dInitValue) { reset(); }
double getValue() const { return _dValue; }
void reset() { _dValue = _dInitValue; }
virtual void setValue(double dValue) { _dValue = dValue; }
virtual string toString() const
{
ostringstream oss;
oss << _dValue;
return oss.str();
}
virtual void update() {};
};
class Constant : public Variable
{
public:
Constant(double dInitValue) : Variable(dInitValue) {}
virtual void setValue(double dValue) { }
};
class LimitedVariable : public Variable
{
protected:
double _dMinValue;
double _dMaxValue;
public:
LimitedVariable(double dInitValue, double dMinValue, double dMaxValue)
: _dMinValue(dMinValue), _dMaxValue(dMaxValue), Variable(dInitValue)
{}
virtual void setValue(double dValue)
{
_dValue = dValue;
if (_dValue > _dMaxValue)
_dValue = _dMaxValue;
else if (_dValue < _dMinValue)
_dValue = _dMinValue;
}
/* virtual string toString() const
{
ostringstream oss;
oss << setiosflags(ios_base::right) << setw(4)
<< (int)(200.0 * getValue()/(_dMaxValue - _dMinValue)); // [-100%, +100%]
return oss.str();
}*/
};
class TriangleVariable : public LimitedVariable
{
protected:
double _dDeltaValue;
public:
TriangleVariable(double dInitValue, double dDeltaValue, double dMinValue, double dMaxValue)
: LimitedVariable(dInitValue, dMinValue, dMaxValue), _dDeltaValue(dDeltaValue) {};
virtual void update()
{
double dValue = getValue() + _dDeltaValue;
if (dValue > _dMaxValue)
{
dValue = _dMaxValue;
_dDeltaValue = -_dDeltaValue;
//cout << "Decreasing variable towards " << _dMinValue << endl;
}
else if (dValue < _dMinValue)
{
dValue = _dMinValue;
_dDeltaValue = -_dDeltaValue;
//cout << "Increasing variable towards " << _dMaxValue << endl;
}
setValue(dValue);
//cout << "TriangleVariable::update : delta=" << _dDeltaValue << ", value=" << dValue << endl;
}
};
//////////// Variable effect class //////////////////////////////////////////////////////////
typedef map<string, Variable*> MapVariables;
typedef void (*EffectVariablesApplier)(MapVariables& mapVars, Effect* pEffect);
class VariableEffect
{
protected:
// Effect description
const char* _pszDesc;
// The associate OIS effect
Effect* _pEffect;
// The effect variables.
MapVariables _mapVariables;
// The effect variables applier function.
EffectVariablesApplier _pfApplyVariables;
// True if the effect is currently being played.
bool _bActive;
public:
VariableEffect(const char* pszDesc, Effect* pEffect,
const MapVariables& mapVars, const EffectVariablesApplier pfApplyVars)
: _pszDesc(pszDesc), _pEffect(pEffect),
_mapVariables(mapVars), _pfApplyVariables(pfApplyVars), _bActive(false)
{}
~VariableEffect()
{
if (_pEffect)
delete _pEffect;
MapVariables::iterator iterVars;
for (iterVars = _mapVariables.begin(); iterVars != _mapVariables.end(); iterVars++)
if (iterVars->second)
delete iterVars->second;
}
void setActive(bool bActive = true)
{
reset();
_bActive = bActive;
}
bool isActive()
{
return _bActive;
}
Effect* getFFEffect()
{
return _pEffect;
}
const char* getDescription() const
{
return _pszDesc;
}
void update()
{
if (isActive())
{
// Update the variables.
MapVariables::iterator iterVars;
for (iterVars = _mapVariables.begin(); iterVars != _mapVariables.end(); iterVars++)
iterVars->second->update();
// Apply the updated variable values to the effect.
_pfApplyVariables(_mapVariables, _pEffect);
}
}
void reset()
{
MapVariables::iterator iterVars;
for (iterVars = _mapVariables.begin(); iterVars != _mapVariables.end(); iterVars++)
iterVars->second->reset();
_pfApplyVariables(_mapVariables, _pEffect);
}
string toString() const
{
string str;
MapVariables::const_iterator iterVars;
for (iterVars = _mapVariables.begin(); iterVars != _mapVariables.end(); iterVars++)
str += iterVars->first + ":" + iterVars->second->toString() + " ";
return str;
}
};
//////////// Joystick manager class ////////////////////////////////////////////////////////
class JoystickManager
{
protected:
// Input manager.
InputManager* _pInputMgr;
// Vectors to hold joysticks and associated force feedback devices
vector<JoyStick*> _vecJoys;
vector<ForceFeedback*> _vecFFDev;
// Selected joystick
int _nCurrJoyInd;
// Force feedback detected ?
bool _bFFFound;
// Selected joystick master gain.
float _dMasterGain;
// Selected joystick auto-center mode.
bool _bAutoCenter;
public:
JoystickManager(InputManager* pInputMgr, EventHandler* pEventHdlr)
: _pInputMgr(pInputMgr), _nCurrJoyInd(-1), _dMasterGain(0.5), _bAutoCenter(true)
{
_bFFFound = false;
for( int nJoyInd = 0; nJoyInd < pInputMgr->getNumberOfDevices(OISJoyStick); ++nJoyInd )
{
//Create the stick
JoyStick* pJoy = (JoyStick*)pInputMgr->createInputObject( OISJoyStick, true );
cout << endl << "Created buffered joystick #" << nJoyInd << " '" << pJoy->vendor()
<< "' (Id=" << pJoy->getID() << ")";
// Check for FF, and if so, keep the joy and dump FF info
ForceFeedback* pFFDev = (ForceFeedback*)pJoy->queryInterface(Interface::ForceFeedback );
if( pFFDev )
{
_bFFFound = true;
// Keep the joy to play with it.
pJoy->setEventCallback(pEventHdlr);
_vecJoys.push_back(pJoy);
// Keep also the associated FF device
_vecFFDev.push_back(pFFDev);
// Dump FF supported effects and other info.
cout << endl << " * Number of force feedback axes : "
<< pFFDev->getFFAxesNumber() << endl;
const ForceFeedback::SupportedEffectList &lstFFEffects =
pFFDev->getSupportedEffects();
if (lstFFEffects.size() > 0)
{
cout << " * Supported effects :";
ForceFeedback::SupportedEffectList::const_iterator itFFEff;
for(itFFEff = lstFFEffects.begin(); itFFEff != lstFFEffects.end(); ++itFFEff)
cout << " " << Effect::getEffectTypeName(itFFEff->second);
cout << endl << endl;
}
else
cout << "Warning: no supported effect found !" << endl;
}
else
{
cout << " (no force feedback support detected) => ignored." << endl << endl;
_pInputMgr->destroyInputObject(pJoy);
}
}
}
~JoystickManager()
{
for(size_t nJoyInd = 0; nJoyInd < _vecJoys.size(); ++nJoyInd)
_pInputMgr->destroyInputObject( _vecJoys[nJoyInd] );
}
size_t getNumberOfJoysticks() const
{
return _vecJoys.size();
}
bool wasFFDetected() const
{
return _bFFFound;
}
enum EWhichJoystick { ePrevious=-1, eNext=+1 };
void selectJoystick(EWhichJoystick eWhich)
{
// Note: Reset the master gain to half the maximum and autocenter mode to Off,
// when really selecting a new joystick.
if (_nCurrJoyInd < 0)
{
_nCurrJoyInd = 0;
_dMasterGain = 0.5; // Half the maximum.
changeMasterGain(0.0);
}
else
{
_nCurrJoyInd += eWhich;
if (_nCurrJoyInd < -1 || _nCurrJoyInd >= (int)_vecJoys.size())
_nCurrJoyInd = -1;
if (_vecJoys.size() > 1 && _nCurrJoyInd >= 0)
{
_dMasterGain = 0.5; // Half the maximum.
changeMasterGain(0.0);
}
}
}
ForceFeedback* getCurrentFFDevice()
{
return (_nCurrJoyInd >= 0) ? _vecFFDev[_nCurrJoyInd] : 0;
}
void changeMasterGain(float dDeltaPercent)
{
if (_nCurrJoyInd >= 0)
{
_dMasterGain += dDeltaPercent / 100;
if (_dMasterGain > 1.0)
_dMasterGain = 1.0;
else if (_dMasterGain < 0.0)
_dMasterGain = 0.0;
_vecFFDev[_nCurrJoyInd]->setMasterGain(_dMasterGain);
}
}
enum EAutoCenterHow { eOff, eOn, eToggle };
void changeAutoCenter(EAutoCenterHow eHow = eToggle)
{
if (_nCurrJoyInd >= 0)
{
if (eHow == eToggle)
_bAutoCenter = !_bAutoCenter;
else
_bAutoCenter = (eHow == eOn ? true : false);
_vecFFDev[_nCurrJoyInd]->setAutoCenterMode(_bAutoCenter);
}
}
void captureEvents()
{
// This fires off buffered events for each joystick we have
for(size_t nJoyInd = 0; nJoyInd < _vecJoys.size(); ++nJoyInd)
if( _vecJoys[nJoyInd] )
_vecJoys[nJoyInd]->capture();
}
string toString() const
{
// Warning: Wrong result if more than 10 joysticks ...
ostringstream oss;
oss << "Joy:" << (_nCurrJoyInd >= 0 ? (char)('0' + _nCurrJoyInd) : '-');
oss << " Gain:" << setiosflags(ios_base::right) << setw(3) << (int)(_dMasterGain*100);
oss << "% Center:" << (_bAutoCenter ? " On " : "Off");
return oss.str();
}
};
//////////// Effect variables applier functions /////////////////////////////////////////////
// These functions apply the given Variables to the given OIS::Effect
// Variable force "Force" + optional "AttackFactor" constant, on a OIS::ConstantEffect
void forceVariableApplier(MapVariables& mapVars, Effect* pEffect)
{
double dForce = mapVars["Force"]->getValue();
double dAttackFactor = 1.0;
if (mapVars.find("AttackFactor") != mapVars.end())
dAttackFactor = mapVars["AttackFactor"]->getValue();
ConstantEffect* pConstForce = dynamic_cast<ConstantEffect*>(pEffect->getForceEffect());
pConstForce->level = (int)dForce;
pConstForce->envelope.attackLevel = (unsigned short)fabs(dForce*dAttackFactor);
pConstForce->envelope.fadeLevel = (unsigned short)fabs(dForce); // Fade never reached, in fact.
}
// Variable "Period" on an OIS::PeriodicEffect
void periodVariableApplier(MapVariables& mapVars, Effect* pEffect)
{
double dPeriod = mapVars["Period"]->getValue();
PeriodicEffect* pPeriodForce = dynamic_cast<PeriodicEffect*>(pEffect->getForceEffect());
pPeriodForce->period = (unsigned int)dPeriod;
}
//////////// Effect manager class //////////////////////////////////////////////////////////
class EffectManager
{
protected:
// The joystick manager
JoystickManager* _pJoystickMgr;
// Vector to hold variable effects
vector<VariableEffect*> _vecEffects;
// Selected effect
int _nCurrEffectInd;
// Update frequency (Hz)
unsigned int _nUpdateFreq;
// Indexes (in _vecEffects) of the variable effects that are playable by the selected joystick.
vector<size_t> _vecPlayableEffectInd;
public:
EffectManager(JoystickManager* pJoystickMgr, unsigned int nUpdateFreq)
: _pJoystickMgr(pJoystickMgr), _nUpdateFreq(nUpdateFreq), _nCurrEffectInd(-1)
{
Effect* pEffect;
MapVariables mapVars;
ConstantEffect* pConstForce;
PeriodicEffect* pPeriodForce;
// Please don't modify or remove effects (unless there is some bug ...) :
// add new ones to enhance the test repository.
// And feel free to add any tested device, even when the test failed !
// Tested devices capabilities :
// - Logitech G25 Racing wheel :
// * Only 1 axis => no directional 2D effect (only left and right)
// * Full support for constant force under WinXPSP2DX9 and Linux 2.6.22.9
// * Full support for periodic forces under WinXPSP2DX9
// (but poor rendering under 20ms period), and no support under Linux 2.6.22.9
// * Full support reported (not tested) for all other forces under WinXPSP2DX9,
// and no support under Linux 2.6.22.9
// - Logitech Rumble pad 2 :
// * Only 1 axis => no directional 2D effect (only left and right)
// * Forces amplitude is rendered through the inertia motors rotation frequency
// (stronger force => quicker rotation)
// * 2 inertia motors : 1 with small inertia, 1 with "heavy" one.
// => poor force feedback rendering ...
// * Support (poor) for all OIS forces under WinXPSP2DX9,
// and only for Triangle, Square and Sine periodic forces under Linux 2.6.22.9
// (reported by enumeration, but does not seem to work actually)
// Master gain setting tests:
// - Logitech G25 Racing wheel : WinXPSP2DX9=OK, Linux2.6.22.9=OK.
// - Logitech Rumble pad 2 : WinXPSP2DX9=OK, Linux2.6.22.9=OK.
// Auto-center mode setting tests:
// - Logitech G25 Racing wheel : WinXPSP2DX9=Failed (DINPUT?), Linux2.6.22.9=Reported as not supported.
// - Logitech Rumble pad 2 : WinXPSP2DX9=Failed (DINPUT?), Linux2.6.22.9=Reported as not supported.
// 1) Constant force on 1 axis with 20s-period triangle oscillations in [-10K, +10K].
// Notes: Linux: replay_length: no way to get it to work if not 0 or Effect::OIS_INFINITE
// Tested devices :
// - Logitech G25 Racing wheel : WinXPSP2DX9=OK, Linux2.6.22.9=OK.
// - Logitech Rumble pad 2 : WinXPSP2DX9=OK (but only light motor involved),
// Linux2.6.22.9=Not supported
pEffect = new Effect(Effect::ConstantForce, Effect::Constant);
pEffect->direction = Effect::North;
pEffect->trigger_button = 0;
pEffect->trigger_interval = 0;
pEffect->replay_length = Effect::OIS_INFINITE; // Linux/Win32: Same behaviour as 0.
pEffect->replay_delay = 0;
pEffect->setNumAxes(1);
pConstForce = dynamic_cast<ConstantEffect*>(pEffect->getForceEffect());
pConstForce->level = 5000; //-10K to +10k
pConstForce->envelope.attackLength = 0;
pConstForce->envelope.attackLevel = (unsigned short)pConstForce->level;
pConstForce->envelope.fadeLength = 0;
pConstForce->envelope.fadeLevel = (unsigned short)pConstForce->level;
mapVars.clear();
mapVars["Force"] =
new TriangleVariable(0.0, // F0
4*10000/_nUpdateFreq / 20.0, // dF for a 20s-period triangle
-10000.0, // Fmin
10000.0); // Fmax
mapVars["AttackFactor"] = new Constant(1.0);
_vecEffects.push_back
(new VariableEffect
("Constant force on 1 axis with 20s-period triangle oscillations "
"of its signed amplitude in [-10K, +10K]",
pEffect, mapVars, forceVariableApplier));
// 2) Constant force on 1 axis with noticeable attack
// with 20s-period triangle oscillations in [-10K, +10K].
// Tested devices :
// - Logitech G25 Racing wheel : WinXPSP2DX9=OK, Linux=OK.
// - Logitech Rumble pad 2 : WinXPSP2DX9=OK (including attack, but only light motor involved),
// Linux2.6.22.9=Not supported.
pEffect = new Effect(Effect::ConstantForce, Effect::Constant);
pEffect->direction = Effect::North;
pEffect->trigger_button = 0;
pEffect->trigger_interval = 0;
pEffect->replay_length = Effect::OIS_INFINITE; //(unsigned int)(1000000.0/_nUpdateFreq); // Linux: Does not work.
pEffect->replay_delay = 0;
pEffect->setNumAxes(1);
pConstForce = dynamic_cast<ConstantEffect*>(pEffect->getForceEffect());
pConstForce->level = 5000; //-10K to +10k
pConstForce->envelope.attackLength = (unsigned int)(1000000.0/_nUpdateFreq/2);
pConstForce->envelope.attackLevel = (unsigned short)(pConstForce->level*0.1);
pConstForce->envelope.fadeLength = 0; // Never reached, actually.
pConstForce->envelope.fadeLevel = (unsigned short)pConstForce->level; // Idem
mapVars.clear();
mapVars["Force"] =
new TriangleVariable(0.0, // F0
4*10000/_nUpdateFreq / 20.0, // dF for a 20s-period triangle
-10000.0, // Fmin
10000.0); // Fmax
mapVars["AttackFactor"] = new Constant(0.1);
_vecEffects.push_back
(new VariableEffect
("Constant force on 1 axis with noticeable attack (app update period / 2)"
"and 20s-period triangle oscillations of its signed amplitude in [-10K, +10K]",
pEffect, mapVars, forceVariableApplier));
// 3) Triangle periodic force on 1 axis with 40s-period triangle oscillations
// of its period in [10, 400] ms, and constant amplitude
// Tested devices :
// - Logitech G25 Racing wheel : WinXPSP2DX9=OK, Linux=OK.
// - Logitech Rumble pad 2 : WinXPSP2DX9=OK but only light motor involved,
// Linux2.6.22.9=Failed.
pEffect = new Effect(Effect::PeriodicForce, Effect::Triangle);
pEffect->direction = Effect::North;
pEffect->trigger_button = 0;
pEffect->trigger_interval = 0;
pEffect->replay_length = Effect::OIS_INFINITE;
pEffect->replay_delay = 0;
pEffect->setNumAxes(1);
pPeriodForce = dynamic_cast<PeriodicEffect*>(pEffect->getForceEffect());
pPeriodForce->magnitude = 10000; // 0 to +10k
pPeriodForce->offset = 0;
pPeriodForce->phase = 0; // 0 to 35599
pPeriodForce->period = 10000; // Micro-seconds
pPeriodForce->envelope.attackLength = 0;
pPeriodForce->envelope.attackLevel = (unsigned short)pPeriodForce->magnitude;
pPeriodForce->envelope.fadeLength = 0;
pPeriodForce->envelope.fadeLevel = (unsigned short)pPeriodForce->magnitude;
mapVars.clear();
mapVars["Period"] =
new TriangleVariable(1*1000.0, // P0
4*(400-10)*1000.0/_nUpdateFreq / 40.0, // dP for a 40s-period triangle
10*1000.0, // Pmin
400*1000.0); // Pmax
_vecEffects.push_back
(new VariableEffect
("Periodic force on 1 axis with 40s-period triangle oscillations "
"of its period in [10, 400] ms, and constant amplitude",
pEffect, mapVars, periodVariableApplier));
}
~EffectManager()
{
vector<VariableEffect*>::iterator iterEffs;
for (iterEffs = _vecEffects.begin(); iterEffs != _vecEffects.end(); iterEffs++)
delete *iterEffs;
}
void updateActiveEffects()
{
vector<VariableEffect*>::iterator iterEffs;
for (iterEffs = _vecEffects.begin(); iterEffs != _vecEffects.end(); iterEffs++)
if ((*iterEffs)->isActive())
{
(*iterEffs)->update();
_pJoystickMgr->getCurrentFFDevice()->modify((*iterEffs)->getFFEffect());
}
}
void checkPlayableEffects()
{
// Nothing to do if no joystick currently selected
if (!_pJoystickMgr->getCurrentFFDevice())
return;
// Get the list of indexes of effects that the selected device can play
_vecPlayableEffectInd.clear();
for (size_t nEffInd = 0; nEffInd < _vecEffects.size(); nEffInd++)
{
const Effect::EForce eForce = _vecEffects[nEffInd]->getFFEffect()->force;
const Effect::EType eType = _vecEffects[nEffInd]->getFFEffect()->type;
if (_pJoystickMgr->getCurrentFFDevice()->supportsEffect(eForce, eType))
{
_vecPlayableEffectInd.push_back(nEffInd);
}
}
// Print details about playable effects
if (_vecPlayableEffectInd.empty())
{
cout << endl << endl << "The device can't play any effect of the test set" << endl;
}
else
{
cout << endl << endl << "Selected device can play the following effects :" << endl;
for (size_t nEffIndInd = 0; nEffIndInd < _vecPlayableEffectInd.size(); nEffIndInd++)
printEffect(_vecPlayableEffectInd[nEffIndInd]);
cout << endl;
}
}
enum EWhichEffect { ePrevious=-1, eNone=0, eNext=+1 };
void selectEffect(EWhichEffect eWhich)
{
// Nothing to do if no joystick currently selected
if (!_pJoystickMgr->getCurrentFFDevice())
{
cout << "\nNo Joystick selected.\n";
return;
}
// Nothing to do if joystick cannot play any effect
if (_vecPlayableEffectInd.empty())
{
cout << "\nNo playable effects.\n";
return;
}
// If no effect selected, and next or previous requested, select the first one.
if (eWhich != eNone && _nCurrEffectInd < 0)
_nCurrEffectInd = 0;
// Otherwise, remove the current one from the device,
// and then select the requested one if any.
else if (_nCurrEffectInd >= 0)
{
_pJoystickMgr->getCurrentFFDevice()
->remove(_vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->getFFEffect());
_vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->setActive(false);
_nCurrEffectInd += eWhich;
if (_nCurrEffectInd < -1 || _nCurrEffectInd >= (int)_vecPlayableEffectInd.size())
_nCurrEffectInd = -1;
}
// If no effect must be selected, reset the selection index
if (eWhich == eNone)
{
_nCurrEffectInd = -1;
}
// Otherwise, upload the new selected effect to the device if any.
else if (_nCurrEffectInd >= 0)
{
_vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->setActive(true);
_pJoystickMgr->getCurrentFFDevice()
->upload(_vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->getFFEffect());
}
}
void printEffect(size_t nEffInd)
{
cout << "* #" << nEffInd << " : " << _vecEffects[nEffInd]->getDescription() << endl;
}
void printEffects()
{
for (size_t nEffInd = 0; nEffInd < _vecEffects.size(); nEffInd++)
printEffect(nEffInd);
}
string toString() const
{
ostringstream oss;
oss << "DevMem: " << setiosflags(ios_base::right) << setw(3);
//This causes constant exceptions with my device. Not needed for anything other than debugging
//if (_pJoystickMgr->getCurrentFFDevice())
// oss << _pJoystickMgr->getCurrentFFDevice()->getFFMemoryLoad() << "%";
//else
// oss << "----";
oss << " Effect:" << setw(2);
if (_nCurrEffectInd >= 0)
oss << _vecPlayableEffectInd[_nCurrEffectInd]
<< " " << _vecEffects[_vecPlayableEffectInd[_nCurrEffectInd]]->toString();
else
oss << "--";
return oss.str();
}
};
//////////// Application class ////////////////////////////////////////////////////////
class Application
{
protected:
InputManager* _pInputMgr;
EventHandler* _pEventHdlr;
Keyboard* _pKeyboard;
JoystickManager* _pJoystickMgr;
EffectManager* _pEffectMgr;
#if defined OIS_WIN32_PLATFORM
HWND _hWnd;
#elif defined OIS_LINUX_PLATFORM
Display* _pXDisp;
Window _xWin;
#endif
bool _bMustStop;
bool _bIsInitialized;
int _nStatus;
// App. hart beat frequency.
static const unsigned int _nHartBeatFreq = 20; // Hz
// Effects update frequency (Hz) : Needs to be quite lower than app. hart beat frequency,
// if we want to be able to calmly study effect changes ...
static const unsigned int _nEffectUpdateFreq = 1; // Hz
public:
Application(int argc, const char* argv[])
{
_pInputMgr = 0;
_pEventHdlr = 0;
_pKeyboard = 0;
_pJoystickMgr = 0;
_pEffectMgr = 0;
#if defined OIS_WIN32_PLATFORM
_hWnd = 0;
#elif defined OIS_LINUX_PLATFORM
_pXDisp = 0;
_xWin = 0;
#endif
_bMustStop = false;
_bIsInitialized = false;
_nStatus = 0;
}
int initialize()
{
ostringstream wnd;
#if defined OIS_WIN32_PLATFORM
//Create a capture window for Input Grabbing
_hWnd = CreateDialog( 0, MAKEINTRESOURCE(IDD_DIALOG1), 0,(DLGPROC)DlgProc);
if( _hWnd == NULL )
OIS_EXCEPT(E_General, "Failed to create Win32 Window Dialog!");
ShowWindow(_hWnd, SW_SHOW);
wnd << (size_t)_hWnd;
#elif defined OIS_LINUX_PLATFORM
//Connects to default X window
if( !(_pXDisp = XOpenDisplay(0)) )
OIS_EXCEPT(E_General, "Error opening X!");
//Create a window
_xWin = XCreateSimpleWindow(_pXDisp,DefaultRootWindow(_pXDisp), 0,0, 100,100, 0, 0, 0);
//bind our connection to that window
XMapWindow(_pXDisp, _xWin);
//Select what events we want to listen to locally
XSelectInput(_pXDisp, _xWin, StructureNotifyMask);
//Wait for Window to show up
XEvent event;
do { XNextEvent(_pXDisp, &event); } while(event.type != MapNotify);
wnd << _xWin;
#endif
// Create OIS input manager
ParamList pl;
pl.insert(make_pair(string("WINDOW"), wnd.str()));
_pInputMgr = InputManager::createInputSystem(pl);
cout << _pInputMgr->inputSystemName() << " created." << endl;
// Create the event handler.
_pEventHdlr = new EventHandler(this);
// Create a simple keyboard
_pKeyboard = (Keyboard*)_pInputMgr->createInputObject( OISKeyboard, true );
_pKeyboard->setEventCallback( _pEventHdlr );
// Create the joystick manager.
_pJoystickMgr = new JoystickManager(_pInputMgr, _pEventHdlr);
if( !_pJoystickMgr->wasFFDetected() )
{
cout << "No Force Feedback device detected." << endl;
_nStatus = 1;
return _nStatus;
}
// Create force feedback effect manager.
_pEffectMgr = new EffectManager(_pJoystickMgr, _nEffectUpdateFreq);
// Initialize the event handler.
_pEventHdlr->initialize(_pJoystickMgr, _pEffectMgr);
_bIsInitialized = true;
return _nStatus;
}
#if defined OIS_LINUX_PLATFORM
// This is just here to show that you still receive x11 events,
// as the lib only needs mouse/key events
void checkX11Events()
{
XEvent event;
//Poll x11 for events
while( XPending(_pXDisp) > 0 )
{
XNextEvent(_pXDisp, &event);
}
}
#endif
int run()
{
const unsigned int nMaxEffectUpdateCnt = _nHartBeatFreq / _nEffectUpdateFreq;
unsigned int nEffectUpdateCnt = 0;
// Initailize app. if not already done, and exit if something went wrong.
if (!_bIsInitialized)
initialize();
if (!_bIsInitialized)
return _nStatus;
try
{
//Main polling loop
while(!_bMustStop)
{
// This fires off buffered events for keyboards
_pKeyboard->capture();
// This fires off buffered events for each joystick we have
_pJoystickMgr->captureEvents();
// Update currently selected effects if time has come to.
if (!nEffectUpdateCnt)
{
_pEffectMgr->updateActiveEffects();
nEffectUpdateCnt = nMaxEffectUpdateCnt;
}
else
nEffectUpdateCnt--;
// Update state line.
cout << "\r" << _pJoystickMgr->toString() << " " << _pEffectMgr->toString()
<< " ";
//Throttle down CPU usage & handle OS events
#if defined OIS_WIN32_PLATFORM
Sleep( (DWORD)(1000.0/_nHartBeatFreq) );
MSG msg;
while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
#elif defined OIS_LINUX_PLATFORM
checkX11Events();
usleep(1000000.0/_nHartBeatFreq);
#endif
}
}
catch( const Exception &ex )
{
#if defined OIS_WIN32_PLATFORM
MessageBox(0, ex.eText, "Exception Raised!", MB_OK);
#else
cout << endl << "OIS Exception Caught!" << endl
<< "\t" << ex.eText << "[Line " << ex.eLine << " in " << ex.eFile << "]" << endl;
#endif
}
terminate();
return _nStatus;
}
void stop()
{
_bMustStop = true;
}
void terminate()
{
if (_pInputMgr)
{
_pInputMgr->destroyInputObject( _pKeyboard );
_pKeyboard = 0;
if (_pJoystickMgr)
{
delete _pJoystickMgr;
_pJoystickMgr = 0;
}
InputManager::destroyInputSystem(_pInputMgr);
_pInputMgr = 0;
}
if (_pEffectMgr)
{
delete _pEffectMgr;
_pEffectMgr = 0;
}
if (_pEventHdlr)
{
delete _pEventHdlr;
_pEventHdlr = 0;
}
#if defined OIS_LINUX_PLATFORM
// Be nice to X and clean up the x window
XDestroyWindow(_pXDisp, _xWin);
XCloseDisplay(_pXDisp);
#endif
}
JoystickManager* getJoystickManager()
{
return _pJoystickMgr;
}
EffectManager* getEffectManager()
{
return _pEffectMgr;
}
void printHelp()
{
cout << endl
<< "Keyboard actions :" << endl
<< "* Escape : Exit App" << endl
<< "* H : This help menu" << endl
<< "* Right/Left : Select next/previous joystick among the FF capable detected ones" << endl
<< "* Up/Down : Select next/previous effect for the selected joystick" << endl
<< "* PgUp/PgDn : Increase/decrease from 5% the master gain "
<< "for all the joysticks" << endl
<< "* Space : Toggle auto-centering on all the joysticks" << endl;
if (_bIsInitialized)
{
cout << endl << "Implemented effects :" << endl << endl;
_pEffectMgr->printEffects();
cout << endl;
}
}
};
//////////// Event handler class definition ////////////////////////////////////////////////
EventHandler::EventHandler(Application* pApp)
: _pApplication(pApp)
{}
void EventHandler::initialize(JoystickManager* pJoystickMgr, EffectManager* pEffectMgr)
{
_pJoystickMgr = pJoystickMgr;
_pEffectMgr = pEffectMgr;
}
bool EventHandler::keyPressed( const KeyEvent &arg )
{
switch (arg.key)
{
// Quit.
case KC_ESCAPE:
_pApplication->stop();
break;
// Help.
case KC_H:
_pApplication->printHelp();
break;
// Change current joystick.
case KC_RIGHT:
_pEffectMgr->selectEffect(EffectManager::eNone);
_pJoystickMgr->selectJoystick(JoystickManager::eNext);
_pEffectMgr->checkPlayableEffects();
break;
case KC_LEFT:
_pEffectMgr->selectEffect(EffectManager::eNone);
_pJoystickMgr->selectJoystick(JoystickManager::ePrevious);
_pEffectMgr->checkPlayableEffects();
break;
// Change current effect.
case KC_UP:
_pEffectMgr->selectEffect(EffectManager::eNext);
break;
case KC_DOWN:
_pEffectMgr->selectEffect(EffectManager::ePrevious);
break;
// Change current master gain.
case KC_PGUP:
_pJoystickMgr->changeMasterGain(5.0); // Percent
break;
case KC_PGDOWN:
_pJoystickMgr->changeMasterGain(-5.0); // Percent
break;
// Toggle auto-center mode.
case KC_SPACE:
_pJoystickMgr->changeAutoCenter();
break;
default:
cout << "Non mapped key: " << arg.key << endl;
}
return true;
}
bool EventHandler::keyReleased( const KeyEvent &arg )
{
return true;
}
bool EventHandler::buttonPressed( const JoyStickEvent &arg, int button )
{
return true;
}
bool EventHandler::buttonReleased( const JoyStickEvent &arg, int button )
{
return true;
}
bool EventHandler::axisMoved( const JoyStickEvent &arg, int axis )
{
return true;
}
bool EventHandler::povMoved( const JoyStickEvent &arg, int pov )
{
return true;
}
//==========================================================================================
int main(int argc, const char* argv[])
{
cout << endl
<< "This is a simple command line Force Feedback testing demo ..." << endl
<< "All connected joystick devices will be created and if FF Support is found," << endl
<< "you'll be able to play some predefined variable effects on them." << endl << endl
<< "Note: 1 effect can be played on 1 joystick at a time for the moment." << endl << endl;
Application app(argc, argv);
int status = app.initialize();
if (!status)
{
app.printHelp();
status = app.run();
}
cout << endl << endl << "Exiting ..." << endl << endl;
#if defined OIS_WIN32_PLATFORM && _DEBUG
cout << "Click on this window and ..." << endl;
system("pause");
#endif
exit(status);
}
INCLUDES = $(STLPORT_CFLAGS) -I$(top_srcdir)/includes $(CFLAGS) -I/usr/X11R6/include
noinst_PROGRAMS = ConsoleApp FFConsoleTest
ConsoleApp_SOURCES = OISConsole.cpp
ConsoleApp_LDFLAGS = -L$(top_builddir)/src
ConsoleApp_LDADD = -lOIS
FFConsoleTest_SOURCES = FFConsoleDemo.cpp
FFConsoleTest_LDFLAGS = -L$(top_builddir)/src
FFConsoleTest_LDADD = -lOIS
INCLUDES = $(STLPORT_CFLAGS) -I$(top_srcdir)/includes $(CFLAGS) -I/usr/X11R6/include
noinst_PROGRAMS = ConsoleApp FFConsoleTest
ConsoleApp_SOURCES = OISConsole.cpp
ConsoleApp_LDFLAGS = -L$(top_builddir)/src
ConsoleApp_LDADD = -lOIS
FFConsoleTest_SOURCES = FFConsoleDemo.cpp
FFConsoleTest_LDFLAGS = -L$(top_builddir)/src
FFConsoleTest_LDADD = -lOIS
//////////////////////////////// OS Nuetral Headers ////////////////
#include "OISInputManager.h"
#include "OISException.h"
#include "OISKeyboard.h"
#include "OISMouse.h"
#include "OISJoyStick.h"
#include "OISEvents.h"
//Advanced Usage
#include "OISForceFeedback.h"
#include <iostream>
#include <vector>
#include <sstream>
////////////////////////////////////Needed Windows Headers////////////
#if defined OIS_WIN32_PLATFORM
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#ifdef min
#undef min
#endif
#include "resource.h"
LRESULT DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
//////////////////////////////////////////////////////////////////////
////////////////////////////////////Needed Linux Headers//////////////
#elif defined OIS_LINUX_PLATFORM
#include <X11/Xlib.h>
#include <X11/Xatom.h>
void checkX11Events();
//////////////////////////////////////////////////////////////////////
////////////////////////////////////Needed Mac Headers//////////////
#elif defined OIS_APPLE_PLATFORM
#include <Carbon/Carbon.h>
void checkMacEvents();
#endif
//////////////////////////////////////////////////////////////////////
using namespace OIS;
//-- Some local prototypes --//
void doStartup();
void handleNonBufferedKeys();
void handleNonBufferedMouse();
void handleNonBufferedJoy( JoyStick* js );
//-- Easy access globals --//
bool appRunning = true; //Global Exit Flag
const char *g_DeviceType[6] = {"OISUnknown", "OISKeyboard", "OISMouse", "OISJoyStick",
"OISTablet", "OISOther"};
InputManager *g_InputManager = 0; //Our Input System
Keyboard *g_kb = 0; //Keyboard Device
Mouse *g_m = 0; //Mouse Device
JoyStick* g_joys[4] = {0,0,0,0}; //This demo supports up to 4 controllers
//-- OS Specific Globals --//
#if defined OIS_WIN32_PLATFORM
HWND hWnd = 0;
#elif defined OIS_LINUX_PLATFORM
Display *xDisp = 0;
Window xWin = 0;
#elif defined OIS_APPLE_PLATFORM
WindowRef mWin = 0;
#endif
//////////// Common Event handler class ////////
class EventHandler : public KeyListener, public MouseListener, public JoyStickListener
{
public:
EventHandler() {}
~EventHandler() {}
bool keyPressed( const KeyEvent &arg ) {
std::cout << " KeyPressed {" << arg.key
<< ", " << ((Keyboard*)(arg.device))->getAsString(arg.key)
<< "} || Character (" << (char)arg.text << ")" << std::endl;
return true;
}
bool keyReleased( const KeyEvent &arg ) {
if( arg.key == KC_ESCAPE || arg.key == KC_Q )
appRunning = false;
std::cout << "KeyReleased {" << ((Keyboard*)(arg.device))->getAsString(arg.key) << "}\n";
return true;
}
bool mouseMoved( const MouseEvent &arg ) {
const OIS::MouseState& s = arg.state;
std::cout << "\nMouseMoved: Abs("
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
return true;
}
bool mousePressed( const MouseEvent &arg, MouseButtonID id ) {
const OIS::MouseState& s = arg.state;
std::cout << "\nMouse button #" << id << " pressed. Abs("
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
return true;
}
bool mouseReleased( const MouseEvent &arg, MouseButtonID id ) {
const OIS::MouseState& s = arg.state;
std::cout << "\nMouse button #" << id << " released. Abs("
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
return true;
}
bool buttonPressed( const JoyStickEvent &arg, int button ) {
std::cout << std::endl << arg.device->vendor() << ". Button Pressed # " << button;
return true;
}
bool buttonReleased( const JoyStickEvent &arg, int button ) {
std::cout << std::endl << arg.device->vendor() << ". Button Released # " << button;
return true;
}
bool axisMoved( const JoyStickEvent &arg, int axis )
{
//Provide a little dead zone
if( arg.state.mAxes[axis].abs > 2500 || arg.state.mAxes[axis].abs < -2500 )
std::cout << std::endl << arg.device->vendor() << ". Axis # " << axis << " Value: " << arg.state.mAxes[axis].abs;
return true;
}
bool povMoved( const JoyStickEvent &arg, int pov )
{
std::cout << std::endl << arg.device->vendor() << ". POV" << pov << " ";
if( arg.state.mPOV[pov].direction & Pov::North ) //Going up
std::cout << "North";
else if( arg.state.mPOV[pov].direction & Pov::South ) //Going down
std::cout << "South";
if( arg.state.mPOV[pov].direction & Pov::East ) //Going right
std::cout << "East";
else if( arg.state.mPOV[pov].direction & Pov::West ) //Going left
std::cout << "West";
if( arg.state.mPOV[pov].direction == Pov::Centered ) //stopped/centered out
std::cout << "Centered";
return true;
}
bool vector3Moved( const JoyStickEvent &arg, int index)
{
std::cout.precision(2);
std::cout.flags(std::ios::fixed | std::ios::right);
std::cout << std::endl << arg.device->vendor() << ". Orientation # " << index
<< " X Value: " << arg.state.mVectors[index].x
<< " Y Value: " << arg.state.mVectors[index].y
<< " Z Value: " << arg.state.mVectors[index].z;
std::cout.precision();
std::cout.flags();
return true;
}
};
//Create a global instance
EventHandler handler;
int main()
{
std::cout << "\n\n*** OIS Console Demo App is starting up... *** \n";
try
{
doStartup();
std::cout << "\nStartup done... Hit 'q' or ESC to exit.\n\n";
while(appRunning)
{
//Throttle down CPU usage
#if defined OIS_WIN32_PLATFORM
Sleep(90);
MSG msg;
while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
#elif defined OIS_LINUX_PLATFORM
checkX11Events();
usleep( 500 );
#elif defined OIS_APPLE_PLATFORM
checkMacEvents();
usleep( 500 );
#endif
if( g_kb )
{
g_kb->capture();
if( !g_kb->buffered() )
handleNonBufferedKeys();
}
if( g_m )
{
g_m->capture();
if( !g_m->buffered() )
handleNonBufferedMouse();
}
for( int i = 0; i < 4 ; ++i )
{
if( g_joys[i] )
{
g_joys[i]->capture();
if( !g_joys[i]->buffered() )
handleNonBufferedJoy( g_joys[i] );
}
}
}
}
catch( const Exception &ex )
{
#if defined OIS_WIN32_PLATFORM
MessageBox( NULL, ex.eText, "An exception has occurred!", MB_OK |
MB_ICONERROR | MB_TASKMODAL);
#else
std::cout << "\nOIS Exception Caught!\n" << "\t" << ex.eText << "[Line "
<< ex.eLine << " in " << ex.eFile << "]\nExiting App";
#endif
}
catch(std::exception &ex)
{
std::cout << "Caught std::exception: what = " << ex.what() << std::endl;
}
//Destroying the manager will cleanup unfreed devices
std::cout << "Cleaning up...\n";
if( g_InputManager )
InputManager::destroyInputSystem(g_InputManager);
#if defined OIS_LINUX_PLATFORM
// Be nice to X and clean up the x window
XDestroyWindow(xDisp, xWin);
XCloseDisplay(xDisp);
#endif
std::cout << "\nGoodbye!\n";
return 0;
}
void doStartup()
{
ParamList pl;
#if defined OIS_WIN32_PLATFORM
//Create a capture window for Input Grabbing
hWnd = CreateDialog( 0, MAKEINTRESOURCE(IDD_DIALOG1), 0,(DLGPROC)DlgProc);
if( hWnd == NULL )
OIS_EXCEPT(E_General, "Failed to create Win32 Window Dialog!");
ShowWindow(hWnd, SW_SHOW);
std::ostringstream wnd;
wnd << (size_t)hWnd;
pl.insert(std::make_pair( std::string("WINDOW"), wnd.str() ));
//Default mode is foreground exclusive..but, we want to show mouse - so nonexclusive
// pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
// pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
#elif defined OIS_LINUX_PLATFORM
//Connects to default X window
if( !(xDisp = XOpenDisplay(0)) )
OIS_EXCEPT(E_General, "Error opening X!");
//Create a window
xWin = XCreateSimpleWindow(xDisp, DefaultRootWindow(xDisp), 0, 0, 100, 100, 0, 0, 0);
//bind our connection to that window
XMapWindow(xDisp, xWin);
// XInternAtom
//Select what events we want to listen to locally
XSelectInput(xDisp, xWin, StructureNotifyMask | SubstructureNotifyMask);
Atom wmProto = XInternAtom(xDisp, "WM_PROTOCOLS", False);
Atom wmDelete = XInternAtom(xDisp, "WM_DELETE_WINDOW", False);
XChangeProperty(xDisp, xWin, wmProto, XA_ATOM, 32, 0, (const unsigned char*)&wmDelete, 1);
XEvent evtent;
do
{
XNextEvent(xDisp, &evtent);
} while(evtent.type != MapNotify);
std::ostringstream wnd;
wnd << xWin;
pl.insert(std::make_pair(std::string("WINDOW"), wnd.str()));
//For this demo, show mouse and do not grab (confine to window)
// pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
// pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
#elif defined OIS_APPLE_PLATFORM
// create the window rect in global coords
::Rect windowRect;
windowRect.left = 0;
windowRect.top = 0;
windowRect.right = 300;
windowRect.bottom = 300;
// set the default attributes for the window
WindowAttributes windowAttrs = kWindowStandardDocumentAttributes
| kWindowStandardHandlerAttribute
| kWindowInWindowMenuAttribute
| kWindowHideOnFullScreenAttribute;
// Create the window
CreateNewWindow(kDocumentWindowClass, windowAttrs, &windowRect, &mWin);
// Color the window background black
SetThemeWindowBackground (mWin, kThemeBrushBlack, true);
// Set the title of our window
CFStringRef titleRef = CFStringCreateWithCString( kCFAllocatorDefault, "OIS Input", kCFStringEncodingASCII );
SetWindowTitleWithCFString( mWin, titleRef );
// Center our window on the screen
RepositionWindow( mWin, NULL, kWindowCenterOnMainScreen );
// Install the event handler for the window
InstallStandardEventHandler(GetWindowEventTarget(mWin));
// This will give our window focus, and not lock it to the terminal
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType( &psn, kProcessTransformToForegroundApplication );
SetFrontProcess(&psn);
// Display and select our window
ShowWindow(mWin);
SelectWindow(mWin);
std::ostringstream wnd;
wnd << (unsigned int)mWin; //cast to int so it gets encoded correctly (else it gets stored as a hex string)
std::cout << "WindowRef: " << mWin << " WindowRef as int: " << wnd.str() << "\n";
pl.insert(std::make_pair(std::string("WINDOW"), wnd.str()));
#endif
//This never returns null.. it will raise an exception on errors
g_InputManager = InputManager::createInputSystem(pl);
//Lets enable all addons that were compiled in:
g_InputManager->enableAddOnFactory(InputManager::AddOn_All);
//Print debugging information
unsigned int v = g_InputManager->getVersionNumber();
std::cout << "OIS Version: " << (v>>16 ) << "." << ((v>>8) & 0x000000FF) << "." << (v & 0x000000FF)
<< "\nRelease Name: " << g_InputManager->getVersionName()
<< "\nManager: " << g_InputManager->inputSystemName()
<< "\nTotal Keyboards: " << g_InputManager->getNumberOfDevices(OISKeyboard)
<< "\nTotal Mice: " << g_InputManager->getNumberOfDevices(OISMouse)
<< "\nTotal JoySticks: " << g_InputManager->getNumberOfDevices(OISJoyStick);
//List all devices
DeviceList list = g_InputManager->listFreeDevices();
for( DeviceList::iterator i = list.begin(); i != list.end(); ++i )
std::cout << "\n\tDevice: " << g_DeviceType[i->first] << " Vendor: " << i->second;
g_kb = (Keyboard*)g_InputManager->createInputObject( OISKeyboard, true );
g_kb->setEventCallback( &handler );
g_m = (Mouse*)g_InputManager->createInputObject( OISMouse, true );
g_m->setEventCallback( &handler );
const MouseState &ms = g_m->getMouseState();
ms.width = 100;
ms.height = 100;
try
{
//This demo uses at most 4 joysticks - use old way to create (i.e. disregard vendor)
int numSticks = std::min(g_InputManager->getNumberOfDevices(OISJoyStick), 4);
for( int i = 0; i < numSticks; ++i )
{
g_joys[i] = (JoyStick*)g_InputManager->createInputObject( OISJoyStick, true );
g_joys[i]->setEventCallback( &handler );
std::cout << "\n\nCreating Joystick " << (i + 1)
<< "\n\tAxes: " << g_joys[i]->getNumberOfComponents(OIS_Axis)
<< "\n\tSliders: " << g_joys[i]->getNumberOfComponents(OIS_Slider)
<< "\n\tPOV/HATs: " << g_joys[i]->getNumberOfComponents(OIS_POV)
<< "\n\tButtons: " << g_joys[i]->getNumberOfComponents(OIS_Button)
<< "\n\tVector3: " << g_joys[i]->getNumberOfComponents(OIS_Vector3);
}
}
catch(OIS::Exception &ex)
{
std::cout << "\nException raised on joystick creation: " << ex.eText << std::endl;
}
}
void handleNonBufferedKeys()
{
if( g_kb->isKeyDown( KC_ESCAPE ) || g_kb->isKeyDown( KC_Q ) )
appRunning = false;
if( g_kb->isModifierDown(Keyboard::Shift) )
std::cout << "Shift is down..\n";
if( g_kb->isModifierDown(Keyboard::Alt) )
std::cout << "Alt is down..\n";
if( g_kb->isModifierDown(Keyboard::Ctrl) )
std::cout << "Ctrl is down..\n";
}
void handleNonBufferedMouse()
{
//Just dump the current mouse state
const MouseState &ms = g_m->getMouseState();
std::cout << "\nMouse: Abs(" << ms.X.abs << " " << ms.Y.abs << " " << ms.Z.abs
<< ") B: " << ms.buttons << " Rel(" << ms.X.rel << " " << ms.Y.rel << " " << ms.Z.rel << ")";
}
void handleNonBufferedJoy( JoyStick* js )
{
//Just dump the current joy state
const JoyStickState &joy = js->getJoyStickState();
for( unsigned int i = 0; i < joy.mAxes.size(); ++i )
std::cout << "\nAxis " << i << " X: " << joy.mAxes[i].abs;
}
#if defined OIS_WIN32_PLATFORM
LRESULT DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
return FALSE;
}
#endif
#if defined OIS_LINUX_PLATFORM
//This is just here to show that you still recieve x11 events, as the lib only needs mouse/key events
void checkX11Events()
{
if(!appRunning)
return;
XEvent event;
while(XPending(xDisp) > 0)
{
XNextEvent(xDisp, &event);
//Handle Resize events
if(event.type == ConfigureNotify)
{
if(g_m)
{
const MouseState &ms = g_m->getMouseState();
ms.width = event.xconfigure.width;
ms.height = event.xconfigure.height;
}
}
else if(event.type == ClientMessage || event.type == DestroyNotify)
{ // We only get DestroyNotify for child windows. However, we regeistered earlier to receive WM_DELETE_MESSAGEs
std::cout << "Exiting...\n";
appRunning = false;
return;
}
else
{
std::cout << "\nUnknown X Event: " << event.type << std::endl;
}
}
}
#endif
#if defined OIS_APPLE_PLATFORM
void checkMacEvents()
{
//TODO - Check for window resize events, and then adjust the members of mousestate
EventRef event = NULL;
EventTargetRef targetWindow = GetEventDispatcherTarget();
if( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr )
{
SendEventToEventTarget(event, targetWindow);
std::cout << "Event : " << GetEventKind(event) << "\n";
ReleaseEvent(event);
}
}
#endif
//////////////////////////////// OS Nuetral Headers ////////////////
#include "OISInputManager.h"
#include "OISException.h"
#include "OISKeyboard.h"
#include "OISMouse.h"
#include "OISJoyStick.h"
#include "OISEvents.h"
//Advanced Usage
#include "OISForceFeedback.h"
#include <iostream>
#include <vector>
#include <sstream>
////////////////////////////////////Needed Windows Headers////////////
#if defined OIS_WIN32_PLATFORM
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#ifdef min
#undef min
#endif
#include "resource.h"
LRESULT DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
//////////////////////////////////////////////////////////////////////
////////////////////////////////////Needed Linux Headers//////////////
#elif defined OIS_LINUX_PLATFORM
#include <X11/Xlib.h>
#include <X11/Xatom.h>
void checkX11Events();
//////////////////////////////////////////////////////////////////////
////////////////////////////////////Needed Mac Headers//////////////
#elif defined OIS_APPLE_PLATFORM
#include <Carbon/Carbon.h>
void checkMacEvents();
#endif
//////////////////////////////////////////////////////////////////////
using namespace OIS;
//-- Some local prototypes --//
void doStartup();
void handleNonBufferedKeys();
void handleNonBufferedMouse();
void handleNonBufferedJoy( JoyStick* js );
//-- Easy access globals --//
bool appRunning = true; //Global Exit Flag
const char *g_DeviceType[6] = {"OISUnknown", "OISKeyboard", "OISMouse", "OISJoyStick",
"OISTablet", "OISOther"};
InputManager *g_InputManager = 0; //Our Input System
Keyboard *g_kb = 0; //Keyboard Device
Mouse *g_m = 0; //Mouse Device
JoyStick* g_joys[4] = {0,0,0,0}; //This demo supports up to 4 controllers
//-- OS Specific Globals --//
#if defined OIS_WIN32_PLATFORM
HWND hWnd = 0;
#elif defined OIS_LINUX_PLATFORM
Display *xDisp = 0;
Window xWin = 0;
#elif defined OIS_APPLE_PLATFORM
WindowRef mWin = 0;
#endif
//////////// Common Event handler class ////////
class EventHandler : public KeyListener, public MouseListener, public JoyStickListener
{
public:
EventHandler() {}
~EventHandler() {}
bool keyPressed( const KeyEvent &arg ) {
std::cout << " KeyPressed {" << arg.key
<< ", " << ((Keyboard*)(arg.device))->getAsString(arg.key)
<< "} || Character (" << (char)arg.text << ")" << std::endl;
return true;
}
bool keyReleased( const KeyEvent &arg ) {
if( arg.key == KC_ESCAPE || arg.key == KC_Q )
appRunning = false;
std::cout << "KeyReleased {" << ((Keyboard*)(arg.device))->getAsString(arg.key) << "}\n";
return true;
}
bool mouseMoved( const MouseEvent &arg ) {
const OIS::MouseState& s = arg.state;
std::cout << "\nMouseMoved: Abs("
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
return true;
}
bool mousePressed( const MouseEvent &arg, MouseButtonID id ) {
const OIS::MouseState& s = arg.state;
std::cout << "\nMouse button #" << id << " pressed. Abs("
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
return true;
}
bool mouseReleased( const MouseEvent &arg, MouseButtonID id ) {
const OIS::MouseState& s = arg.state;
std::cout << "\nMouse button #" << id << " released. Abs("
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
return true;
}
bool buttonPressed( const JoyStickEvent &arg, int button ) {
std::cout << std::endl << arg.device->vendor() << ". Button Pressed # " << button;
return true;
}
bool buttonReleased( const JoyStickEvent &arg, int button ) {
std::cout << std::endl << arg.device->vendor() << ". Button Released # " << button;
return true;
}
bool axisMoved( const JoyStickEvent &arg, int axis )
{
//Provide a little dead zone
if( arg.state.mAxes[axis].abs > 2500 || arg.state.mAxes[axis].abs < -2500 )
std::cout << std::endl << arg.device->vendor() << ". Axis # " << axis << " Value: " << arg.state.mAxes[axis].abs;
return true;
}
bool povMoved( const JoyStickEvent &arg, int pov )
{
std::cout << std::endl << arg.device->vendor() << ". POV" << pov << " ";
if( arg.state.mPOV[pov].direction & Pov::North ) //Going up
std::cout << "North";
else if( arg.state.mPOV[pov].direction & Pov::South ) //Going down
std::cout << "South";
if( arg.state.mPOV[pov].direction & Pov::East ) //Going right
std::cout << "East";
else if( arg.state.mPOV[pov].direction & Pov::West ) //Going left
std::cout << "West";
if( arg.state.mPOV[pov].direction == Pov::Centered ) //stopped/centered out
std::cout << "Centered";
return true;
}
bool vector3Moved( const JoyStickEvent &arg, int index)
{
std::cout.precision(2);
std::cout.flags(std::ios::fixed | std::ios::right);
std::cout << std::endl << arg.device->vendor() << ". Orientation # " << index
<< " X Value: " << arg.state.mVectors[index].x
<< " Y Value: " << arg.state.mVectors[index].y
<< " Z Value: " << arg.state.mVectors[index].z;
std::cout.precision();
std::cout.flags();
return true;
}
};
//Create a global instance
EventHandler handler;
int main()
{
std::cout << "\n\n*** OIS Console Demo App is starting up... *** \n";
try
{
doStartup();
std::cout << "\nStartup done... Hit 'q' or ESC to exit.\n\n";
while(appRunning)
{
//Throttle down CPU usage
#if defined OIS_WIN32_PLATFORM
Sleep(90);
MSG msg;
while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
#elif defined OIS_LINUX_PLATFORM
checkX11Events();
usleep( 500 );
#elif defined OIS_APPLE_PLATFORM
checkMacEvents();
usleep( 500 );
#endif
if( g_kb )
{
g_kb->capture();
if( !g_kb->buffered() )
handleNonBufferedKeys();
}
if( g_m )
{
g_m->capture();
if( !g_m->buffered() )
handleNonBufferedMouse();
}
for( int i = 0; i < 4 ; ++i )
{
if( g_joys[i] )
{
g_joys[i]->capture();
if( !g_joys[i]->buffered() )
handleNonBufferedJoy( g_joys[i] );
}
}
}
}
catch( const Exception &ex )
{
#if defined OIS_WIN32_PLATFORM
MessageBox( NULL, ex.eText, "An exception has occurred!", MB_OK |
MB_ICONERROR | MB_TASKMODAL);
#else
std::cout << "\nOIS Exception Caught!\n" << "\t" << ex.eText << "[Line "
<< ex.eLine << " in " << ex.eFile << "]\nExiting App";
#endif
}
catch(std::exception &ex)
{
std::cout << "Caught std::exception: what = " << ex.what() << std::endl;
}
//Destroying the manager will cleanup unfreed devices
std::cout << "Cleaning up...\n";
if( g_InputManager )
InputManager::destroyInputSystem(g_InputManager);
#if defined OIS_LINUX_PLATFORM
// Be nice to X and clean up the x window
XDestroyWindow(xDisp, xWin);
XCloseDisplay(xDisp);
#endif
std::cout << "\nGoodbye!\n";
return 0;
}
void doStartup()
{
ParamList pl;
#if defined OIS_WIN32_PLATFORM
//Create a capture window for Input Grabbing
hWnd = CreateDialog( 0, MAKEINTRESOURCE(IDD_DIALOG1), 0,(DLGPROC)DlgProc);
if( hWnd == NULL )
OIS_EXCEPT(E_General, "Failed to create Win32 Window Dialog!");
ShowWindow(hWnd, SW_SHOW);
std::ostringstream wnd;
wnd << (size_t)hWnd;
pl.insert(std::make_pair( std::string("WINDOW"), wnd.str() ));
//Default mode is foreground exclusive..but, we want to show mouse - so nonexclusive
// pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
// pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
#elif defined OIS_LINUX_PLATFORM
//Connects to default X window
if( !(xDisp = XOpenDisplay(0)) )
OIS_EXCEPT(E_General, "Error opening X!");
//Create a window
xWin = XCreateSimpleWindow(xDisp, DefaultRootWindow(xDisp), 0, 0, 100, 100, 0, 0, 0);
//bind our connection to that window
XMapWindow(xDisp, xWin);
// XInternAtom
//Select what events we want to listen to locally
XSelectInput(xDisp, xWin, StructureNotifyMask | SubstructureNotifyMask);
Atom wmProto = XInternAtom(xDisp, "WM_PROTOCOLS", False);
Atom wmDelete = XInternAtom(xDisp, "WM_DELETE_WINDOW", False);
XChangeProperty(xDisp, xWin, wmProto, XA_ATOM, 32, 0, (const unsigned char*)&wmDelete, 1);
XEvent evtent;
do
{
XNextEvent(xDisp, &evtent);
} while(evtent.type != MapNotify);
std::ostringstream wnd;
wnd << xWin;
pl.insert(std::make_pair(std::string("WINDOW"), wnd.str()));
//For this demo, show mouse and do not grab (confine to window)
// pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
// pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
#elif defined OIS_APPLE_PLATFORM
// create the window rect in global coords
::Rect windowRect;
windowRect.left = 0;
windowRect.top = 0;
windowRect.right = 300;
windowRect.bottom = 300;
// set the default attributes for the window
WindowAttributes windowAttrs = kWindowStandardDocumentAttributes
| kWindowStandardHandlerAttribute
| kWindowInWindowMenuAttribute
| kWindowHideOnFullScreenAttribute;
// Create the window
CreateNewWindow(kDocumentWindowClass, windowAttrs, &windowRect, &mWin);
// Color the window background black
SetThemeWindowBackground (mWin, kThemeBrushBlack, true);
// Set the title of our window
CFStringRef titleRef = CFStringCreateWithCString( kCFAllocatorDefault, "OIS Input", kCFStringEncodingASCII );
SetWindowTitleWithCFString( mWin, titleRef );
// Center our window on the screen
RepositionWindow( mWin, NULL, kWindowCenterOnMainScreen );
// Install the event handler for the window
InstallStandardEventHandler(GetWindowEventTarget(mWin));
// This will give our window focus, and not lock it to the terminal
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType( &psn, kProcessTransformToForegroundApplication );
SetFrontProcess(&psn);
// Display and select our window
ShowWindow(mWin);
SelectWindow(mWin);
std::ostringstream wnd;
wnd << (unsigned int)mWin; //cast to int so it gets encoded correctly (else it gets stored as a hex string)
std::cout << "WindowRef: " << mWin << " WindowRef as int: " << wnd.str() << "\n";
pl.insert(std::make_pair(std::string("WINDOW"), wnd.str()));
#endif
//This never returns null.. it will raise an exception on errors
g_InputManager = InputManager::createInputSystem(pl);
//Lets enable all addons that were compiled in:
g_InputManager->enableAddOnFactory(InputManager::AddOn_All);
//Print debugging information
unsigned int v = g_InputManager->getVersionNumber();
std::cout << "OIS Version: " << (v>>16 ) << "." << ((v>>8) & 0x000000FF) << "." << (v & 0x000000FF)
<< "\nRelease Name: " << g_InputManager->getVersionName()
<< "\nManager: " << g_InputManager->inputSystemName()
<< "\nTotal Keyboards: " << g_InputManager->getNumberOfDevices(OISKeyboard)
<< "\nTotal Mice: " << g_InputManager->getNumberOfDevices(OISMouse)
<< "\nTotal JoySticks: " << g_InputManager->getNumberOfDevices(OISJoyStick);
//List all devices
DeviceList list = g_InputManager->listFreeDevices();
for( DeviceList::iterator i = list.begin(); i != list.end(); ++i )
std::cout << "\n\tDevice: " << g_DeviceType[i->first] << " Vendor: " << i->second;
g_kb = (Keyboard*)g_InputManager->createInputObject( OISKeyboard, true );
g_kb->setEventCallback( &handler );
g_m = (Mouse*)g_InputManager->createInputObject( OISMouse, true );
g_m->setEventCallback( &handler );
const MouseState &ms = g_m->getMouseState();
ms.width = 100;
ms.height = 100;
try
{
//This demo uses at most 4 joysticks - use old way to create (i.e. disregard vendor)
int numSticks = std::min(g_InputManager->getNumberOfDevices(OISJoyStick), 4);
for( int i = 0; i < numSticks; ++i )
{
g_joys[i] = (JoyStick*)g_InputManager->createInputObject( OISJoyStick, true );
g_joys[i]->setEventCallback( &handler );
std::cout << "\n\nCreating Joystick " << (i + 1)
<< "\n\tAxes: " << g_joys[i]->getNumberOfComponents(OIS_Axis)
<< "\n\tSliders: " << g_joys[i]->getNumberOfComponents(OIS_Slider)
<< "\n\tPOV/HATs: " << g_joys[i]->getNumberOfComponents(OIS_POV)
<< "\n\tButtons: " << g_joys[i]->getNumberOfComponents(OIS_Button)
<< "\n\tVector3: " << g_joys[i]->getNumberOfComponents(OIS_Vector3);
}
}
catch(OIS::Exception &ex)
{
std::cout << "\nException raised on joystick creation: " << ex.eText << std::endl;
}
}
void handleNonBufferedKeys()
{
if( g_kb->isKeyDown( KC_ESCAPE ) || g_kb->isKeyDown( KC_Q ) )
appRunning = false;
if( g_kb->isModifierDown(Keyboard::Shift) )
std::cout << "Shift is down..\n";
if( g_kb->isModifierDown(Keyboard::Alt) )
std::cout << "Alt is down..\n";
if( g_kb->isModifierDown(Keyboard::Ctrl) )
std::cout << "Ctrl is down..\n";
}
void handleNonBufferedMouse()
{
//Just dump the current mouse state
const MouseState &ms = g_m->getMouseState();
std::cout << "\nMouse: Abs(" << ms.X.abs << " " << ms.Y.abs << " " << ms.Z.abs
<< ") B: " << ms.buttons << " Rel(" << ms.X.rel << " " << ms.Y.rel << " " << ms.Z.rel << ")";
}
void handleNonBufferedJoy( JoyStick* js )
{
//Just dump the current joy state
const JoyStickState &joy = js->getJoyStickState();
for( unsigned int i = 0; i < joy.mAxes.size(); ++i )
std::cout << "\nAxis " << i << " X: " << joy.mAxes[i].abs;
}
#if defined OIS_WIN32_PLATFORM
LRESULT DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
return FALSE;
}
#endif
#if defined OIS_LINUX_PLATFORM
//This is just here to show that you still recieve x11 events, as the lib only needs mouse/key events
void checkX11Events()
{
if(!appRunning)
return;
XEvent event;
while(XPending(xDisp) > 0)
{
XNextEvent(xDisp, &event);
//Handle Resize events
if(event.type == ConfigureNotify)
{
if(g_m)
{
const MouseState &ms = g_m->getMouseState();
ms.width = event.xconfigure.width;
ms.height = event.xconfigure.height;
}
}
else if(event.type == ClientMessage || event.type == DestroyNotify)
{ // We only get DestroyNotify for child windows. However, we regeistered earlier to receive WM_DELETE_MESSAGEs
std::cout << "Exiting...\n";
appRunning = false;
return;
}
else
{
std::cout << "\nUnknown X Event: " << event.type << std::endl;
}
}
}
#endif
#if defined OIS_APPLE_PLATFORM
void checkMacEvents()
{
//TODO - Check for window resize events, and then adjust the members of mousestate
EventRef event = NULL;
EventTargetRef targetWindow = GetEventDispatcherTarget();
if( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr )
{
SendEventToEventTarget(event, targetWindow);
std::cout << "Event : " << GetEventKind(event) << "\n";
ReleaseEvent(event);
}
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_OISALL_H
#define OIS_OISALL_H
#include "OISPrereqs.h"
#include "OISObject.h"
#include "OISMouse.h"
#include "OISKeyboard.h"
#include "OISJoyStick.h"
#include "OISMultiTouch.h"
#include "OISInputManager.h"
#include "OISFactoryCreator.h"
#include "OISException.h"
#include "OISEvents.h"
#include "OISEffect.h"
#include "OISInterface.h"
#include "OISForceFeedback.h"
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_OISALL_H
#define OIS_OISALL_H
#include "OISPrereqs.h"
#include "OISObject.h"
#include "OISMouse.h"
#include "OISKeyboard.h"
#include "OISJoyStick.h"
#include "OISMultiTouch.h"
#include "OISInputManager.h"
#include "OISFactoryCreator.h"
#include "OISException.h"
#include "OISEvents.h"
#include "OISEffect.h"
#include "OISInterface.h"
#include "OISForceFeedback.h"
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_CONFIG_HEADER
#define OIS_CONFIG_HEADER
//----------------------------------------------------------------------------//
//* This file contains defines for building certain parts of this Lib
//* This file is not meant for External inclusion. However, you can edit this
//* file before a build to effect what features are used internally
//----------------------------------------------------------------------------//
/**
@remarks
These lines have no bearing on internal build of OIS. This is here for
external build settings. Meaning, changing this does not require a
rebuild of OIS. This just affects VC dll import settings, as the DLL
build already defines this during its build for setting dll exports.
The undefine here is here just incase you decide to only use
DLL, and want to set it permently and recompile OIS too.. Avoid redefinition
from DLL build of OIS.
So, if wanting to link against DLL version, just uncomment these lines.
*/
//#ifdef OIS_DYNAMIC_LIB
//# undef OIS_DYNAMIC_LIB
//#endif
//#define OIS_DYNAMIC_LIB
/**
@remarks
Build in support for LIRC / WinLIRC - remote control support.
Requires Boost::asio
@notes
Experimental - Supports connecting and enumerating. Control does not
yet return state or events
*/
//#define OIS_LIRC_SUPPORT
/**
@remarks
Build in support for PC Nintendo WiiMote Win32 HID interface.
Requires Boost::threads
@notes
Useable, but not quite finished - supports rumble, all buttons, & main orientation axis.
Still needs Nunchuck, IR, and LED/Battery support.
*/
//#define OIS_WIN32_WIIMOTE_SUPPORT
/**
@remarks
Build in support for Win32 XInput (Xbox 360 Controller)
*/
//#define OIS_WIN32_XINPUT_SUPPORT
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_CONFIG_HEADER
#define OIS_CONFIG_HEADER
//----------------------------------------------------------------------------//
//* This file contains defines for building certain parts of this Lib
//* This file is not meant for External inclusion. However, you can edit this
//* file before a build to effect what features are used internally
//----------------------------------------------------------------------------//
/**
@remarks
These lines have no bearing on internal build of OIS. This is here for
external build settings. Meaning, changing this does not require a
rebuild of OIS. This just affects VC dll import settings, as the DLL
build already defines this during its build for setting dll exports.
The undefine here is here just incase you decide to only use
DLL, and want to set it permently and recompile OIS too.. Avoid redefinition
from DLL build of OIS.
So, if wanting to link against DLL version, just uncomment these lines.
*/
//#ifdef OIS_DYNAMIC_LIB
//# undef OIS_DYNAMIC_LIB
//#endif
//#define OIS_DYNAMIC_LIB
/**
@remarks
Build in support for LIRC / WinLIRC - remote control support.
Requires Boost::asio
@notes
Experimental - Supports connecting and enumerating. Control does not
yet return state or events
*/
//#define OIS_LIRC_SUPPORT
/**
@remarks
Build in support for PC Nintendo WiiMote Win32 HID interface.
Requires Boost::threads
@notes
Useable, but not quite finished - supports rumble, all buttons, & main orientation axis.
Still needs Nunchuck, IR, and LED/Battery support.
*/
//#define OIS_WIN32_WIIMOTE_SUPPORT
/**
@remarks
Build in support for Win32 XInput (Xbox 360 Controller)
*/
//#define OIS_WIN32_XINPUT_SUPPORT
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Effect_H
#define OIS_Effect_H
#include "OISPrereqs.h"
namespace OIS
{
//Predeclare some Effect Property structs
class ForceEffect;
class ConstantEffect;
class RampEffect;
class PeriodicEffect;
class ConditionalEffect;
/**
Force Feedback is a relatively complex set of properties to upload to a device.
The best place for information on the different properties, effects, etc is in
the DX Documentation and MSDN - there are even pretty graphs ther =)
As this class is modeled on the the DX interface you can apply that same
knowledge to creating effects via this class on any OS supported by OIS.
In anycase, this is the main class you will be using. There is *absolutely* no
need to instance any of the supporting ForceEffect classes yourself.
*/
class _OISExport Effect
{
public:
//! Type of force
enum EForce
{
UnknownForce = 0,
ConstantForce,
RampForce,
PeriodicForce,
ConditionalForce,
CustomForce,
_ForcesNumber // Always keep in last position.
};
static const char* getForceTypeName(EForce eValue);
//! Type of effect
enum EType
{
//Type ----- Pairs with force:
Unknown = 0, //UnknownForce
Constant, //ConstantForce
Ramp, //RampForce
Square, //PeriodicForce
Triangle, //PeriodicForce
Sine, //PeriodicForce
SawToothUp, //PeriodicForce
SawToothDown,//PeriodicForce
Friction, //ConditionalForce
Damper, //ConditionalForce
Inertia, //ConditionalForce
Spring, //ConditionalForce
Custom, //CustomForce
_TypesNumber // Always keep in last position.
};
static const char* getEffectTypeName(EType eValue);
//! Direction of the Force
enum EDirection
{
NorthWest,
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
_DirectionsNumber // Always keep in last position.
};
static const char* getDirectionName(EDirection eValue);
/**
This constructor allows you to set the force type and effect.
*/
Effect(EForce ef, EType et);
virtual ~Effect();
const EForce force;
const EType type;
//Infinite Time
static const unsigned int OIS_INFINITE = 0xFFFFFFFF;
//-------------------------------------------------------------------//
//--- Set these variables before uploading or modifying an effect ---//
//Direction to apply to the force - affects two axes+ effects
EDirection direction;
//Number of button triggering an effect (-1 means no trigger)
short trigger_button;
//Time to wait before an effect can be re-triggered (microseconds)
unsigned int trigger_interval;
//Duration of an effect (microseconds)
unsigned int replay_length;
//Time to wait before to start playing an effect (microseconds)
unsigned int replay_delay;
//Get the specific Force Effect. This should be cast depending on the EForce
ForceEffect* getForceEffect() const;
/**
@remarks
Set the number of Axes to use before the initial creation of the effect.
Can only be done prior to creation! Use the FF interface to determine
how many axes can be used (are availiable)
*/
void setNumAxes(short nAxes);
/**
@remarks
Returns the number of axes used in this effect
*/
short getNumAxes() const;
//------------- Library Internal -------------------------------------//
/**
set internally.. do not change or you will not be able to upload/stop
this effect any more. It will become lost. It is mutable so even
with const reference it can/will be changed by this lib
*/
mutable int _handle;
protected:
// Prevent copying.
Effect(const Effect&);
Effect& operator=(Effect);
ForceEffect* effect; //Properties depend on EForce
short axes; //Number of axes to use in effect
};
//-----------------------------------------------------------------------------//
/**
Base class of all effect property classes
*/
class _OISExport ForceEffect
{
public:
virtual ~ForceEffect() {}
};
//-----------------------------------------------------------------------------//
/**
An optional envelope to be applied to the start/end of an effect. If any of
these values are nonzero, then the envelope will be used in setting up the
effect.
*/
class _OISExport Envelope : public ForceEffect
{
public:
Envelope() : attackLength(0), attackLevel(0), fadeLength(0), fadeLevel(0) {}
#if defined(OIS_MSVC_COMPILER)
#pragma warning (push)
#pragma warning (disable : 4800)
#endif
bool isUsed() const { return attackLength | attackLevel | fadeLength | fadeLevel; }
#if defined(OIS_MSVC_COMPILER)
#pragma warning (pop)
#endif
// Duration of the attack (microseconds)
unsigned int attackLength;
// Absolute level at the beginning of the attack (0 to 10K)
// (automatically signed when necessary by FF core according to effect level sign)
unsigned short attackLevel;
// Duration of fade (microseconds)
unsigned int fadeLength;
// Absolute level at the end of fade (0 to 10K)
// (automatically signed when necessary by FF core according to effect level sign)
unsigned short fadeLevel;
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Constant
*/
class _OISExport ConstantEffect : public ForceEffect
{
public:
ConstantEffect() : level(5000) {}
Envelope envelope; //Optional envolope
signed short level; //-10K to +10k
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Ramp
*/
class _OISExport RampEffect : public ForceEffect
{
public:
RampEffect() : startLevel(0), endLevel(0) {}
Envelope envelope; //Optional envelope
signed short startLevel; //-10K to +10k
signed short endLevel; //-10K to +10k
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Periodic
*/
class _OISExport PeriodicEffect : public ForceEffect
{
public:
PeriodicEffect() : magnitude(0), offset(0), phase(0), period(0) {}
Envelope envelope; //Optional Envelope
unsigned short magnitude; //0 to 10,0000
signed short offset;
unsigned short phase; //Position at which playback begins 0 to 35,999
unsigned int period; //Period of effect (microseconds)
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Condional
*/
class _OISExport ConditionalEffect : public ForceEffect
{
public:
ConditionalEffect() :
rightCoeff(0), leftCoeff(0), rightSaturation(0), leftSaturation(0),
deadband(0), center(0) {}
signed short rightCoeff; //-10k to +10k (Positive Coeff)
signed short leftCoeff; //-10k to +10k (Negative Coeff)
unsigned short rightSaturation; //0 to 10k (Pos Saturation)
unsigned short leftSaturation; //0 to 10k (Neg Saturation)
//Region around center in which the condition is not active, in the range
//from 0 through 10,000
unsigned short deadband;
//(Offset in DX) -10k and 10k
signed short center;
};
}
#endif //OIS_Effect_H
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Effect_H
#define OIS_Effect_H
#include "OISPrereqs.h"
namespace OIS
{
//Predeclare some Effect Property structs
class ForceEffect;
class ConstantEffect;
class RampEffect;
class PeriodicEffect;
class ConditionalEffect;
/**
Force Feedback is a relatively complex set of properties to upload to a device.
The best place for information on the different properties, effects, etc is in
the DX Documentation and MSDN - there are even pretty graphs ther =)
As this class is modeled on the the DX interface you can apply that same
knowledge to creating effects via this class on any OS supported by OIS.
In anycase, this is the main class you will be using. There is *absolutely* no
need to instance any of the supporting ForceEffect classes yourself.
*/
class _OISExport Effect
{
public:
//! Type of force
enum EForce
{
UnknownForce = 0,
ConstantForce,
RampForce,
PeriodicForce,
ConditionalForce,
CustomForce,
_ForcesNumber // Always keep in last position.
};
static const char* getForceTypeName(EForce eValue);
//! Type of effect
enum EType
{
//Type ----- Pairs with force:
Unknown = 0, //UnknownForce
Constant, //ConstantForce
Ramp, //RampForce
Square, //PeriodicForce
Triangle, //PeriodicForce
Sine, //PeriodicForce
SawToothUp, //PeriodicForce
SawToothDown,//PeriodicForce
Friction, //ConditionalForce
Damper, //ConditionalForce
Inertia, //ConditionalForce
Spring, //ConditionalForce
Custom, //CustomForce
_TypesNumber // Always keep in last position.
};
static const char* getEffectTypeName(EType eValue);
//! Direction of the Force
enum EDirection
{
NorthWest,
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
_DirectionsNumber // Always keep in last position.
};
static const char* getDirectionName(EDirection eValue);
/**
This constructor allows you to set the force type and effect.
*/
Effect(EForce ef, EType et);
virtual ~Effect();
const EForce force;
const EType type;
//Infinite Time
static const unsigned int OIS_INFINITE = 0xFFFFFFFF;
//-------------------------------------------------------------------//
//--- Set these variables before uploading or modifying an effect ---//
//Direction to apply to the force - affects two axes+ effects
EDirection direction;
//Number of button triggering an effect (-1 means no trigger)
short trigger_button;
//Time to wait before an effect can be re-triggered (microseconds)
unsigned int trigger_interval;
//Duration of an effect (microseconds)
unsigned int replay_length;
//Time to wait before to start playing an effect (microseconds)
unsigned int replay_delay;
//Get the specific Force Effect. This should be cast depending on the EForce
ForceEffect* getForceEffect() const;
/**
@remarks
Set the number of Axes to use before the initial creation of the effect.
Can only be done prior to creation! Use the FF interface to determine
how many axes can be used (are availiable)
*/
void setNumAxes(short nAxes);
/**
@remarks
Returns the number of axes used in this effect
*/
short getNumAxes() const;
//------------- Library Internal -------------------------------------//
/**
set internally.. do not change or you will not be able to upload/stop
this effect any more. It will become lost. It is mutable so even
with const reference it can/will be changed by this lib
*/
mutable int _handle;
protected:
// Prevent copying.
Effect(const Effect&);
Effect& operator=(Effect);
ForceEffect* effect; //Properties depend on EForce
short axes; //Number of axes to use in effect
};
//-----------------------------------------------------------------------------//
/**
Base class of all effect property classes
*/
class _OISExport ForceEffect
{
public:
virtual ~ForceEffect() {}
};
//-----------------------------------------------------------------------------//
/**
An optional envelope to be applied to the start/end of an effect. If any of
these values are nonzero, then the envelope will be used in setting up the
effect.
*/
class _OISExport Envelope : public ForceEffect
{
public:
Envelope() : attackLength(0), attackLevel(0), fadeLength(0), fadeLevel(0) {}
#if defined(OIS_MSVC_COMPILER)
#pragma warning (push)
#pragma warning (disable : 4800)
#endif
bool isUsed() const { return attackLength | attackLevel | fadeLength | fadeLevel; }
#if defined(OIS_MSVC_COMPILER)
#pragma warning (pop)
#endif
// Duration of the attack (microseconds)
unsigned int attackLength;
// Absolute level at the beginning of the attack (0 to 10K)
// (automatically signed when necessary by FF core according to effect level sign)
unsigned short attackLevel;
// Duration of fade (microseconds)
unsigned int fadeLength;
// Absolute level at the end of fade (0 to 10K)
// (automatically signed when necessary by FF core according to effect level sign)
unsigned short fadeLevel;
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Constant
*/
class _OISExport ConstantEffect : public ForceEffect
{
public:
ConstantEffect() : level(5000) {}
Envelope envelope; //Optional envolope
signed short level; //-10K to +10k
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Ramp
*/
class _OISExport RampEffect : public ForceEffect
{
public:
RampEffect() : startLevel(0), endLevel(0) {}
Envelope envelope; //Optional envelope
signed short startLevel; //-10K to +10k
signed short endLevel; //-10K to +10k
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Periodic
*/
class _OISExport PeriodicEffect : public ForceEffect
{
public:
PeriodicEffect() : magnitude(0), offset(0), phase(0), period(0) {}
Envelope envelope; //Optional Envelope
unsigned short magnitude; //0 to 10,0000
signed short offset;
unsigned short phase; //Position at which playback begins 0 to 35,999
unsigned int period; //Period of effect (microseconds)
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Condional
*/
class _OISExport ConditionalEffect : public ForceEffect
{
public:
ConditionalEffect() :
rightCoeff(0), leftCoeff(0), rightSaturation(0), leftSaturation(0),
deadband(0), center(0) {}
signed short rightCoeff; //-10k to +10k (Positive Coeff)
signed short leftCoeff; //-10k to +10k (Negative Coeff)
unsigned short rightSaturation; //0 to 10k (Pos Saturation)
unsigned short leftSaturation; //0 to 10k (Neg Saturation)
//Region around center in which the condition is not active, in the range
//from 0 through 10,000
unsigned short deadband;
//(Offset in DX) -10k and 10k
signed short center;
};
}
#endif //OIS_Effect_H
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _OIS_EVENTHEADERS_
#define _OIS_EVENTHEADERS_
#include "OISPrereqs.h"
namespace OIS
{
/**
Base class of all events
*/
class _OISExport EventArg
{
public:
explicit EventArg( Object* obj ) : device(obj) {}
virtual ~EventArg() {}
//! Pointer to the Input Device
const Object* device;
};
}
#endif //_OIS_EVENTHEADERS_
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _OIS_EVENTHEADERS_
#define _OIS_EVENTHEADERS_
#include "OISPrereqs.h"
namespace OIS
{
/**
Base class of all events
*/
class _OISExport EventArg
{
public:
explicit EventArg( Object* obj ) : device(obj) {}
virtual ~EventArg() {}
//! Pointer to the Input Device
const Object* device;
};
}
#endif //_OIS_EVENTHEADERS_
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _OIS_EXCEPTION_HEADER_
#define _OIS_EXCEPTION_HEADER_
#include "OISPrereqs.h"
#include <exception>
namespace OIS
{
//! Simple enum's for dealing with exceptions
enum OIS_ERROR
{
E_InputDisconnected,
E_InputDeviceNonExistant,
E_InputDeviceNotSupported,
E_DeviceFull,
E_NotSupported,
E_NotImplemented,
E_Duplicate,
E_InvalidParam,
E_General
};
/**
@remarks
Class for handling OIS exceptions. Much cleaner than checking every method for reurn value.
Inherits from std::exception so you can simply log those messages if you want to be generic.
Also note that this has a source file now since OSX was not finding the OIS::Exception symbol
which would cause program abortion with now correponding exception type.
*/
class _OISExport Exception : public std::exception
{
public:
//! Creates exception object
Exception( OIS_ERROR err, const char* str, int line, const char *file )
: eType(err), eLine(line), eFile(file), eText(str) {}
Exception(const Exception& other)
: eType(other.eType), eLine(other.eLine), eFile(other.eFile), eText(other.eText) {}
~Exception() throw() {}
virtual const char* what() const throw();
//! The type of exception raised
const OIS_ERROR eType;
//! The line number it occurred on
const int eLine;
//! The source file
const char* eFile;
//! A message passed along when the exception was raised
const char* eText;
private:
// Unimplemented and unaccessible due to const members.
Exception& operator=(Exception);
};
}
//! Use this macro to handle exceptions easily
#define OIS_EXCEPT( err, str ) throw( OIS::Exception(err, str, __LINE__, __FILE__) )
#endif //_OIS_EXCEPTION_HEADER_
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _OIS_EXCEPTION_HEADER_
#define _OIS_EXCEPTION_HEADER_
#include "OISPrereqs.h"
#include <exception>
namespace OIS
{
//! Simple enum's for dealing with exceptions
enum OIS_ERROR
{
E_InputDisconnected,
E_InputDeviceNonExistant,
E_InputDeviceNotSupported,
E_DeviceFull,
E_NotSupported,
E_NotImplemented,
E_Duplicate,
E_InvalidParam,
E_General
};
/**
@remarks
Class for handling OIS exceptions. Much cleaner than checking every method for reurn value.
Inherits from std::exception so you can simply log those messages if you want to be generic.
Also note that this has a source file now since OSX was not finding the OIS::Exception symbol
which would cause program abortion with now correponding exception type.
*/
class _OISExport Exception : public std::exception
{
public:
//! Creates exception object
Exception( OIS_ERROR err, const char* str, int line, const char *file )
: eType(err), eLine(line), eFile(file), eText(str) {}
Exception(const Exception& other)
: eType(other.eType), eLine(other.eLine), eFile(other.eFile), eText(other.eText) {}
~Exception() throw() {}
virtual const char* what() const throw();
//! The type of exception raised
const OIS_ERROR eType;
//! The line number it occurred on
const int eLine;
//! The source file
const char* eFile;
//! A message passed along when the exception was raised
const char* eText;
private:
// Unimplemented and unaccessible due to const members.
Exception& operator=(Exception);
};
}
//! Use this macro to handle exceptions easily
#define OIS_EXCEPT( err, str ) throw( OIS::Exception(err, str, __LINE__, __FILE__) )
#endif //_OIS_EXCEPTION_HEADER_
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_FactoryCreator_H
#define OIS_FactoryCreator_H
#include "OISPrereqs.h"
namespace OIS
{
/**
Interface for creating devices - all devices ultimately get enumerated/created via a factory.
A factory can create multiple types of objects.
*/
class _OISExport FactoryCreator
{
public:
/**
@remarks Virtual Destructor
*/
virtual ~FactoryCreator() {};
/**
@remarks Return a list of all unused devices the factory maintains
*/
virtual DeviceList freeDeviceList() = 0;
/**
@remarks Number of total devices of requested type
@param iType Type of devices to check
*/
virtual int totalDevices(Type iType) = 0;
/**
@remarks Number of free devices of requested type
@param iType Type of devices to check
*/
virtual int freeDevices(Type iType) = 0;
/**
@remarks Does a Type exist with the given vendor name
@param iType Type to check
@param vendor Vendor name to test
*/
virtual bool vendorExist(Type iType, const std::string & vendor) = 0;
/**
@remarks Creates the object
@param iType Type to create
@param bufferMode True to setup for buffered events
@param vendor Create a device with the vendor name, "" means vendor name is unimportant
*/
virtual Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "") = 0;
/**
@remarks Destroys object
@param obj Object to destroy
*/
virtual void destroyObject(Object* obj) = 0;
};
}
#endif //OIS_FactoryCreator_H
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_FactoryCreator_H
#define OIS_FactoryCreator_H
#include "OISPrereqs.h"
namespace OIS
{
/**
Interface for creating devices - all devices ultimately get enumerated/created via a factory.
A factory can create multiple types of objects.
*/
class _OISExport FactoryCreator
{
public:
/**
@remarks Virtual Destructor
*/
virtual ~FactoryCreator() {};
/**
@remarks Return a list of all unused devices the factory maintains
*/
virtual DeviceList freeDeviceList() = 0;
/**
@remarks Number of total devices of requested type
@param iType Type of devices to check
*/
virtual int totalDevices(Type iType) = 0;
/**
@remarks Number of free devices of requested type
@param iType Type of devices to check
*/
virtual int freeDevices(Type iType) = 0;
/**
@remarks Does a Type exist with the given vendor name
@param iType Type to check
@param vendor Vendor name to test
*/
virtual bool vendorExist(Type iType, const std::string & vendor) = 0;
/**
@remarks Creates the object
@param iType Type to create
@param bufferMode True to setup for buffered events
@param vendor Create a device with the vendor name, "" means vendor name is unimportant
*/
virtual Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "") = 0;
/**
@remarks Destroys object
@param obj Object to destroy
*/
virtual void destroyObject(Object* obj) = 0;
};
}
#endif //OIS_FactoryCreator_H
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_ForceFeedBack_H
#define OIS_ForceFeedBack_H
#include "OISPrereqs.h"
#include "OISInterface.h"
#include "OISEffect.h"
namespace OIS
{
/**
Interface class for dealing with Force Feedback devices
*/
class _OISExport ForceFeedback : public Interface
{
public:
ForceFeedback();
virtual ~ForceFeedback() {}
/**
@remarks
This is like setting the master volume of an audio device.
Individual effects have gain levels; however, this affects all
effects at once.
Note: If the device does not support master gain setting, nothing is done
@param level
A value between 0.0 and 1.0 represent the percentage of gain. 1.0
being the highest possible force level (means no scaling).
*/
virtual void setMasterGain( float level ) = 0;
/**
@remarks
If using Force Feedback effects, this should be turned off
before uploading any effects. Auto centering is the motor moving
the joystick back to center. DirectInput only has an on/off setting,
whereas linux has levels.. Though, we go with DI's on/off mode only
Note: If the device does not support auto-centering, nothing is done
@param auto_on
true to turn auto centering on, false to turn off.
*/
virtual void setAutoCenterMode( bool auto_on ) = 0;
/**
@remarks
Creates and Plays the effect immediately. If the device is full
of effects, it will fail to be uploaded. You will know this by
an invalid Effect Handle
*/
virtual void upload( const Effect* effect ) = 0;
/**
@remarks
Modifies an effect that is currently playing
*/
virtual void modify( const Effect* effect ) = 0;
/**
@remarks
Remove the effect from the device
*/
virtual void remove( const Effect* effect ) = 0;
/**
@remarks
Get the number of supported Axes for FF usage
*/
virtual short getFFAxesNumber() = 0;
/**
@remarks
Get the current load (%, in [0, 100] of the FF device memory
*/
virtual unsigned short getFFMemoryLoad() = 0;
typedef std::multimap<Effect::EForce, Effect::EType> SupportedEffectList;
/**
@remarks
Get a list of all supported effects
*/
const SupportedEffectList& getSupportedEffects() const;
/**
@remarks
Tell if a given force / effect type pair is supported
*/
bool supportsEffect(Effect::EForce force, Effect::EType type) const;
void _addEffectTypes( Effect::EForce force, Effect::EType type );
void _setGainSupport( bool on );
void _setAutoCenterSupport( bool on );
protected:
SupportedEffectList mSupportedEffects;
bool mSetGainSupport;
bool mSetAutoCenterSupport;
};
}
#endif //OIS_ForceFeedBack_H
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_ForceFeedBack_H
#define OIS_ForceFeedBack_H
#include "OISPrereqs.h"
#include "OISInterface.h"
#include "OISEffect.h"
namespace OIS
{
/**
Interface class for dealing with Force Feedback devices
*/
class _OISExport ForceFeedback : public Interface
{
public:
ForceFeedback();
virtual ~ForceFeedback() {}
/**
@remarks
This is like setting the master volume of an audio device.
Individual effects have gain levels; however, this affects all
effects at once.
Note: If the device does not support master gain setting, nothing is done
@param level
A value between 0.0 and 1.0 represent the percentage of gain. 1.0
being the highest possible force level (means no scaling).
*/
virtual void setMasterGain( float level ) = 0;
/**
@remarks
If using Force Feedback effects, this should be turned off
before uploading any effects. Auto centering is the motor moving
the joystick back to center. DirectInput only has an on/off setting,
whereas linux has levels.. Though, we go with DI's on/off mode only
Note: If the device does not support auto-centering, nothing is done
@param auto_on
true to turn auto centering on, false to turn off.
*/
virtual void setAutoCenterMode( bool auto_on ) = 0;
/**
@remarks
Creates and Plays the effect immediately. If the device is full
of effects, it will fail to be uploaded. You will know this by
an invalid Effect Handle
*/
virtual void upload( const Effect* effect ) = 0;
/**
@remarks
Modifies an effect that is currently playing
*/
virtual void modify( const Effect* effect ) = 0;
/**
@remarks
Remove the effect from the device
*/
virtual void remove( const Effect* effect ) = 0;
/**
@remarks
Get the number of supported Axes for FF usage
*/
virtual short getFFAxesNumber() = 0;
/**
@remarks
Get the current load (%, in [0, 100] of the FF device memory
*/
virtual unsigned short getFFMemoryLoad() = 0;
typedef std::multimap<Effect::EForce, Effect::EType> SupportedEffectList;
/**
@remarks
Get a list of all supported effects
*/
const SupportedEffectList& getSupportedEffects() const;
/**
@remarks
Tell if a given force / effect type pair is supported
*/
bool supportsEffect(Effect::EForce force, Effect::EType type) const;
void _addEffectTypes( Effect::EForce force, Effect::EType type );
void _setGainSupport( bool on );
void _setAutoCenterSupport( bool on );
protected:
SupportedEffectList mSupportedEffects;
bool mSetGainSupport;
bool mSetAutoCenterSupport;
};
}
#endif //OIS_ForceFeedBack_H
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_InputManager_H
#define OIS_InputManager_H
#include "OISPrereqs.h"
namespace OIS
{
//Forward declare a couple of classes we might use later
class LIRCFactoryCreator;
class WiiMoteFactoryCreator;
/**
Base Manager class. No longer a Singleton; so feel free to create as many InputManager's as you have
windows.
*/
class _OISExport InputManager
{
public:
/**
@remarks
Returns version number (useful in DLL/SO libs)
@returns
Bits: 1-8 Patch number, 9-16 Minor version, 17-32 Major version
*/
static unsigned int getVersionNumber();
/**
@remarks
Returns version string (useful in DLL/SO libs)
@returns
Version name
*/
const std::string &getVersionName();
/**
@remarks
Creates appropriate input system dependent on platform.
@param winHandle
Contains OS specific window handle (such as HWND or X11 Window)
@returns
A pointer to the created manager, or raises Exception
*/
static InputManager* createInputSystem( std::size_t winHandle );
/**
@remarks
Creates appropriate input system dependent on platform.
@param paramList
ParamList contains OS specific info (such as HWND and HINSTANCE for window apps),
and access mode.
@returns
A pointer to the created manager, or raises Exception
*/
static InputManager* createInputSystem( ParamList &paramList );
/**
@remarks
Destroys the InputManager
@param manager
Manager to destroy
*/
static void destroyInputSystem(InputManager* manager);
/**
@remarks Gets the name of the current platform input system
*/
const std::string& inputSystemName();
/**
@remarks
Returns the number of the specified OIS::Type devices discovered by OIS
@param iType
Type that you are interested in
*/
int getNumberOfDevices( Type iType );
/**
@remarks
Lists all unused devices
@returns
DeviceList which contains Type and vendor of device
*/
DeviceList listFreeDevices();
/**
@remarks
Tries to create an object with the specified vendor. If you have no
preference of vendor, leave vender as default (""). Raises exception on failure
*/
Object* createInputObject( Type iType, bool bufferMode, const std::string &vendor = "");
/**
@remarks Destroys Input Object
*/
void destroyInputObject( Object* obj );
/**
@remarks
Add a custom object factory to allow for user controls.
@param factory
Factory instance to add
@notes
Make sure you do not delete the factory before devices created from
the factory are destroyed (either by calling RemoveFactoryCreator, or shutting down
the input system). Order should be something like the following:
* Create Input System
* Create Factory Instance
* AddFactoryCreator(factory)
* Create a device from the InputManager (device created by factory)
* One of the follwoing:
* removeFactoryCreator(factory)
* inputManager->destroyInputObject(obj)
* destroyInputSystem(inputManager)
* destroy Factory Instance
You can safely delete the factory instance once you have removed it or shut down the
input manager.
*/
void addFactoryCreator( FactoryCreator* factory );
/**
@remarks
Remove a previously added object factory
@param factory
Factory object to remove.
@notes
Removing a factory will automatically destroy any Objects created from the factory
*/
void removeFactoryCreator( FactoryCreator* factory );
//! All generic devices OIS supports internally (if they are compiled in)
enum AddOnFactories
{
AddOn_All = 0, //All Devices
AddOn_LIRC = 1, //PC Linux Infrared Remote Control
AddOn_WiiMote = 2 //PC WiiMote Support
};
/**
@remarks
Enable an addon FactoryCreator extension. By default, none are activated.
If the desired support was not compiled in, this has no effect. Calling
multiple times has no effect. Once activated, there is no way to deactivate -
simply destroy and recreate input manager.
*/
void enableAddOnFactory(AddOnFactories factory);
protected:
/**
@remarks
Called from createInputSystem, gives derived input class a chance to setup after it is created
*/
virtual void _initialize(ParamList &paramList) = 0;
/**
@remarks
Derived classes must provide input system name
*/
explicit InputManager(const std::string& name);
/**
@remarks
Virtual Destructor - this base class will clean up all devices still opened in mFactoryObjects list
*/
virtual ~InputManager();
//! OIS Version name
const std::string m_VersionName;
//! FactoryCreator list
FactoryList mFactories;
//! Factory created objects - useful so we can find creator to send destruction request to
FactoryCreatedObject mFactoryObjects;
//! Name of the input system
const std::string mInputSystemName;
//! Extra factory (not enabled by default)
LIRCFactoryCreator *m_lircSupport;
WiiMoteFactoryCreator *m_wiiMoteSupport;
private:
// Prevent copying.
InputManager(const InputManager&);
InputManager& operator=(InputManager);
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_InputManager_H
#define OIS_InputManager_H
#include "OISPrereqs.h"
namespace OIS
{
//Forward declare a couple of classes we might use later
class LIRCFactoryCreator;
class WiiMoteFactoryCreator;
/**
Base Manager class. No longer a Singleton; so feel free to create as many InputManager's as you have
windows.
*/
class _OISExport InputManager
{
public:
/**
@remarks
Returns version number (useful in DLL/SO libs)
@returns
Bits: 1-8 Patch number, 9-16 Minor version, 17-32 Major version
*/
static unsigned int getVersionNumber();
/**
@remarks
Returns version string (useful in DLL/SO libs)
@returns
Version name
*/
const std::string &getVersionName();
/**
@remarks
Creates appropriate input system dependent on platform.
@param winHandle
Contains OS specific window handle (such as HWND or X11 Window)
@returns
A pointer to the created manager, or raises Exception
*/
static InputManager* createInputSystem( std::size_t winHandle );
/**
@remarks
Creates appropriate input system dependent on platform.
@param paramList
ParamList contains OS specific info (such as HWND and HINSTANCE for window apps),
and access mode.
@returns
A pointer to the created manager, or raises Exception
*/
static InputManager* createInputSystem( ParamList &paramList );
/**
@remarks
Destroys the InputManager
@param manager
Manager to destroy
*/
static void destroyInputSystem(InputManager* manager);
/**
@remarks Gets the name of the current platform input system
*/
const std::string& inputSystemName();
/**
@remarks
Returns the number of the specified OIS::Type devices discovered by OIS
@param iType
Type that you are interested in
*/
int getNumberOfDevices( Type iType );
/**
@remarks
Lists all unused devices
@returns
DeviceList which contains Type and vendor of device
*/
DeviceList listFreeDevices();
/**
@remarks
Tries to create an object with the specified vendor. If you have no
preference of vendor, leave vender as default (""). Raises exception on failure
*/
Object* createInputObject( Type iType, bool bufferMode, const std::string &vendor = "");
/**
@remarks Destroys Input Object
*/
void destroyInputObject( Object* obj );
/**
@remarks
Add a custom object factory to allow for user controls.
@param factory
Factory instance to add
@notes
Make sure you do not delete the factory before devices created from
the factory are destroyed (either by calling RemoveFactoryCreator, or shutting down
the input system). Order should be something like the following:
* Create Input System
* Create Factory Instance
* AddFactoryCreator(factory)
* Create a device from the InputManager (device created by factory)
* One of the follwoing:
* removeFactoryCreator(factory)
* inputManager->destroyInputObject(obj)
* destroyInputSystem(inputManager)
* destroy Factory Instance
You can safely delete the factory instance once you have removed it or shut down the
input manager.
*/
void addFactoryCreator( FactoryCreator* factory );
/**
@remarks
Remove a previously added object factory
@param factory
Factory object to remove.
@notes
Removing a factory will automatically destroy any Objects created from the factory
*/
void removeFactoryCreator( FactoryCreator* factory );
//! All generic devices OIS supports internally (if they are compiled in)
enum AddOnFactories
{
AddOn_All = 0, //All Devices
AddOn_LIRC = 1, //PC Linux Infrared Remote Control
AddOn_WiiMote = 2 //PC WiiMote Support
};
/**
@remarks
Enable an addon FactoryCreator extension. By default, none are activated.
If the desired support was not compiled in, this has no effect. Calling
multiple times has no effect. Once activated, there is no way to deactivate -
simply destroy and recreate input manager.
*/
void enableAddOnFactory(AddOnFactories factory);
protected:
/**
@remarks
Called from createInputSystem, gives derived input class a chance to setup after it is created
*/
virtual void _initialize(ParamList &paramList) = 0;
/**
@remarks
Derived classes must provide input system name
*/
explicit InputManager(const std::string& name);
/**
@remarks
Virtual Destructor - this base class will clean up all devices still opened in mFactoryObjects list
*/
virtual ~InputManager();
//! OIS Version name
const std::string m_VersionName;
//! FactoryCreator list
FactoryList mFactories;
//! Factory created objects - useful so we can find creator to send destruction request to
FactoryCreatedObject mFactoryObjects;
//! Name of the input system
const std::string mInputSystemName;
//! Extra factory (not enabled by default)
LIRCFactoryCreator *m_lircSupport;
WiiMoteFactoryCreator *m_wiiMoteSupport;
private:
// Prevent copying.
InputManager(const InputManager&);
InputManager& operator=(InputManager);
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Interface_H
#define OIS_Interface_H
#include "OISPrereqs.h"
namespace OIS
{
/**
An Object's interface is a way to gain write access to devices which support
it. For example, force feedack.
*/
class _OISExport Interface
{
public:
virtual ~Interface() {};
//! Type of Interface
enum IType
{
ForceFeedback,
Reserved
};
};
}
#endif //OIS_Interface_H
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Interface_H
#define OIS_Interface_H
#include "OISPrereqs.h"
namespace OIS
{
/**
An Object's interface is a way to gain write access to devices which support
it. For example, force feedack.
*/
class _OISExport Interface
{
public:
virtual ~Interface() {};
//! Type of Interface
enum IType
{
ForceFeedback,
Reserved
};
};
}
#endif //OIS_Interface_H
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Joystick_H
#define OIS_Joystick_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
/** @remarks default sensitivity for vector3 component of joystick */
#define OIS_JOYSTICK_VECTOR3_DEFAULT 2.28f
//! POV / HAT Joystick component
class _OISExport Pov : public Component
{
public:
Pov() : Component(OIS_POV), direction(0) {}
static const int Centered = 0x00000000;
static const int North = 0x00000001;
static const int South = 0x00000010;
static const int East = 0x00000100;
static const int West = 0x00001000;
static const int NorthEast = 0x00000101;
static const int SouthEast = 0x00000110;
static const int NorthWest = 0x00001001;
static const int SouthWest = 0x00001010;
int direction;
};
//! A sliding axis - only used in Win32 Right Now
class _OISExport Slider : public Component
{
public:
Slider() : Component(OIS_Slider), abX(0), abY(0) {};
//! true if pushed, false otherwise
int abX, abY;
};
/**
Represents the state of the joystick
All members are valid for both buffered and non buffered mode
Sticks with zero values are not present on the device
*/
class _OISExport JoyStickState
{
public:
//! Constructor
JoyStickState() { clear(); }
//! Represents all the buttons (uses a bitset)
std::vector<bool> mButtons;
//! Represents all the single axes on the device
std::vector<Axis> mAxes;
//! Represents the value of a POV. Maximum of 4
Pov mPOV[4];
//! Represent the max sliders
Slider mSliders[4];
//! Represents all Vector type controls the device exports
std::vector<Vector3> mVectors;
//! internal method to reset all variables to initial values
void clear()
{
for( std::vector<bool>::iterator i = mButtons.begin(), e = mButtons.end(); i != e; ++i )
{
(*i) = false;
}
for( std::vector<Axis>::iterator i = mAxes.begin(), e = mAxes.end(); i != e; ++i )
{
i->absOnly = true; //Currently, joysticks only report Absolute values
i->clear();
}
for( std::vector<Vector3>::iterator i = mVectors.begin(), e = mVectors.end(); i != e; ++i )
{
i->clear();
}
for( int i = 0; i < 4; ++i )
{
mPOV[i].direction = Pov::Centered;
mSliders[i].abX = mSliders[i].abY = 0;
}
}
};
/** Specialised for joystick events */
class _OISExport JoyStickEvent : public EventArg
{
public:
JoyStickEvent( Object* obj, const JoyStickState &st ) : EventArg(obj), state(st) {}
virtual ~JoyStickEvent() {}
const JoyStickState &state;
private:
// Prevent copying.
JoyStickEvent(const JoyStickEvent&);
JoyStickEvent& operator=(JoyStickEvent);
};
/**
To recieve buffered joystick input, derive a class from this, and implement the
methods here. Then set the call back to your JoyStick instance with JoyStick::setEventCallback
Each JoyStick instance can use the same callback class, as a devID number will be provided
to differentiate between connected joysticks. Of course, each can have a seperate
callback instead.
*/
class _OISExport JoyStickListener
{
public:
virtual ~JoyStickListener() {}
/** @remarks Joystick button down event */
virtual bool buttonPressed( const JoyStickEvent &arg, int button ) = 0;
/** @remarks Joystick button up event */
virtual bool buttonReleased( const JoyStickEvent &arg, int button ) = 0;
/** @remarks Joystick axis moved event */
virtual bool axisMoved( const JoyStickEvent &arg, int axis ) = 0;
//-- Not so common control events, so are not required --//
//! Joystick Event, and sliderID
virtual bool sliderMoved( const JoyStickEvent &, int index) {return true;}
//! Joystick Event, and povID
virtual bool povMoved( const JoyStickEvent &arg, int index) {return true;}
//! Joystick Event, and Vector3ID
virtual bool vector3Moved( const JoyStickEvent &arg, int index) {return true;}
};
/**
Joystick base class. To be implemented by specific system (ie. DirectX joystick)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport JoyStick : public Object
{
public:
virtual ~JoyStick() {}
/**
@remarks
Returns the number of requested components
@param cType
The ComponentType you are interested in knowing about
*/
int getNumberOfComponents(ComponentType cType) const;
/**
@remarks
Sets a cutoff limit for changes in the Vector3 component for movement to
be ignored. Helps reduce much event traffic for frequent small/sensitive
changes
@param degrees
The degree under which Vector3 events should be discarded
*/
void setVector3Sensitivity(float degrees = OIS_JOYSTICK_VECTOR3_DEFAULT);
/**
@remarks
Returns the sensitivity cutoff for Vector3 Component
*/
float getVector3Sensitivity() const;
/**
@remarks
Register/unregister a JoyStick Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param joyListener
Send a pointer to a class derived from JoyStickListener or 0 to clear the callback
*/
virtual void setEventCallback( JoyStickListener *joyListener );
/** @remarks Returns currently set callback.. or null */
JoyStickListener* getEventCallback() const;
/** @remarks Returns the state of the joystick - is valid for both buffered and non buffered mode */
const JoyStickState& getJoyStickState() const { return mState; }
//! The minimal axis value
static const int MIN_AXIS = -32768;
//! The maximum axis value
static const int MAX_AXIS = 32767;
protected:
JoyStick(const std::string &vendor, bool buffered, int devID, InputManager* creator);
//! Number of sliders
int mSliders;
//! Number of POVs
int mPOVs;
//! The JoyStickState structure (contains all component values)
JoyStickState mState;
//! The callback listener
JoyStickListener *mListener;
//! Adjustment factor for orientation vector accuracy
float mVector3Sensitivity;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Joystick_H
#define OIS_Joystick_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
/** @remarks default sensitivity for vector3 component of joystick */
#define OIS_JOYSTICK_VECTOR3_DEFAULT 2.28f
//! POV / HAT Joystick component
class _OISExport Pov : public Component
{
public:
Pov() : Component(OIS_POV), direction(0) {}
static const int Centered = 0x00000000;
static const int North = 0x00000001;
static const int South = 0x00000010;
static const int East = 0x00000100;
static const int West = 0x00001000;
static const int NorthEast = 0x00000101;
static const int SouthEast = 0x00000110;
static const int NorthWest = 0x00001001;
static const int SouthWest = 0x00001010;
int direction;
};
//! A sliding axis - only used in Win32 Right Now
class _OISExport Slider : public Component
{
public:
Slider() : Component(OIS_Slider), abX(0), abY(0) {};
//! true if pushed, false otherwise
int abX, abY;
};
/**
Represents the state of the joystick
All members are valid for both buffered and non buffered mode
Sticks with zero values are not present on the device
*/
class _OISExport JoyStickState
{
public:
//! Constructor
JoyStickState() { clear(); }
//! Represents all the buttons (uses a bitset)
std::vector<bool> mButtons;
//! Represents all the single axes on the device
std::vector<Axis> mAxes;
//! Represents the value of a POV. Maximum of 4
Pov mPOV[4];
//! Represent the max sliders
Slider mSliders[4];
//! Represents all Vector type controls the device exports
std::vector<Vector3> mVectors;
//! internal method to reset all variables to initial values
void clear()
{
for( std::vector<bool>::iterator i = mButtons.begin(), e = mButtons.end(); i != e; ++i )
{
(*i) = false;
}
for( std::vector<Axis>::iterator i = mAxes.begin(), e = mAxes.end(); i != e; ++i )
{
i->absOnly = true; //Currently, joysticks only report Absolute values
i->clear();
}
for( std::vector<Vector3>::iterator i = mVectors.begin(), e = mVectors.end(); i != e; ++i )
{
i->clear();
}
for( int i = 0; i < 4; ++i )
{
mPOV[i].direction = Pov::Centered;
mSliders[i].abX = mSliders[i].abY = 0;
}
}
};
/** Specialised for joystick events */
class _OISExport JoyStickEvent : public EventArg
{
public:
JoyStickEvent( Object* obj, const JoyStickState &st ) : EventArg(obj), state(st) {}
virtual ~JoyStickEvent() {}
const JoyStickState &state;
private:
// Prevent copying.
JoyStickEvent(const JoyStickEvent&);
JoyStickEvent& operator=(JoyStickEvent);
};
/**
To recieve buffered joystick input, derive a class from this, and implement the
methods here. Then set the call back to your JoyStick instance with JoyStick::setEventCallback
Each JoyStick instance can use the same callback class, as a devID number will be provided
to differentiate between connected joysticks. Of course, each can have a seperate
callback instead.
*/
class _OISExport JoyStickListener
{
public:
virtual ~JoyStickListener() {}
/** @remarks Joystick button down event */
virtual bool buttonPressed( const JoyStickEvent &arg, int button ) = 0;
/** @remarks Joystick button up event */
virtual bool buttonReleased( const JoyStickEvent &arg, int button ) = 0;
/** @remarks Joystick axis moved event */
virtual bool axisMoved( const JoyStickEvent &arg, int axis ) = 0;
//-- Not so common control events, so are not required --//
//! Joystick Event, and sliderID
virtual bool sliderMoved( const JoyStickEvent &, int index) {return true;}
//! Joystick Event, and povID
virtual bool povMoved( const JoyStickEvent &arg, int index) {return true;}
//! Joystick Event, and Vector3ID
virtual bool vector3Moved( const JoyStickEvent &arg, int index) {return true;}
};
/**
Joystick base class. To be implemented by specific system (ie. DirectX joystick)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport JoyStick : public Object
{
public:
virtual ~JoyStick() {}
/**
@remarks
Returns the number of requested components
@param cType
The ComponentType you are interested in knowing about
*/
int getNumberOfComponents(ComponentType cType) const;
/**
@remarks
Sets a cutoff limit for changes in the Vector3 component for movement to
be ignored. Helps reduce much event traffic for frequent small/sensitive
changes
@param degrees
The degree under which Vector3 events should be discarded
*/
void setVector3Sensitivity(float degrees = OIS_JOYSTICK_VECTOR3_DEFAULT);
/**
@remarks
Returns the sensitivity cutoff for Vector3 Component
*/
float getVector3Sensitivity() const;
/**
@remarks
Register/unregister a JoyStick Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param joyListener
Send a pointer to a class derived from JoyStickListener or 0 to clear the callback
*/
virtual void setEventCallback( JoyStickListener *joyListener );
/** @remarks Returns currently set callback.. or null */
JoyStickListener* getEventCallback() const;
/** @remarks Returns the state of the joystick - is valid for both buffered and non buffered mode */
const JoyStickState& getJoyStickState() const { return mState; }
//! The minimal axis value
static const int MIN_AXIS = -32768;
//! The maximum axis value
static const int MAX_AXIS = 32767;
protected:
JoyStick(const std::string &vendor, bool buffered, int devID, InputManager* creator);
//! Number of sliders
int mSliders;
//! Number of POVs
int mPOVs;
//! The JoyStickState structure (contains all component values)
JoyStickState mState;
//! The callback listener
JoyStickListener *mListener;
//! Adjustment factor for orientation vector accuracy
float mVector3Sensitivity;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Keyboard_H
#define OIS_Keyboard_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
//! Keyboard scan codes
enum KeyCode
{
KC_UNASSIGNED = 0x00,
KC_ESCAPE = 0x01,
KC_1 = 0x02,
KC_2 = 0x03,
KC_3 = 0x04,
KC_4 = 0x05,
KC_5 = 0x06,
KC_6 = 0x07,
KC_7 = 0x08,
KC_8 = 0x09,
KC_9 = 0x0A,
KC_0 = 0x0B,
KC_MINUS = 0x0C, // - on main keyboard
KC_EQUALS = 0x0D,
KC_BACK = 0x0E, // backspace
KC_TAB = 0x0F,
KC_Q = 0x10,
KC_W = 0x11,
KC_E = 0x12,
KC_R = 0x13,
KC_T = 0x14,
KC_Y = 0x15,
KC_U = 0x16,
KC_I = 0x17,
KC_O = 0x18,
KC_P = 0x19,
KC_LBRACKET = 0x1A,
KC_RBRACKET = 0x1B,
KC_RETURN = 0x1C, // Enter on main keyboard
KC_LCONTROL = 0x1D,
KC_A = 0x1E,
KC_S = 0x1F,
KC_D = 0x20,
KC_F = 0x21,
KC_G = 0x22,
KC_H = 0x23,
KC_J = 0x24,
KC_K = 0x25,
KC_L = 0x26,
KC_SEMICOLON = 0x27,
KC_APOSTROPHE = 0x28,
KC_GRAVE = 0x29, // accent
KC_LSHIFT = 0x2A,
KC_BACKSLASH = 0x2B,
KC_Z = 0x2C,
KC_X = 0x2D,
KC_C = 0x2E,
KC_V = 0x2F,
KC_B = 0x30,
KC_N = 0x31,
KC_M = 0x32,
KC_COMMA = 0x33,
KC_PERIOD = 0x34, // . on main keyboard
KC_SLASH = 0x35, // / on main keyboard
KC_RSHIFT = 0x36,
KC_MULTIPLY = 0x37, // * on numeric keypad
KC_LMENU = 0x38, // left Alt
KC_SPACE = 0x39,
KC_CAPITAL = 0x3A,
KC_F1 = 0x3B,
KC_F2 = 0x3C,
KC_F3 = 0x3D,
KC_F4 = 0x3E,
KC_F5 = 0x3F,
KC_F6 = 0x40,
KC_F7 = 0x41,
KC_F8 = 0x42,
KC_F9 = 0x43,
KC_F10 = 0x44,
KC_NUMLOCK = 0x45,
KC_SCROLL = 0x46, // Scroll Lock
KC_NUMPAD7 = 0x47,
KC_NUMPAD8 = 0x48,
KC_NUMPAD9 = 0x49,
KC_SUBTRACT = 0x4A, // - on numeric keypad
KC_NUMPAD4 = 0x4B,
KC_NUMPAD5 = 0x4C,
KC_NUMPAD6 = 0x4D,
KC_ADD = 0x4E, // + on numeric keypad
KC_NUMPAD1 = 0x4F,
KC_NUMPAD2 = 0x50,
KC_NUMPAD3 = 0x51,
KC_NUMPAD0 = 0x52,
KC_DECIMAL = 0x53, // . on numeric keypad
KC_OEM_102 = 0x56, // < > | on UK/Germany keyboards
KC_F11 = 0x57,
KC_F12 = 0x58,
KC_F13 = 0x64, // (NEC PC98)
KC_F14 = 0x65, // (NEC PC98)
KC_F15 = 0x66, // (NEC PC98)
KC_KANA = 0x70, // (Japanese keyboard)
KC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards
KC_CONVERT = 0x79, // (Japanese keyboard)
KC_NOCONVERT = 0x7B, // (Japanese keyboard)
KC_YEN = 0x7D, // (Japanese keyboard)
KC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards
KC_NUMPADEQUALS= 0x8D, // = on numeric keypad (NEC PC98)
KC_PREVTRACK = 0x90, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
KC_AT = 0x91, // (NEC PC98)
KC_COLON = 0x92, // (NEC PC98)
KC_UNDERLINE = 0x93, // (NEC PC98)
KC_KANJI = 0x94, // (Japanese keyboard)
KC_STOP = 0x95, // (NEC PC98)
KC_AX = 0x96, // (Japan AX)
KC_UNLABELED = 0x97, // (J3100)
KC_NEXTTRACK = 0x99, // Next Track
KC_NUMPADENTER = 0x9C, // Enter on numeric keypad
KC_RCONTROL = 0x9D,
KC_MUTE = 0xA0, // Mute
KC_CALCULATOR = 0xA1, // Calculator
KC_PLAYPAUSE = 0xA2, // Play / Pause
KC_MEDIASTOP = 0xA4, // Media Stop
KC_VOLUMEDOWN = 0xAE, // Volume -
KC_VOLUMEUP = 0xB0, // Volume +
KC_WEBHOME = 0xB2, // Web home
KC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98)
KC_DIVIDE = 0xB5, // / on numeric keypad
KC_SYSRQ = 0xB7,
KC_RMENU = 0xB8, // right Alt
KC_PAUSE = 0xC5, // Pause
KC_HOME = 0xC7, // Home on arrow keypad
KC_UP = 0xC8, // UpArrow on arrow keypad
KC_PGUP = 0xC9, // PgUp on arrow keypad
KC_LEFT = 0xCB, // LeftArrow on arrow keypad
KC_RIGHT = 0xCD, // RightArrow on arrow keypad
KC_END = 0xCF, // End on arrow keypad
KC_DOWN = 0xD0, // DownArrow on arrow keypad
KC_PGDOWN = 0xD1, // PgDn on arrow keypad
KC_INSERT = 0xD2, // Insert on arrow keypad
KC_DELETE = 0xD3, // Delete on arrow keypad
KC_LWIN = 0xDB, // Left Windows key
KC_RWIN = 0xDC, // Right Windows key
KC_APPS = 0xDD, // AppMenu key
KC_POWER = 0xDE, // System Power
KC_SLEEP = 0xDF, // System Sleep
KC_WAKE = 0xE3, // System Wake
KC_WEBSEARCH = 0xE5, // Web Search
KC_WEBFAVORITES= 0xE6, // Web Favorites
KC_WEBREFRESH = 0xE7, // Web Refresh
KC_WEBSTOP = 0xE8, // Web Stop
KC_WEBFORWARD = 0xE9, // Web Forward
KC_WEBBACK = 0xEA, // Web Back
KC_MYCOMPUTER = 0xEB, // My Computer
KC_MAIL = 0xEC, // Mail
KC_MEDIASELECT = 0xED // Media Select
};
/**
Specialised for key events
*/
class _OISExport KeyEvent : public EventArg
{
public:
KeyEvent(Object* obj, KeyCode kc, unsigned int txt) : EventArg(obj), key(kc), text(txt) {}
virtual ~KeyEvent() {}
//! KeyCode of event
KeyCode key;
//! Text character, depends on current TextTranslationMode
unsigned int text;
};
/**
To recieve buffered keyboard input, derive a class from this, and implement the
methods here. Then set the call back to your Keyboard instance with Keyboard::setEventCallback
*/
class _OISExport KeyListener
{
public:
virtual ~KeyListener() {}
virtual bool keyPressed(const KeyEvent &arg) = 0;
virtual bool keyReleased(const KeyEvent &arg) = 0;
};
/**
Keyboard base class. To be implemented by specific system (ie. DirectX Keyboard)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport Keyboard : public Object
{
public:
virtual ~Keyboard() {};
/**
@remarks
Returns true if key is donwn
@param key
A KeyCode to check
*/
virtual bool isKeyDown(KeyCode key) const = 0;
/**
@remarks
Register/unregister a Keyboard Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param keyListener
Send a pointer to a class derived from KeyListener or 0 to clear the callback
*/
virtual void setEventCallback(KeyListener *keyListener) { mListener = keyListener;}
/**
@remarks
Returns currently set callback.. or 0
*/
KeyListener* getEventCallback() const {return mListener;}
//! TextTranslation Mode
enum TextTranslationMode
{
Off,
Unicode,
Ascii
};
/**
@remarks
Enable extra processing to translate KC_*** to an
actual text character based off of locale. Different
managers may implement none or all. Check the
translation mode after setting to be sure
@param mode
Off, Unicode, Ascii
*/
virtual void setTextTranslation(TextTranslationMode mode);
/**
@remarks
Returns current translation mode
*/
TextTranslationMode getTextTranslation() const {return mTextMode;}
/**
@remarks
Translates KeyCode to string representation.
For example, KC_ENTER will be "Enter" - Locale
specific of course.
@param kc
KeyCode to convert
@returns
The string as determined from the current locale
*/
virtual const std::string& getAsString(KeyCode kc) = 0;
//! Enum of bit position of modifer
enum Modifier
{
Shift = 0x0000001,
Ctrl = 0x0000010,
Alt = 0x0000100
};
/**
@remarks
Check modifier status
*/
bool isModifierDown(Modifier mod) const;
/**
@remarks
Copies the state of the keys into the sent buffer
(in the form of 1 is down and 0 is up)
*/
virtual void copyKeyStates(char keys[256]) const = 0;
protected:
Keyboard(const std::string &vendor, bool buffered, int devID, InputManager* creator)
: Object(vendor, OISKeyboard, buffered, devID, creator),
mModifiers(0), mListener(0), mTextMode(Unicode) {}
//! Bit field that holds status of Alt, Ctrl, Shift
unsigned int mModifiers;
//! Used for buffered/actionmapping callback
KeyListener *mListener;
//! The current translation mode
TextTranslationMode mTextMode;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Keyboard_H
#define OIS_Keyboard_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
//! Keyboard scan codes
enum KeyCode
{
KC_UNASSIGNED = 0x00,
KC_ESCAPE = 0x01,
KC_1 = 0x02,
KC_2 = 0x03,
KC_3 = 0x04,
KC_4 = 0x05,
KC_5 = 0x06,
KC_6 = 0x07,
KC_7 = 0x08,
KC_8 = 0x09,
KC_9 = 0x0A,
KC_0 = 0x0B,
KC_MINUS = 0x0C, // - on main keyboard
KC_EQUALS = 0x0D,
KC_BACK = 0x0E, // backspace
KC_TAB = 0x0F,
KC_Q = 0x10,
KC_W = 0x11,
KC_E = 0x12,
KC_R = 0x13,
KC_T = 0x14,
KC_Y = 0x15,
KC_U = 0x16,
KC_I = 0x17,
KC_O = 0x18,
KC_P = 0x19,
KC_LBRACKET = 0x1A,
KC_RBRACKET = 0x1B,
KC_RETURN = 0x1C, // Enter on main keyboard
KC_LCONTROL = 0x1D,
KC_A = 0x1E,
KC_S = 0x1F,
KC_D = 0x20,
KC_F = 0x21,
KC_G = 0x22,
KC_H = 0x23,
KC_J = 0x24,
KC_K = 0x25,
KC_L = 0x26,
KC_SEMICOLON = 0x27,
KC_APOSTROPHE = 0x28,
KC_GRAVE = 0x29, // accent
KC_LSHIFT = 0x2A,
KC_BACKSLASH = 0x2B,
KC_Z = 0x2C,
KC_X = 0x2D,
KC_C = 0x2E,
KC_V = 0x2F,
KC_B = 0x30,
KC_N = 0x31,
KC_M = 0x32,
KC_COMMA = 0x33,
KC_PERIOD = 0x34, // . on main keyboard
KC_SLASH = 0x35, // / on main keyboard
KC_RSHIFT = 0x36,
KC_MULTIPLY = 0x37, // * on numeric keypad
KC_LMENU = 0x38, // left Alt
KC_SPACE = 0x39,
KC_CAPITAL = 0x3A,
KC_F1 = 0x3B,
KC_F2 = 0x3C,
KC_F3 = 0x3D,
KC_F4 = 0x3E,
KC_F5 = 0x3F,
KC_F6 = 0x40,
KC_F7 = 0x41,
KC_F8 = 0x42,
KC_F9 = 0x43,
KC_F10 = 0x44,
KC_NUMLOCK = 0x45,
KC_SCROLL = 0x46, // Scroll Lock
KC_NUMPAD7 = 0x47,
KC_NUMPAD8 = 0x48,
KC_NUMPAD9 = 0x49,
KC_SUBTRACT = 0x4A, // - on numeric keypad
KC_NUMPAD4 = 0x4B,
KC_NUMPAD5 = 0x4C,
KC_NUMPAD6 = 0x4D,
KC_ADD = 0x4E, // + on numeric keypad
KC_NUMPAD1 = 0x4F,
KC_NUMPAD2 = 0x50,
KC_NUMPAD3 = 0x51,
KC_NUMPAD0 = 0x52,
KC_DECIMAL = 0x53, // . on numeric keypad
KC_OEM_102 = 0x56, // < > | on UK/Germany keyboards
KC_F11 = 0x57,
KC_F12 = 0x58,
KC_F13 = 0x64, // (NEC PC98)
KC_F14 = 0x65, // (NEC PC98)
KC_F15 = 0x66, // (NEC PC98)
KC_KANA = 0x70, // (Japanese keyboard)
KC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards
KC_CONVERT = 0x79, // (Japanese keyboard)
KC_NOCONVERT = 0x7B, // (Japanese keyboard)
KC_YEN = 0x7D, // (Japanese keyboard)
KC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards
KC_NUMPADEQUALS= 0x8D, // = on numeric keypad (NEC PC98)
KC_PREVTRACK = 0x90, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
KC_AT = 0x91, // (NEC PC98)
KC_COLON = 0x92, // (NEC PC98)
KC_UNDERLINE = 0x93, // (NEC PC98)
KC_KANJI = 0x94, // (Japanese keyboard)
KC_STOP = 0x95, // (NEC PC98)
KC_AX = 0x96, // (Japan AX)
KC_UNLABELED = 0x97, // (J3100)
KC_NEXTTRACK = 0x99, // Next Track
KC_NUMPADENTER = 0x9C, // Enter on numeric keypad
KC_RCONTROL = 0x9D,
KC_MUTE = 0xA0, // Mute
KC_CALCULATOR = 0xA1, // Calculator
KC_PLAYPAUSE = 0xA2, // Play / Pause
KC_MEDIASTOP = 0xA4, // Media Stop
KC_VOLUMEDOWN = 0xAE, // Volume -
KC_VOLUMEUP = 0xB0, // Volume +
KC_WEBHOME = 0xB2, // Web home
KC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98)
KC_DIVIDE = 0xB5, // / on numeric keypad
KC_SYSRQ = 0xB7,
KC_RMENU = 0xB8, // right Alt
KC_PAUSE = 0xC5, // Pause
KC_HOME = 0xC7, // Home on arrow keypad
KC_UP = 0xC8, // UpArrow on arrow keypad
KC_PGUP = 0xC9, // PgUp on arrow keypad
KC_LEFT = 0xCB, // LeftArrow on arrow keypad
KC_RIGHT = 0xCD, // RightArrow on arrow keypad
KC_END = 0xCF, // End on arrow keypad
KC_DOWN = 0xD0, // DownArrow on arrow keypad
KC_PGDOWN = 0xD1, // PgDn on arrow keypad
KC_INSERT = 0xD2, // Insert on arrow keypad
KC_DELETE = 0xD3, // Delete on arrow keypad
KC_LWIN = 0xDB, // Left Windows key
KC_RWIN = 0xDC, // Right Windows key
KC_APPS = 0xDD, // AppMenu key
KC_POWER = 0xDE, // System Power
KC_SLEEP = 0xDF, // System Sleep
KC_WAKE = 0xE3, // System Wake
KC_WEBSEARCH = 0xE5, // Web Search
KC_WEBFAVORITES= 0xE6, // Web Favorites
KC_WEBREFRESH = 0xE7, // Web Refresh
KC_WEBSTOP = 0xE8, // Web Stop
KC_WEBFORWARD = 0xE9, // Web Forward
KC_WEBBACK = 0xEA, // Web Back
KC_MYCOMPUTER = 0xEB, // My Computer
KC_MAIL = 0xEC, // Mail
KC_MEDIASELECT = 0xED // Media Select
};
/**
Specialised for key events
*/
class _OISExport KeyEvent : public EventArg
{
public:
KeyEvent(Object* obj, KeyCode kc, unsigned int txt) : EventArg(obj), key(kc), text(txt) {}
virtual ~KeyEvent() {}
//! KeyCode of event
KeyCode key;
//! Text character, depends on current TextTranslationMode
unsigned int text;
};
/**
To recieve buffered keyboard input, derive a class from this, and implement the
methods here. Then set the call back to your Keyboard instance with Keyboard::setEventCallback
*/
class _OISExport KeyListener
{
public:
virtual ~KeyListener() {}
virtual bool keyPressed(const KeyEvent &arg) = 0;
virtual bool keyReleased(const KeyEvent &arg) = 0;
};
/**
Keyboard base class. To be implemented by specific system (ie. DirectX Keyboard)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport Keyboard : public Object
{
public:
virtual ~Keyboard() {};
/**
@remarks
Returns true if key is donwn
@param key
A KeyCode to check
*/
virtual bool isKeyDown(KeyCode key) const = 0;
/**
@remarks
Register/unregister a Keyboard Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param keyListener
Send a pointer to a class derived from KeyListener or 0 to clear the callback
*/
virtual void setEventCallback(KeyListener *keyListener) { mListener = keyListener;}
/**
@remarks
Returns currently set callback.. or 0
*/
KeyListener* getEventCallback() const {return mListener;}
//! TextTranslation Mode
enum TextTranslationMode
{
Off,
Unicode,
Ascii
};
/**
@remarks
Enable extra processing to translate KC_*** to an
actual text character based off of locale. Different
managers may implement none or all. Check the
translation mode after setting to be sure
@param mode
Off, Unicode, Ascii
*/
virtual void setTextTranslation(TextTranslationMode mode);
/**
@remarks
Returns current translation mode
*/
TextTranslationMode getTextTranslation() const {return mTextMode;}
/**
@remarks
Translates KeyCode to string representation.
For example, KC_ENTER will be "Enter" - Locale
specific of course.
@param kc
KeyCode to convert
@returns
The string as determined from the current locale
*/
virtual const std::string& getAsString(KeyCode kc) = 0;
//! Enum of bit position of modifer
enum Modifier
{
Shift = 0x0000001,
Ctrl = 0x0000010,
Alt = 0x0000100
};
/**
@remarks
Check modifier status
*/
bool isModifierDown(Modifier mod) const;
/**
@remarks
Copies the state of the keys into the sent buffer
(in the form of 1 is down and 0 is up)
*/
virtual void copyKeyStates(char keys[256]) const = 0;
protected:
Keyboard(const std::string &vendor, bool buffered, int devID, InputManager* creator)
: Object(vendor, OISKeyboard, buffered, devID, creator),
mModifiers(0), mListener(0), mTextMode(Unicode) {}
//! Bit field that holds status of Alt, Ctrl, Shift
unsigned int mModifiers;
//! Used for buffered/actionmapping callback
KeyListener *mListener;
//! The current translation mode
TextTranslationMode mTextMode;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Mouse_H
#define OIS_Mouse_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
//! Button ID for mouse devices
enum MouseButtonID
{
MB_Left = 0, MB_Right, MB_Middle,
MB_Button3, MB_Button4, MB_Button5, MB_Button6, MB_Button7
};
/**
Represents the state of the mouse
All members are valid for both buffered and non buffered mode
*/
class _OISExport MouseState
{
public:
MouseState() : width(50), height(50), buttons(0) {};
/** Represents the height/width of your display area.. used if mouse clipping
or mouse grabbed in case of X11 - defaults to 50.. Make sure to set this
and change when your size changes.. */
mutable int width, height;
//! X Axis component
Axis X;
//! Y Axis Component
Axis Y;
//! Z Axis Component
Axis Z;
//! represents all buttons - bit position indicates button down
int buttons;
//! Button down test
inline bool buttonDown( MouseButtonID button ) const
{
return ((buttons & ( 1L << button )) == 0) ? false : true;
}
//! Clear all the values
void clear()
{
X.clear();
Y.clear();
Z.clear();
buttons = 0;
}
};
/** Specialised for mouse events */
class _OISExport MouseEvent : public EventArg
{
public:
MouseEvent( Object *obj, const MouseState &ms ) : EventArg(obj), state(ms) {}
virtual ~MouseEvent() {}
//! The state of the mouse - including buttons and axes
const MouseState &state;
private:
// Prevent copying.
MouseEvent(const MouseEvent&);
MouseEvent& operator=(MouseEvent);
};
/**
To recieve buffered mouse input, derive a class from this, and implement the
methods here. Then set the call back to your Mouse instance with Mouse::setEventCallback
*/
class _OISExport MouseListener
{
public:
virtual ~MouseListener() {}
virtual bool mouseMoved( const MouseEvent &arg ) = 0;
virtual bool mousePressed( const MouseEvent &arg, MouseButtonID id ) = 0;
virtual bool mouseReleased( const MouseEvent &arg, MouseButtonID id ) = 0;
};
/**
Mouse base class. To be implemented by specific system (ie. DirectX Mouse)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport Mouse : public Object
{
public:
virtual ~Mouse() {}
/**
@remarks
Register/unregister a Mouse Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param mouseListener
Send a pointer to a class derived from MouseListener or 0 to clear the callback
*/
virtual void setEventCallback( MouseListener *mouseListener ) {mListener = mouseListener;}
/** @remarks Returns currently set callback.. or 0 */
MouseListener* getEventCallback() const {return mListener;}
/** @remarks Returns the state of the mouse - is valid for both buffered and non buffered mode */
const MouseState& getMouseState() const { return mState; }
protected:
Mouse(const std::string &vendor, bool buffered, int devID, InputManager* creator)
: Object(vendor, OISMouse, buffered, devID, creator), mListener(0) {}
//! The state of the mouse
MouseState mState;
//! Used for buffered/actionmapping callback
MouseListener *mListener;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Mouse_H
#define OIS_Mouse_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
//! Button ID for mouse devices
enum MouseButtonID
{
MB_Left = 0, MB_Right, MB_Middle,
MB_Button3, MB_Button4, MB_Button5, MB_Button6, MB_Button7
};
/**
Represents the state of the mouse
All members are valid for both buffered and non buffered mode
*/
class _OISExport MouseState
{
public:
MouseState() : width(50), height(50), buttons(0) {};
/** Represents the height/width of your display area.. used if mouse clipping
or mouse grabbed in case of X11 - defaults to 50.. Make sure to set this
and change when your size changes.. */
mutable int width, height;
//! X Axis component
Axis X;
//! Y Axis Component
Axis Y;
//! Z Axis Component
Axis Z;
//! represents all buttons - bit position indicates button down
int buttons;
//! Button down test
inline bool buttonDown( MouseButtonID button ) const
{
return ((buttons & ( 1L << button )) == 0) ? false : true;
}
//! Clear all the values
void clear()
{
X.clear();
Y.clear();
Z.clear();
buttons = 0;
}
};
/** Specialised for mouse events */
class _OISExport MouseEvent : public EventArg
{
public:
MouseEvent( Object *obj, const MouseState &ms ) : EventArg(obj), state(ms) {}
virtual ~MouseEvent() {}
//! The state of the mouse - including buttons and axes
const MouseState &state;
private:
// Prevent copying.
MouseEvent(const MouseEvent&);
MouseEvent& operator=(MouseEvent);
};
/**
To recieve buffered mouse input, derive a class from this, and implement the
methods here. Then set the call back to your Mouse instance with Mouse::setEventCallback
*/
class _OISExport MouseListener
{
public:
virtual ~MouseListener() {}
virtual bool mouseMoved( const MouseEvent &arg ) = 0;
virtual bool mousePressed( const MouseEvent &arg, MouseButtonID id ) = 0;
virtual bool mouseReleased( const MouseEvent &arg, MouseButtonID id ) = 0;
};
/**
Mouse base class. To be implemented by specific system (ie. DirectX Mouse)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport Mouse : public Object
{
public:
virtual ~Mouse() {}
/**
@remarks
Register/unregister a Mouse Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param mouseListener
Send a pointer to a class derived from MouseListener or 0 to clear the callback
*/
virtual void setEventCallback( MouseListener *mouseListener ) {mListener = mouseListener;}
/** @remarks Returns currently set callback.. or 0 */
MouseListener* getEventCallback() const {return mListener;}
/** @remarks Returns the state of the mouse - is valid for both buffered and non buffered mode */
const MouseState& getMouseState() const { return mState; }
protected:
Mouse(const std::string &vendor, bool buffered, int devID, InputManager* creator)
: Object(vendor, OISMouse, buffered, devID, creator), mListener(0) {}
//! The state of the mouse
MouseState mState;
//! Used for buffered/actionmapping callback
MouseListener *mListener;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_MultiTouch_H
#define OIS_MultiTouch_H
#include "OISObject.h"
#include "OISEvents.h"
#include <set>
#include <vector>
#define OIS_MAX_NUM_TOUCHES 4 // 4 finger touches are probably the highest we'll ever get
namespace OIS
{
/**
Represents the state of the multi-touch device
All members are valid for both buffered and non buffered mode
*/
//! Touch Event type
enum MultiTypeEventTypeID
{
MT_None = 0, MT_Pressed, MT_Released, MT_Moved, MT_Cancelled
};
class _OISExport MultiTouchState
{
public:
MultiTouchState() : width(50), height(50), touchType(MT_None) {};
/** Represents the height/width of your display area.. used if touch clipping
or touch grabbed in case of X11 - defaults to 50.. Make sure to set this
and change when your size changes.. */
mutable int width, height;
//! X Axis component
Axis X;
//! Y Axis Component
Axis Y;
//! Z Axis Component
Axis Z;
int touchType;
inline bool touchIsType( MultiTypeEventTypeID touch ) const
{
return ((touchType & ( 1L << touch )) == 0) ? false : true;
}
//! Clear all the values
void clear()
{
X.clear();
Y.clear();
Z.clear();
touchType = MT_None;
}
};
/** Specialised for multi-touch events */
class _OISExport MultiTouchEvent : public EventArg
{
public:
MultiTouchEvent( Object *obj, const MultiTouchState &ms ) : EventArg(obj), state(ms) {}
virtual ~MultiTouchEvent() {}
//! The state of the touch - including axes
const MultiTouchState &state;
};
/**
To receive buffered touch input, derive a class from this, and implement the
methods here. Then set the call back to your MultiTouch instance with MultiTouch::setEventCallback
*/
class _OISExport MultiTouchListener
{
public:
virtual ~MultiTouchListener() {}
virtual bool touchMoved( const MultiTouchEvent &arg ) = 0;
virtual bool touchPressed( const MultiTouchEvent &arg ) = 0;
virtual bool touchReleased( const MultiTouchEvent &arg ) = 0;
virtual bool touchCancelled( const MultiTouchEvent &arg ) = 0;
};
/**
MultiTouch base class. To be implemented by specific system (ie. iPhone UITouch)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport MultiTouch : public Object
{
public:
virtual ~MultiTouch() {}
/**
@remarks
Register/unregister a MultiTouch Listener - Only one allowed for simplicity. If broadcasting
is necessary, just broadcast from the callback you registered.
@param touchListener
Send a pointer to a class derived from MultiTouchListener or 0 to clear the callback
*/
virtual void setEventCallback( MultiTouchListener *touchListener ) {mListener = touchListener;}
/** @remarks Returns currently set callback.. or 0 */
MultiTouchListener* getEventCallback() {return mListener;}
/** @remarks Clear out the set of input states. Should be called after input has been processed by the application */
void clearStates(void) { mStates.clear(); }
/** @remarks Returns the state of the touch - is valid for both buffered and non buffered mode */
std::vector<MultiTouchState> getMultiTouchStates() const { return mStates; }
/** @remarks Returns the first n touch states. Useful if you know your app only needs to
process n touches. The return value is a vector to allow random access */
const std::vector<MultiTouchState> getFirstNTouchStates(int n) {
std::vector<MultiTouchState> states;
for( unsigned int i = 0; i < mStates.size(); i++ ) {
if(!(mStates[i].touchIsType(MT_None))) {
states.push_back(mStates[i]);
}
}
return states;
}
/** @remarks Returns the first n touch states. Useful if you know your app only needs to
process n touches. The return value is a vector to allow random access */
const std::vector<MultiTouchState> getMultiTouchStatesOfType(MultiTypeEventTypeID type) {
std::vector<MultiTouchState> states;
for( unsigned int i = 0; i < mStates.size(); i++ ) {
if(mStates[i].touchIsType(type)) {
states.push_back(mStates[i]);
}
}
return states;
}
protected:
MultiTouch(const std::string &vendor, bool buffered, int devID, InputManager* creator)
: Object(vendor, OISMultiTouch, buffered, devID, creator), mListener(0) {}
//! The state of the touch device, implemented in a vector to store the state from each finger touch
std::vector<MultiTouchState> mStates;
//! Used for buffered/actionmapping callback
MultiTouchListener *mListener;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_MultiTouch_H
#define OIS_MultiTouch_H
#include "OISObject.h"
#include "OISEvents.h"
#include <set>
#include <vector>
#define OIS_MAX_NUM_TOUCHES 4 // 4 finger touches are probably the highest we'll ever get
namespace OIS
{
/**
Represents the state of the multi-touch device
All members are valid for both buffered and non buffered mode
*/
//! Touch Event type
enum MultiTypeEventTypeID
{
MT_None = 0, MT_Pressed, MT_Released, MT_Moved, MT_Cancelled
};
class _OISExport MultiTouchState
{
public:
MultiTouchState() : width(50), height(50), touchType(MT_None) {};
/** Represents the height/width of your display area.. used if touch clipping
or touch grabbed in case of X11 - defaults to 50.. Make sure to set this
and change when your size changes.. */
mutable int width, height;
//! X Axis component
Axis X;
//! Y Axis Component
Axis Y;
//! Z Axis Component
Axis Z;
int touchType;
inline bool touchIsType( MultiTypeEventTypeID touch ) const
{
return ((touchType & ( 1L << touch )) == 0) ? false : true;
}
//! Clear all the values
void clear()
{
X.clear();
Y.clear();
Z.clear();
touchType = MT_None;
}
};
/** Specialised for multi-touch events */
class _OISExport MultiTouchEvent : public EventArg
{
public:
MultiTouchEvent( Object *obj, const MultiTouchState &ms ) : EventArg(obj), state(ms) {}
virtual ~MultiTouchEvent() {}
//! The state of the touch - including axes
const MultiTouchState &state;
};
/**
To receive buffered touch input, derive a class from this, and implement the
methods here. Then set the call back to your MultiTouch instance with MultiTouch::setEventCallback
*/
class _OISExport MultiTouchListener
{
public:
virtual ~MultiTouchListener() {}
virtual bool touchMoved( const MultiTouchEvent &arg ) = 0;
virtual bool touchPressed( const MultiTouchEvent &arg ) = 0;
virtual bool touchReleased( const MultiTouchEvent &arg ) = 0;
virtual bool touchCancelled( const MultiTouchEvent &arg ) = 0;
};
/**
MultiTouch base class. To be implemented by specific system (ie. iPhone UITouch)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport MultiTouch : public Object
{
public:
virtual ~MultiTouch() {}
/**
@remarks
Register/unregister a MultiTouch Listener - Only one allowed for simplicity. If broadcasting
is necessary, just broadcast from the callback you registered.
@param touchListener
Send a pointer to a class derived from MultiTouchListener or 0 to clear the callback
*/
virtual void setEventCallback( MultiTouchListener *touchListener ) {mListener = touchListener;}
/** @remarks Returns currently set callback.. or 0 */
MultiTouchListener* getEventCallback() {return mListener;}
/** @remarks Clear out the set of input states. Should be called after input has been processed by the application */
void clearStates(void) { mStates.clear(); }
/** @remarks Returns the state of the touch - is valid for both buffered and non buffered mode */
std::vector<MultiTouchState> getMultiTouchStates() const { return mStates; }
/** @remarks Returns the first n touch states. Useful if you know your app only needs to
process n touches. The return value is a vector to allow random access */
const std::vector<MultiTouchState> getFirstNTouchStates(int n) {
std::vector<MultiTouchState> states;
for( unsigned int i = 0; i < mStates.size(); i++ ) {
if(!(mStates[i].touchIsType(MT_None))) {
states.push_back(mStates[i]);
}
}
return states;
}
/** @remarks Returns the first n touch states. Useful if you know your app only needs to
process n touches. The return value is a vector to allow random access */
const std::vector<MultiTouchState> getMultiTouchStatesOfType(MultiTypeEventTypeID type) {
std::vector<MultiTouchState> states;
for( unsigned int i = 0; i < mStates.size(); i++ ) {
if(mStates[i].touchIsType(type)) {
states.push_back(mStates[i]);
}
}
return states;
}
protected:
MultiTouch(const std::string &vendor, bool buffered, int devID, InputManager* creator)
: Object(vendor, OISMultiTouch, buffered, devID, creator), mListener(0) {}
//! The state of the touch device, implemented in a vector to store the state from each finger touch
std::vector<MultiTouchState> mStates;
//! Used for buffered/actionmapping callback
MultiTouchListener *mListener;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Object_H
#define OIS_Object_H
#include "OISPrereqs.h"
#include "OISInterface.h"
namespace OIS
{
/** The base class of all input types. */
class _OISExport Object
{
public:
virtual ~Object() {}
/** @remarks Get the type of device */
Type type() const { return mType; }
/** @remarks Get the vender string name */
const std::string& vendor() const { return mVendor; }
/** @remarks Get buffered mode - true is buffered, false otherwise */
virtual bool buffered() const { return mBuffered; }
/** @remarks Returns this input object's creator */
InputManager* getCreator() const { return mCreator; }
/** @remarks Sets buffered mode */
virtual void setBuffered(bool buffered) = 0;
/** @remarks Used for updating call once per frame before checking state or to update events */
virtual void capture() = 0;
/** @remarks This may/may not) differentiate the different controllers based on (for instance) a port number (useful for console InputManagers) */
virtual int getID() const {return mDevID;}
/**
@remarks
If available, get an interface to write to some devices.
Examples include, turning on and off LEDs, ForceFeedback, etc
@param type
The type of interface you are looking for
*/
virtual Interface* queryInterface(Interface::IType type) = 0;
/** @remarks Internal... Do not call this directly. */
virtual void _initialize() = 0;
protected:
Object(const std::string &vendor, Type iType, bool buffered,
int devID, InputManager* creator) :
mVendor(vendor),
mType(iType),
mBuffered(buffered),
mDevID(devID),
mCreator(creator) {}
//! Vendor name if applicable/known
std::string mVendor;
//! Type of controller object
Type mType;
//! Buffered flag
bool mBuffered;
//! Not fully implemented yet
int mDevID;
//! The creator who created this object
InputManager* mCreator;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Object_H
#define OIS_Object_H
#include "OISPrereqs.h"
#include "OISInterface.h"
namespace OIS
{
/** The base class of all input types. */
class _OISExport Object
{
public:
virtual ~Object() {}
/** @remarks Get the type of device */
Type type() const { return mType; }
/** @remarks Get the vender string name */
const std::string& vendor() const { return mVendor; }
/** @remarks Get buffered mode - true is buffered, false otherwise */
virtual bool buffered() const { return mBuffered; }
/** @remarks Returns this input object's creator */
InputManager* getCreator() const { return mCreator; }
/** @remarks Sets buffered mode */
virtual void setBuffered(bool buffered) = 0;
/** @remarks Used for updating call once per frame before checking state or to update events */
virtual void capture() = 0;
/** @remarks This may/may not) differentiate the different controllers based on (for instance) a port number (useful for console InputManagers) */
virtual int getID() const {return mDevID;}
/**
@remarks
If available, get an interface to write to some devices.
Examples include, turning on and off LEDs, ForceFeedback, etc
@param type
The type of interface you are looking for
*/
virtual Interface* queryInterface(Interface::IType type) = 0;
/** @remarks Internal... Do not call this directly. */
virtual void _initialize() = 0;
protected:
Object(const std::string &vendor, Type iType, bool buffered,
int devID, InputManager* creator) :
mVendor(vendor),
mType(iType),
mBuffered(buffered),
mDevID(devID),
mCreator(creator) {}
//! Vendor name if applicable/known
std::string mVendor;
//! Type of controller object
Type mType;
//! Buffered flag
bool mBuffered;
//! Not fully implemented yet
int mDevID;
//! The creator who created this object
InputManager* mCreator;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Prereqs_H
#define OIS_Prereqs_H
//----------------------------------------------------------------------------//
// This Header File contains: forward declared classes
// * Forward Declarations of all public API classes
// * Several typedef's used around the library
// * Base class component types
// * Preprocessor definitons
//----------------------------------------------------------------------------//
//-------------- Common STL Containers ---------------------------------------//
#include <vector>
#include <string>
#include <map>
#include "OISConfig.h"
// Default is blank for most OS's
#define _OISExport
//-------------- Determine Compiler ---------------------------------
#if defined( _MSC_VER )
# define OIS_MSVC_COMPILER
#elif defined( __GNUC__ )
# if defined( __WIN32__ ) || defined( _WIN32 )
# define OIS_MINGW_COMPILER
# else
# define OIS_GCC_COMPILER
# endif
#elif defined( __BORLANDC__ )
# define OIS_BORLAND_COMPILER
#else
# error No Recognized Compiler!
#endif
// --------------- Determine Operating System Platform ---------------
#if defined( __WIN32__ ) || defined( _WIN32 ) // Windows 2000, XP, ETC
# if defined ( _XBOX )
# define OIS_XBOX_PLATFORM
# else
# define OIS_WIN32_PLATFORM
# if defined( OIS_DYNAMIC_LIB )
# undef _OISExport
//Ignorable Dll interface warning...
# if !defined(OIS_MINGW_COMPILER)
# pragma warning (disable : 4251)
# endif
# if defined( OIS_NONCLIENT_BUILD )
# define _OISExport __declspec( dllexport )
# else
# if defined(OIS_MINGW_COMPILER)
# define _OISExport
# else
# define _OISExport __declspec( dllimport )
# endif
# endif
# endif
# endif
#elif defined( __APPLE_CC__ ) // Apple OS X
// Device Simulator
# if __IPHONE_OS_VERSION_MIN_REQUIRED >= 20201 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000
//# if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000
# define OIS_IPHONE_PLATFORM
# else
# define OIS_APPLE_PLATFORM
# endif
# undef _OISExport
# define _OISExport __attribute__((visibility("default")))
#else //Probably Linux
# define OIS_LINUX_PLATFORM
# include <unistd.h>
#endif
//Is Processor 32 or 64 bits...
#if defined(__x86_64__)
# define OIS_ARCH_64
#else
# define OIS_ARCH_32
#endif
//-------------- Common Classes, Enums, and Typdef's -------------------------//
#define OIS_VERSION_MAJOR 1
#define OIS_VERSION_MINOR 4
#define OIS_VERSION_PATCH 0
#define OIS_VERSION_NAME "1.4.0"
#define OIS_VERSION ((OIS_VERSION_MAJOR << 16) | (OIS_VERSION_MINOR << 8) | OIS_VERSION_PATCH)
namespace OIS
{
//Forward Declarations
class InputManager;
class FactoryCreator;
class Object;
class Keyboard;
class Mouse;
class JoyStick;
class MultiTouch;
class KeyListener;
class MouseListener;
class MultiTouchListener;
class JoyStickListener;
class Interface;
class ForceFeedback;
class Effect;
class Exception;
//! Way to send OS nuetral parameters.. ie OS Window handles, modes, flags
typedef std::multimap<std::string, std::string> ParamList;
//! List of FactoryCreator's
typedef std::vector<FactoryCreator*> FactoryList;
//! Map of FactoryCreator created Objects
typedef std::map<Object*, FactoryCreator*> FactoryCreatedObject;
//! Each Input class has a General Type variable, a form of RTTI
enum Type
{
OISUnknown = 0,
OISKeyboard = 1,
OISMouse = 2,
OISJoyStick = 3,
OISTablet = 4,
OISMultiTouch = 5
};
//! Map of device objects connected and their respective vendors
typedef std::multimap<Type, std::string> DeviceList;
//-------- Shared common components ------------------------//
//! Base type for all device components (button, axis, etc)
enum ComponentType
{
OIS_Unknown = 0,
OIS_Button = 1, //ie. Key, mouse button, joy button, etc
OIS_Axis = 2, //ie. A joystick or mouse axis
OIS_Slider = 3, //
OIS_POV = 4, //ie. Arrow direction keys
OIS_Vector3 = 5 //ie. WiiMote orientation
};
//! Base of all device components (button, axis, etc)
class _OISExport Component
{
public:
Component() : cType(OIS_Unknown) {};
explicit Component(ComponentType type) : cType(type) {};
//! Indicates what type of coponent this is
ComponentType cType;
};
//! Button can be a keyboard key, mouse button, etc
class _OISExport Button : public Component
{
public:
Button() : Component(OIS_Button), pushed(false) {}
explicit Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {}
//! true if pushed, false otherwise
bool pushed;
};
//! Axis component
class _OISExport Axis : public Component
{
public:
Axis() : Component(OIS_Axis), abs(0), rel(0), absOnly(false) {};
//! Absoulte and Relative value components
int abs, rel;
//! Indicates if this Axis only supports Absoulte (ie JoyStick)
bool absOnly;
//! Used internally by OIS
void clear()
{
abs = rel = 0;
}
};
//! A 3D Vector component (perhaps an orientation, as in the WiiMote)
class _OISExport Vector3 : public Component
{
public:
Vector3() {}
Vector3(float _x, float _y, float _z) : Component(OIS_Vector3), x(_x), y(_y), z(_z) {};
//! X component of vector
float x;
//! Y component of vector
float y;
//! Z component of vector
float z;
void clear()
{
x = y = z = 0.0f;
}
};
}
#endif //end if prereq header defined
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Prereqs_H
#define OIS_Prereqs_H
//----------------------------------------------------------------------------//
// This Header File contains: forward declared classes
// * Forward Declarations of all public API classes
// * Several typedef's used around the library
// * Base class component types
// * Preprocessor definitons
//----------------------------------------------------------------------------//
//-------------- Common STL Containers ---------------------------------------//
#include <vector>
#include <string>
#include <map>
#include "OISConfig.h"
// Default is blank for most OS's
#define _OISExport
//-------------- Determine Compiler ---------------------------------
#if defined( _MSC_VER )
# define OIS_MSVC_COMPILER
#elif defined( __GNUC__ )
# if defined( __WIN32__ ) || defined( _WIN32 )
# define OIS_MINGW_COMPILER
# else
# define OIS_GCC_COMPILER
# endif
#elif defined( __BORLANDC__ )
# define OIS_BORLAND_COMPILER
#else
# error No Recognized Compiler!
#endif
// --------------- Determine Operating System Platform ---------------
#if defined( __WIN32__ ) || defined( _WIN32 ) // Windows 2000, XP, ETC
# if defined ( _XBOX )
# define OIS_XBOX_PLATFORM
# else
# define OIS_WIN32_PLATFORM
# if defined( OIS_DYNAMIC_LIB )
# undef _OISExport
//Ignorable Dll interface warning...
# if !defined(OIS_MINGW_COMPILER)
# pragma warning (disable : 4251)
# endif
# if defined( OIS_NONCLIENT_BUILD )
# define _OISExport __declspec( dllexport )
# else
# if defined(OIS_MINGW_COMPILER)
# define _OISExport
# else
# define _OISExport __declspec( dllimport )
# endif
# endif
# endif
# endif
#elif defined( __APPLE_CC__ ) // Apple OS X
// Device Simulator
# if __IPHONE_OS_VERSION_MIN_REQUIRED >= 20201 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000
//# if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000
# define OIS_IPHONE_PLATFORM
# else
# define OIS_APPLE_PLATFORM
# endif
# undef _OISExport
# define _OISExport __attribute__((visibility("default")))
#else //Probably Linux
# define OIS_LINUX_PLATFORM
# include <unistd.h>
#endif
//Is Processor 32 or 64 bits...
#if defined(__x86_64__)
# define OIS_ARCH_64
#else
# define OIS_ARCH_32
#endif
//-------------- Common Classes, Enums, and Typdef's -------------------------//
#define OIS_VERSION_MAJOR 1
#define OIS_VERSION_MINOR 4
#define OIS_VERSION_PATCH 0
#define OIS_VERSION_NAME "1.4.0"
#define OIS_VERSION ((OIS_VERSION_MAJOR << 16) | (OIS_VERSION_MINOR << 8) | OIS_VERSION_PATCH)
namespace OIS
{
//Forward Declarations
class InputManager;
class FactoryCreator;
class Object;
class Keyboard;
class Mouse;
class JoyStick;
class MultiTouch;
class KeyListener;
class MouseListener;
class MultiTouchListener;
class JoyStickListener;
class Interface;
class ForceFeedback;
class Effect;
class Exception;
//! Way to send OS nuetral parameters.. ie OS Window handles, modes, flags
typedef std::multimap<std::string, std::string> ParamList;
//! List of FactoryCreator's
typedef std::vector<FactoryCreator*> FactoryList;
//! Map of FactoryCreator created Objects
typedef std::map<Object*, FactoryCreator*> FactoryCreatedObject;
//! Each Input class has a General Type variable, a form of RTTI
enum Type
{
OISUnknown = 0,
OISKeyboard = 1,
OISMouse = 2,
OISJoyStick = 3,
OISTablet = 4,
OISMultiTouch = 5
};
//! Map of device objects connected and their respective vendors
typedef std::multimap<Type, std::string> DeviceList;
//-------- Shared common components ------------------------//
//! Base type for all device components (button, axis, etc)
enum ComponentType
{
OIS_Unknown = 0,
OIS_Button = 1, //ie. Key, mouse button, joy button, etc
OIS_Axis = 2, //ie. A joystick or mouse axis
OIS_Slider = 3, //
OIS_POV = 4, //ie. Arrow direction keys
OIS_Vector3 = 5 //ie. WiiMote orientation
};
//! Base of all device components (button, axis, etc)
class _OISExport Component
{
public:
Component() : cType(OIS_Unknown) {};
explicit Component(ComponentType type) : cType(type) {};
//! Indicates what type of coponent this is
ComponentType cType;
};
//! Button can be a keyboard key, mouse button, etc
class _OISExport Button : public Component
{
public:
Button() : Component(OIS_Button), pushed(false) {}
explicit Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {}
//! true if pushed, false otherwise
bool pushed;
};
//! Axis component
class _OISExport Axis : public Component
{
public:
Axis() : Component(OIS_Axis), abs(0), rel(0), absOnly(false) {};
//! Absoulte and Relative value components
int abs, rel;
//! Indicates if this Axis only supports Absoulte (ie JoyStick)
bool absOnly;
//! Used internally by OIS
void clear()
{
abs = rel = 0;
}
};
//! A 3D Vector component (perhaps an orientation, as in the WiiMote)
class _OISExport Vector3 : public Component
{
public:
Vector3() {}
Vector3(float _x, float _y, float _z) : Component(OIS_Vector3), x(_x), y(_y), z(_z) {};
//! X component of vector
float x;
//! Y component of vector
float y;
//! Z component of vector
float z;
void clear()
{
x = y = z = 0.0f;
}
};
}
#endif //end if prereq header defined
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_SDLInputManager_H
#define OIS_SDLInputManager_H
#include "OISInputManager.h"
#include "SDL/SDLPrereqs.h"
namespace OIS
{
/**
SDL Input Manager wrapper
*/
class SDLInputManager : public InputManager
{
public:
SDLInputManager();
virtual ~SDLInputManager();
/** @copydoc InputManager::inputSystemName */
virtual const std::string& inputSystemName() { return iName; }
/** @copydoc InputManager::numJoysticks */
virtual int numJoySticks();
/** @copydoc InputManager::numMice */
virtual int numMice();
/** @copydoc InputManager::numKeyBoards */
virtual int numKeyboards();
/** @copydoc InputManager::createInputObject */
Object* createInputObject( Type iType, bool bufferMode );
/** @copydoc InputManager::destroyInputObject */
void destroyInputObject( Object* obj );
/** @copydoc InputManager::_initialize */
void _initialize( ParamList &paramList );
//Utility methods to coordinate between mouse and keyboard grabbing
bool _getGrabMode() {return mGrabbed;};
void _setGrabMode(bool grabbed) {mGrabbed = grabbed;}
protected:
//! internal class method for dealing with param list
void _parseConfigSettings( ParamList &paramList );
//! internal class method for finding attached devices
void _enumerateDevices();
static const std::string iName;
bool mGrabbed;
};
}
#endif
/*
The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no event will
the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_SDLInputManager_H
#define OIS_SDLInputManager_H
#include "OISInputManager.h"
#include "SDL/SDLPrereqs.h"
namespace OIS
{
/**
SDL Input Manager wrapper
*/
class SDLInputManager : public InputManager
{
public:
SDLInputManager();
virtual ~SDLInputManager();
/** @copydoc InputManager::inputSystemName */
virtual const std::string& inputSystemName() { return iName; }
/** @copydoc InputManager::numJoysticks */
virtual int numJoySticks();
/** @copydoc InputManager::numMice */
virtual int numMice();
/** @copydoc InputManager::numKeyBoards */
virtual int numKeyboards();
/** @copydoc InputManager::createInputObject */
Object* createInputObject( Type iType, bool bufferMode );
/** @copydoc InputManager::destroyInputObject */
void destroyInputObject( Object* obj );
/** @copydoc InputManager::_initialize */
void _initialize( ParamList &paramList );
//Utility methods to coordinate between mouse and keyboard grabbing
bool _getGrabMode() {return mGrabbed;};
void _setGrabMode(bool grabbed) {mGrabbed = grabbed;}
protected:
//! internal class method for dealing with param list
void _parseConfigSettings( ParamList &paramList );
//! internal class method for finding attached devices
void _enumerateDevices();
static const std::string iName;
bool mGrabbed;
};
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment