From: <eg...@us...> - 2007-08-16 21:15:05
|
Revision: 662 http://opengate.svn.sourceforge.net/opengate/?rev=662&view=rev Author: egore Date: 2007-08-16 14:15:05 -0700 (Thu, 16 Aug 2007) Log Message: ----------- ois, again and again Added Paths: ----------- branches/ogsector/externals/ois-1.0/src/Makefile.am branches/ogsector/externals/ois-1.0/src/OISEffect.cpp branches/ogsector/externals/ois-1.0/src/OISForceFeedback.cpp branches/ogsector/externals/ois-1.0/src/OISInputManager.cpp branches/ogsector/externals/ois-1.0/src/OISJoyStick.cpp branches/ogsector/externals/ois-1.0/src/OISKeyboard.cpp branches/ogsector/externals/ois-1.0/src/win32/ branches/ogsector/externals/ois-1.0/src/win32/Win32ForceFeedback.cpp branches/ogsector/externals/ois-1.0/src/win32/Win32InputManager.cpp branches/ogsector/externals/ois-1.0/src/win32/Win32JoyStick.cpp branches/ogsector/externals/ois-1.0/src/win32/Win32KeyBoard.cpp branches/ogsector/externals/ois-1.0/src/win32/Win32Mouse.cpp Added: branches/ogsector/externals/ois-1.0/src/Makefile.am =================================================================== --- branches/ogsector/externals/ois-1.0/src/Makefile.am (rev 0) +++ branches/ogsector/externals/ois-1.0/src/Makefile.am 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,19 @@ +INCLUDES = $(STLPORT_CFLAGS) -I$(top_srcdir)/includes $(CFLAGS) -I/usr/X11R6/include + +lib_LTLIBRARIES=libOIS.la +libOIS_la_SOURCES = OISInputManager.cpp \ + OISObject.cpp \ + OISEffect.cpp \ + OISJoyStick.cpp \ + OISKeyboard.cpp \ + OISForceFeedback.cpp \ + ./linux/EventHelpers.cpp \ + ./linux/LinuxInputManager.cpp \ + ./linux/LinuxJoyStickEvents.cpp \ + ./linux/LinuxForceFeedback.cpp \ + ./linux/LinuxKeyboard.cpp \ + ./linux/LinuxMouse.cpp + +libOIS_la_LDFLAGS = -release @PACKAGE_VERSION@ +libOIS_la_LIBADD = $(STLPORT_LIBS) -L/usr/X11R6/lib -lX11 -lXaw + Property changes on: branches/ogsector/externals/ois-1.0/src/Makefile.am ___________________________________________________________________ Name: svn:executable + * Added: branches/ogsector/externals/ois-1.0/src/OISEffect.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/OISEffect.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/OISEffect.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,93 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "OISEffect.h" +#include "OISException.h" + +using namespace OIS; + +//VC7.1 had a problem with these not getting included.. +//Perhaps a case of a crazy extreme optimizer :/ (moved to header) +//const unsigned int Effect::OIS_INFINITE = 0xFFFFFFFF; + +//------------------------------------------------------------------------------// +Effect::Effect() : + force(UnknownForce), + type(Unknown), + effect(0), + axes(1) +{ +} + +//------------------------------------------------------------------------------// +Effect::Effect(EForce ef, EType et) : + force(ef), + type(et), + direction(North), + trigger_button(-1), + trigger_interval(0), + replay_length(Effect::OIS_INFINITE), + replay_delay(0), + _handle(-1), + axes(1) +{ + effect = 0; + + switch( ef ) + { + case ConstantForce: effect = new ConstantEffect(); break; + case RampForce: effect = new RampEffect(); break; + case PeriodicForce: effect = new PeriodicEffect(); break; + case ConditionalForce: effect = new ConditionalEffect(); break; + default: break; + } +} + +//------------------------------------------------------------------------------// +Effect::~Effect() +{ + delete effect; +} + +//------------------------------------------------------------------------------// +ForceEffect* Effect::getForceEffect() const +{ + //If no effect was created in constructor, then we raise an error here + if( effect == 0 ) + OIS_EXCEPT( E_NotSupported, "Requested ForceEffect is null!" ); + + return effect; +} + +//------------------------------------------------------------------------------// +void Effect::setNumAxes(short nAxes) +{ + //Can only be set before a handle was assigned (effect created) + if( _handle != -1 ) + axes = nAxes; +} + +//------------------------------------------------------------------------------// +short Effect::getNumAxes() const +{ + return axes; +} Property changes on: branches/ogsector/externals/ois-1.0/src/OISEffect.cpp ___________________________________________________________________ Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/OISForceFeedback.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/OISForceFeedback.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/OISForceFeedback.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,42 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "OISForceFeedback.h" +#include "OISException.h" + +using namespace OIS; + +//-------------------------------------------------------------// +void ForceFeedback::_addEffectTypes( Effect::EForce force, Effect::EType type ) +{ + if( force == Effect::UnknownForce || type == Effect::Unknown ) + OIS_EXCEPT( E_General, "Unknown Force||Type was added too effect list..." ); + + mSupportedEffects[force] = type; +} + +//-------------------------------------------------------------// +const ForceFeedback::SupportedEffectList& + ForceFeedback::getSupportedEffects() const +{ + return mSupportedEffects; +} Property changes on: branches/ogsector/externals/ois-1.0/src/OISForceFeedback.cpp ___________________________________________________________________ Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/OISInputManager.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/OISInputManager.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/OISInputManager.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,103 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "OISInputManager.h" +#include "OISException.h" +#include <sstream> + +//Bring in correct Header / InputManager for current build platform +#if defined OIS_SDL_PLATFORM +# include "SDL/SDLInputManager.h" +#elif defined OIS_WIN32_PLATFORM +# include "win32/Win32InputManager.h" +#elif defined OIS_LINUX_PLATFORM +# include "linux/LinuxInputManager.h" +#elif defined OIS_APPLE_PLATFORM +# include "mac/MacInputManager.h" +#elif defined OIS_XBOX_PLATFORM +# include "xbox/XBoxInputManager.h" +#endif + +using namespace OIS; + +const char* gVersionName = OIS_VERSION_NAME; + +//----------------------------------------------------------------------------// +unsigned int InputManager::getVersionNumber() +{ + return OIS_VERSION; +} + +//----------------------------------------------------------------------------// +const char* InputManager::getVersionName() +{ + return gVersionName; +} + +//----------------------------------------------------------------------------// +InputManager* InputManager::createInputSystem( std::size_t windowhandle ) +{ + ParamList pl; + std::ostringstream wnd; + wnd << windowhandle; + pl.insert(std::make_pair( std::string("WINDOW"), wnd.str() )); + + return createInputSystem( pl ); +} + +//----------------------------------------------------------------------------// +InputManager* InputManager::createInputSystem( ParamList ¶mList ) +{ + InputManager* im = 0; + +#if defined OIS_SDL_PLATFORM + im = new SDLInputManager(); +#elif defined OIS_WIN32_PLATFORM + im = new Win32InputManager(); +#elif defined OIS_XBOX_PLATFORM + im = new XBoxInputManager(); +#elif defined OIS_LINUX_PLATFORM + im = new LinuxInputManager(); +#elif defined OIS_APPLE_PLATFORM + im = new MacInputManager(); +#else + OIS_EXCEPT(E_General, "No platform library.. check build platform defines!"); +#endif + + try + { + im->_initialize(paramList); + } + catch(...) + { + delete im; + throw; //rethrow + } + + return im; +} + +//----------------------------------------------------------------------------// +void InputManager::destroyInputSystem(InputManager* manager) +{ + delete manager; +} Property changes on: branches/ogsector/externals/ois-1.0/src/OISInputManager.cpp ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/OISJoyStick.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/OISJoyStick.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/OISJoyStick.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,30 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "OISJoyStick.h" + +//VC7.1 had a problem with these not getting included.. +//Perhaps a case of a crazy extreme optimizer :/ (moved to header) +// The minimal axis value +//const int OIS::JoyStick::MIN_AXIS = -32767; +// The maximum axis value +//const int OIS::JoyStick::MAX_AXIS = 32768; Property changes on: branches/ogsector/externals/ois-1.0/src/OISJoyStick.cpp ___________________________________________________________________ Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/OISKeyboard.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/OISKeyboard.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/OISKeyboard.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,49 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "OISKeyboard.h" +#include "OISException.h" + +using namespace OIS; +//----------------------------------------------------------------------// +Keyboard::Keyboard() : mModifiers(0), listener(0), mTextMode(Unicode) +{ +} + +//----------------------------------------------------------------------// +void Keyboard::setTextTranslation( TextTranslationMode mode ) +{ + mTextMode = mode; +} + +//----------------------------------------------------------------------// +bool Keyboard::isModifierDown( Modifier mod ) +{ +#if defined(OIS_MSVC_COMPILER) + #pragma warning (push) + #pragma warning (disable : 4800) +#endif + return (mModifiers & mod); +#if defined(OIS_MSVC_COMPILER) + #pragma warning (pop) +#endif +} Property changes on: branches/ogsector/externals/ois-1.0/src/OISKeyboard.cpp ___________________________________________________________________ Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/win32/Win32ForceFeedback.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/win32/Win32ForceFeedback.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/win32/Win32ForceFeedback.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,334 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "Win32/Win32ForceFeedback.h" +#include "OISException.h" +#include <Math.h> + +#if defined (_DEBUG) + #include <sstream> +#endif + +using namespace OIS; + +//--------------------------------------------------------------// +Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* joy) : + mHandles(0), mJoyStick(joy) +{ +} + +//--------------------------------------------------------------// +Win32ForceFeedback::~Win32ForceFeedback() +{ + //Get the effect - if it exists + for(EffectList::iterator i = mEffectList.begin(); i != mEffectList.end(); ++i ) + { + LPDIRECTINPUTEFFECT dxEffect = i->second; + if( dxEffect ) + dxEffect->Unload(); + } + + mEffectList.clear(); +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::upload( const Effect* effect ) +{ + switch( effect->force ) + { + case OIS::Effect::ConstantForce: _updateConstantEffect(effect); break; + case OIS::Effect::RampForce: _updateRampEffect(effect); break; + case OIS::Effect::PeriodicForce: _updatePeriodicEffect(effect); break; + case OIS::Effect::ConditionalForce: _updateConditionalEffect(effect); break; + //case OIS::Effect::CustomForce: _updateCustomEffect(effect); break; + default: OIS_EXCEPT(E_NotImplemented, "Requested Force not Implemented yet, sorry!"); break; + } +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::modify( const Effect* eff ) +{ + //Modifying is essentially the same as an upload, so, just reuse that function + upload(eff); +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::remove( const Effect* eff ) +{ + //Get the effect - if it exists + EffectList::iterator i = mEffectList.find(eff->_handle); + if( i != mEffectList.end() ) + { + LPDIRECTINPUTEFFECT dxEffect = i->second; + if( dxEffect ) + { + dxEffect->Stop(); + //We care about the return value - as the effect might not + //have been unlaoded + if( SUCCEEDED(dxEffect->Unload()) ) + mEffectList.erase(i); + } + else + mEffectList.erase(i); + } +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::setMasterGain( float level ) +{ + //Between 0 - 10,000 + int gain_level = (int)(10000.0f * level); + + if( gain_level > 10000 ) + gain_level = 10000; + else if( gain_level < 0 ) + gain_level = 0; + + DIPROPDWORD DIPropGain; + DIPropGain.diph.dwSize = sizeof(DIPropGain); + DIPropGain.diph.dwHeaderSize = sizeof(DIPROPHEADER); + DIPropGain.diph.dwObj = 0; + DIPropGain.diph.dwHow = DIPH_DEVICE; + DIPropGain.dwData = gain_level; + + mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph); +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::setAutoCenterMode( bool auto_on ) +{ + //DI Property DIPROPAUTOCENTER_OFF = 0, 1 is on + DIPROPDWORD DIPropAutoCenter; + DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter); + DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER); + DIPropAutoCenter.diph.dwObj = 0; + DIPropAutoCenter.diph.dwHow = DIPH_DEVICE; + DIPropAutoCenter.dwData = auto_on; + + //hr = + mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph); +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::_updateConstantEffect( const Effect* effect ) +{ + DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; + LONG rglDirection[2] = { 0, 0 }; + DICONSTANTFORCE cf; + DIEFFECT diEffect; + + //Currently only support 1 axis + //if( effect->getNumAxes() == 1 ) + cf.lMagnitude = static_cast<ConstantEffect*>(effect->getForceEffect())->level; + + _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICONSTANTFORCE), &cf, effect); + _upload(GUID_ConstantForce, &diEffect, effect); +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::_updateRampEffect( const Effect* effect ) +{ + DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; + LONG rglDirection[2] = { 0, 0 }; + DIRAMPFORCE rf; + DIEFFECT diEffect; + + //Currently only support 1 axis + rf.lStart = static_cast<RampEffect*>(effect->getForceEffect())->startLevel; + rf.lEnd = static_cast<RampEffect*>(effect->getForceEffect())->endLevel; + + _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DIRAMPFORCE), &rf, effect); + _upload(GUID_RampForce, &diEffect, effect); +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::_updatePeriodicEffect( const Effect* effect ) +{ + DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; + LONG rglDirection[2] = { 0, 0 }; + DIPERIODIC pf; + DIEFFECT diEffect; + + //Currently only support 1 axis + pf.dwMagnitude = static_cast<PeriodicEffect*>(effect->getForceEffect())->magnitude; + pf.lOffset = static_cast<PeriodicEffect*>(effect->getForceEffect())->offset; + pf.dwPhase = static_cast<PeriodicEffect*>(effect->getForceEffect())->phase; + pf.dwPeriod = static_cast<PeriodicEffect*>(effect->getForceEffect())->period; + + _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DIPERIODIC), &pf, effect); + + switch( effect->type ) + { + case OIS::Effect::Square: _upload(GUID_Square, &diEffect, effect); break; + case OIS::Effect::Triangle: _upload(GUID_Triangle, &diEffect, effect); break; + case OIS::Effect::Sine: _upload(GUID_Sine, &diEffect, effect); break; + case OIS::Effect::SawToothUp: _upload(GUID_SawtoothUp, &diEffect, effect); break; + case OIS::Effect::SawToothDown: _upload(GUID_SawtoothDown, &diEffect, effect); break; + default: break; + } +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::_updateConditionalEffect( const Effect* effect ) +{ + DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; + LONG rglDirection[2] = { 0, 0 }; + DICONDITION cf; + DIEFFECT diEffect; + + cf.lOffset = static_cast<ConditionalEffect*>(effect->getForceEffect())->deadband; + cf.lPositiveCoefficient = static_cast<ConditionalEffect*>(effect->getForceEffect())->rightCoeff; + cf.lNegativeCoefficient = static_cast<ConditionalEffect*>(effect->getForceEffect())->leftCoeff; + cf.dwPositiveSaturation = static_cast<ConditionalEffect*>(effect->getForceEffect())->rightSaturation; + cf.dwNegativeSaturation = static_cast<ConditionalEffect*>(effect->getForceEffect())->leftSaturation; + cf.lDeadBand = static_cast<ConditionalEffect*>(effect->getForceEffect())->deadband; + + _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICONDITION), &cf, effect); + + switch( effect->type ) + { + case OIS::Effect::Friction: _upload(GUID_Friction, &diEffect, effect); break; + case OIS::Effect::Damper: _upload(GUID_Damper, &diEffect, effect); break; + case OIS::Effect::Inertia: _upload(GUID_Inertia, &diEffect, effect); break; + case OIS::Effect::Spring: _upload(GUID_Spring, &diEffect, effect); break; + default: break; + } +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::_updateCustomEffect( const Effect* /*effect*/ ) +{ + //DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; + //LONG rglDirection[2] = { 0, 0 }; + //DICUSTOMFORCE cf; + //DIEFFECT diEffect; + //cf.cChannels = 0; + //cf.dwSamplePeriod = 0; + //cf.cSamples = 0; + //cf.rglForceData = 0; + //_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICUSTOMFORCE), &cf, effect); + //_upload(GUID_CustomForce, &diEffect, effect); +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::_setCommonProperties( + DIEFFECT* diEffect, DWORD* rgdwAxes, + LONG* rglDirection, DWORD struct_size, + LPVOID struct_type, const Effect* effect ) +{ + ZeroMemory(diEffect, sizeof(DIEFFECT)); + + diEffect->dwSize = sizeof(DIEFFECT); + diEffect->dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + diEffect->dwDuration = effect->replay_length; + diEffect->dwSamplePeriod = 0; + diEffect->dwGain = DI_FFNOMINALMAX; + diEffect->dwTriggerButton = DIEB_NOTRIGGER; + diEffect->dwTriggerRepeatInterval = 0; + diEffect->cAxes = effect->getNumAxes(); + diEffect->rgdwAxes = rgdwAxes; + diEffect->rglDirection = rglDirection; + diEffect->lpEnvelope = 0; + diEffect->cbTypeSpecificParams = struct_size; + diEffect->lpvTypeSpecificParams = struct_type; + diEffect->dwStartDelay = effect->replay_delay; +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::_upload( GUID guid, DIEFFECT* diEffect, const Effect* effect) +{ + LPDIRECTINPUTEFFECT dxEffect = 0; + + //Get the effect - if it exists + EffectList::iterator i = mEffectList.find(effect->_handle); + //It has been created already + if( i != mEffectList.end() ) + dxEffect = i->second; + else //This effect has not yet been created - generate a handle + effect->_handle = mHandles++; + + if( dxEffect == 0 ) + { + //This effect has not yet been created, so create it + HRESULT hr = mJoyStick->CreateEffect(guid, diEffect, &dxEffect, NULL); + if(SUCCEEDED(hr)) + { + mEffectList[effect->_handle] = dxEffect; + dxEffect->Start(INFINITE,0); + } + else if( hr == DIERR_DEVICEFULL ) + OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!"); + else + OIS_EXCEPT(E_General, "Unknown error creating effect->.."); + } + else + { + //ToDo -- Update the Effect + HRESULT hr = dxEffect->SetParameters( diEffect, DIEP_DIRECTION | + DIEP_DURATION | DIEP_ENVELOPE | DIEP_STARTDELAY | DIEP_TRIGGERBUTTON | + DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS | DIEP_START ); + + if(FAILED(hr)) OIS_EXCEPT(E_InvalidParam, "Error updating device!"); + } +} + +//--------------------------------------------------------------// +void Win32ForceFeedback::_addEffectSupport( LPCDIEFFECTINFO pdei ) +{ + //Determine what the effect is and how it corresponds to our OIS's Enums + //We could save the GUIDs too, however, we will just use the predefined + //ones later + if( pdei->guid == GUID_ConstantForce ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Constant ); + else if( pdei->guid == GUID_Triangle ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Triangle ); + else if( pdei->guid == GUID_Spring ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Spring ); + else if( pdei->guid == GUID_Friction ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Friction ); + else if( pdei->guid == GUID_Square ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Square ); + else if( pdei->guid == GUID_Sine ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Sine ); + else if( pdei->guid == GUID_SawtoothUp ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothUp ); + else if( pdei->guid == GUID_SawtoothDown ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothDown ); + else if( pdei->guid == GUID_Damper ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Damper ); + else if( pdei->guid == GUID_Inertia ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Inertia ); + else if( pdei->guid == GUID_CustomForce ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Custom ); + else if( pdei->guid == GUID_RampForce ) + _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Ramp ); +#if defined (_DEBUG) + //Only care about this for Debugging Purposes + //else + //{ + // std::ostringstream ss; + // ss << "Win32ForceFeedback, DirectInput8 Effect not found. Reported as: " + // << pdei->tszName; + // OIS_EXCEPT( E_General, ss.str().c_str()); + //} +#endif +} Property changes on: branches/ogsector/externals/ois-1.0/src/win32/Win32ForceFeedback.cpp ___________________________________________________________________ Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/win32/Win32InputManager.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/win32/Win32InputManager.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/win32/Win32InputManager.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,208 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "Win32/Win32InputManager.h" +#include "Win32/Win32Keyboard.h" +#include "Win32/Win32Mouse.h" +#include "Win32/Win32JoyStick.h" +#include "OISException.h" + +using namespace OIS; + +const std::string Win32InputManager::iName = "Win32"; + +//--------------------------------------------------------------------------------// +Win32InputManager::Win32InputManager() +{ + hWnd = 0; + mDirectInput = 0; + + kbSettings = 0; + mouseSettings = 0; + joySettings = 0; + + joySticks = 0; +} + +//--------------------------------------------------------------------------------// +Win32InputManager::~Win32InputManager() +{ + if( mDirectInput ) + { + mDirectInput->Release(); + mDirectInput = 0; + } +} + +//--------------------------------------------------------------------------------// +void Win32InputManager::_initialize( ParamList ¶mList ) +{ + HINSTANCE hInst = 0; + HRESULT hr; + + //TODO 64 bit proof this little conversion xxx wip + //First of all, get the Windows Handle and Instance + ParamList::iterator i = paramList.find("WINDOW"); + if( i == paramList.end() ) + OIS_EXCEPT( E_InvalidParam, "Win32InputManager::Win32InputManager >> No HWND found!" ); + + hWnd = (HWND)strtoul(i->second.c_str(), 0, 10); + + if( IsWindow(hWnd) == 0 ) + OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> The sent HWND is not valid!"); + + hInst = GetModuleHandle(0); + + //Create the device + hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL ); + if (FAILED(hr)) + OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> Not able to init DirectX8 Input!"); + + //Ok, now we have DirectInput, parse whatever extra settings were sent to us + _parseConfigSettings( paramList ); + _enumerateDevices(); +} + +//--------------------------------------------------------------------------------// +void Win32InputManager::_parseConfigSettings( ParamList ¶mList ) +{ + //Here we pick up settings such as a device's cooperation mode + std::map<std::string, DWORD> temp; + temp["DISCL_BACKGROUND"] = DISCL_BACKGROUND; + temp["DISCL_EXCLUSIVE"] = DISCL_EXCLUSIVE; + temp["DISCL_FOREGROUND"] = DISCL_FOREGROUND; + temp["DISCL_NONEXCLUSIVE"] = DISCL_NONEXCLUSIVE; + temp["DISCL_NOWINKEY"] = DISCL_NOWINKEY; + + //Check for pairs: ie. ("w32_keyboard","DISCL_NOWINKEY")("w32_keyboard","DISCL_FOREGROUND") + ParamList::iterator i = paramList.begin(), e = paramList.end(); + for( ; i != e; ++i ) + { + if( i->first == "w32_keyboard" ) + kbSettings |= temp[i->second]; + else if( i->first == "w32_mouse" ) + mouseSettings |= temp[i->second]; + else if( i->first == "w32_joystick" ) + joySettings |= temp[i->second]; + } + if( kbSettings == 0 ) kbSettings = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY; + if( mouseSettings == 0 ) mouseSettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE; + if( joySettings == 0 ) joySettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE; +} + +//--------------------------------------------------------------------------------// +void Win32InputManager::_enumerateDevices() +{ + //Enumerate all attached devices + mDirectInput->EnumDevices(NULL, _DIEnumKbdCallback, this, DIEDFL_ATTACHEDONLY); +} + +//--------------------------------------------------------------------------------// +BOOL CALLBACK Win32InputManager::_DIEnumKbdCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) +{ + Win32InputManager *_this_ = static_cast<Win32InputManager*>(pvRef); + if( GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK || + GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD || + GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_1STPERSON || + GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DRIVING || + GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_FLIGHT) + { + JoyStickInfo jsInfo; + jsInfo.deviceID = lpddi->guidInstance; + jsInfo.vendor = lpddi->tszInstanceName; + jsInfo.devId = _this_->joySticks; + + _this_->joySticks++; + + _this_->unusedJoyStickList.push_back( jsInfo ); + } + + return DIENUM_CONTINUE; +} + +//--------------------------------------------------------------------------------// +int Win32InputManager::numJoySticks() +{ + return joySticks; +} + +//--------------------------------------------------------------------------------// +int Win32InputManager::numMice() +{ + return 1; +} + +//--------------------------------------------------------------------------------// +int Win32InputManager::numKeyboards() +{ + return 1; +} + +//----------------------------------------------------------------------------// +Object* Win32InputManager::createInputObject( Type iType, bool bufferMode ) +{ + Object* obj = 0; + + switch( iType ) + { + case OISKeyboard: obj = new Win32Keyboard( this, mDirectInput, bufferMode, kbSettings ); break; + case OISMouse: obj = new Win32Mouse( this, mDirectInput, bufferMode, mouseSettings ); break; + case OISJoyStick: + { + //Find a JoyStick not in use + JoyStickInfoList::iterator i = unusedJoyStickList.begin(); + if( i != unusedJoyStickList.end() ) + { + obj = new Win32JoyStick( this, mDirectInput, bufferMode, joySettings, (*i) ); + unusedJoyStickList.erase(i); + break; + } + OIS_EXCEPT(E_InputDeviceNonExistant, "No Unused JoyStick could be found!"); + } + default: OIS_EXCEPT( E_InputDeviceNotSupported, "Type not implemented"); + } + + try { + obj->_initialize(); + } + catch(...) { + delete obj; + throw; //rethrow + } + + return obj; +} + +//----------------------------------------------------------------------------// +void Win32InputManager::destroyInputObject( Object* obj ) +{ + if( obj == 0 ) + return; + + //If it was a numbered device... add it back to availiable list + if( obj->type() == OISJoyStick ) + { + unusedJoyStickList.push_back(((Win32JoyStick*)obj)->_getJoyInfo()); + } + + delete obj; +} Property changes on: branches/ogsector/externals/ois-1.0/src/win32/Win32InputManager.cpp ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/win32/Win32JoyStick.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/win32/Win32JoyStick.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/win32/Win32JoyStick.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,405 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "Win32/Win32JoyStick.h" +#include "Win32/Win32InputManager.h" +#include "Win32/Win32ForceFeedback.h" + +#include "OISEvents.h" +#include "OISException.h" + +#include <cassert> + +using namespace OIS; + +//--------------------------------------------------------------------------------------------------// +Win32JoyStick::Win32JoyStick( InputManager* creator, IDirectInput8* pDI, + bool buffered, DWORD coopSettings, + const JoyStickInfo &info ) +{ + mCreator = creator; + mBuffered = buffered; + mDirectInput = pDI; + coopSetting = coopSettings; + mJoyStick = 0; + mType = OISJoyStick; + + deviceGuid = info.deviceID; + mVendor = info.vendor; + mDevID = info.devId; + + listener = 0; + ff_device = 0; +} + +//--------------------------------------------------------------------------------------------------// +Win32JoyStick::~Win32JoyStick() +{ + delete ff_device; + + if(mJoyStick) + { + mJoyStick->Unacquire(); + mJoyStick->Release(); + mJoyStick = 0; + } +} + +//--------------------------------------------------------------------------------------------------// +void Win32JoyStick::_initialize() +{ + //Clear old state + mState.mAxes.clear(); + + delete ff_device; + ff_device = 0; + + DIPROPDWORD dipdw; + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = JOYSTICK_DX_BUFFERSIZE; + + if(FAILED(mDirectInput->CreateDevice(deviceGuid, &mJoyStick, NULL))) + OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!"); + + if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2))) + OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!"); + + HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle(); + + if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting))) + OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!"); + + if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) ) + OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set buffer size property" ); + + //Enumerate all axes/buttons/sliders/etc before aquiring + _enumerate(); + + mState.clear(); + + capture(); +} + +//--------------------------------------------------------------------------------------------------// +void Win32JoyStick::_enumerate() +{ + //We can check force feedback here too + DIDEVCAPS DIJoyCaps; + DIJoyCaps.dwSize = sizeof(DIDEVCAPS); + mJoyStick->GetCapabilities(&DIJoyCaps); + + numAxes = (short)DIJoyCaps.dwAxes; + numButtons = (short)DIJoyCaps.dwButtons; + numHats = (short)DIJoyCaps.dwPOVs; + + mState.mAxes.resize(numAxes); + + //Reset the axis mapping enumeration value + _AxisNumber = 0; + + //Enumerate Force Feedback (if any) + mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL); + + //Enumerate and set axis constraints (and check FF Axes) + mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS); +} + +//--------------------------------------------------------------------------------------------------// +BOOL CALLBACK Win32JoyStick::DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) +{ + Win32JoyStick* _this = (Win32JoyStick*)pvRef; + + //Setup mappings + DIPROPPOINTER diptr; + diptr.diph.dwSize = sizeof(DIPROPPOINTER); + diptr.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diptr.diph.dwHow = DIPH_BYID; + diptr.diph.dwObj = lpddoi->dwType; + //Add the high bit in so that an axis value of zero does not mean a null userdata + diptr.uData = 0x80000000 | _this->_AxisNumber; + + if (FAILED(_this->mJoyStick->SetProperty(DIPROP_APPDATA, &diptr.diph))) + { //If for some reason we could not set needed user data, just ignore this axis + return DIENUM_CONTINUE; + } + + //Increase for next time through + _this->_AxisNumber += 1; + + //Set range + DIPROPRANGE diprg; + diprg.diph.dwSize = sizeof(DIPROPRANGE); + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diprg.diph.dwHow = DIPH_BYID; + diprg.diph.dwObj = lpddoi->dwType; + diprg.lMin = MIN_AXIS; + diprg.lMax = MAX_AXIS; + + if (FAILED(_this->mJoyStick->SetProperty(DIPROP_RANGE, &diprg.diph))) + OIS_EXCEPT( E_General, "Win32JoyStick::_DIEnumDeviceObjectsCallback >> Failed to set min/max range property" ); + + //Check if FF Axes + if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 ) + { + if( _this->ff_device ) + { + //todo - increment force feedback axis count + } + } + + return DIENUM_CONTINUE; +} + +//--------------------------------------------------------------------------------------------------// +BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef) +{ + Win32JoyStick* _this = (Win32JoyStick*)pvRef; + + //Create the FF class after we know there is at least one effect type + if( _this->ff_device == 0 ) + _this->ff_device = new Win32ForceFeedback(_this->mJoyStick); + + _this->ff_device->_addEffectSupport( pdei ); + + return DIENUM_CONTINUE; +} + +//--------------------------------------------------------------------------------------------------// +void Win32JoyStick::capture() +{ + DIDEVICEOBJECTDATA diBuff[JOYSTICK_DX_BUFFERSIZE]; + DWORD entries = JOYSTICK_DX_BUFFERSIZE; + + // Poll the device to read the current state + HRESULT hr = mJoyStick->Poll(); + if( hr == DI_OK ) + hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); + + if( hr != DI_OK ) + { + hr = mJoyStick->Acquire(); + while( hr == DIERR_INPUTLOST ) + hr = mJoyStick->Acquire(); + + // Poll the device to read the current state + mJoyStick->Poll(); + hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); + //Perhaps the user just tabbed away + if( FAILED(hr) ) + return; + } + + bool axisMoved[24] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false}; + bool sliderMoved[4] = {false,false,false,false}; + + //Loop through all the events + for(unsigned int i = 0; i < entries; ++i) + { + //First check to see if event entry is a Axis we enumerated earlier + if( diBuff[i].uAppData != 0xFFFFFFFF && diBuff[i].uAppData > 0 ) + { + int axis = 0x7FFFFFFF & diBuff[i].uAppData; //Mask out the high bit + assert( axis >= 0 && axis < mState.mAxes.size() && "Axis out of range!"); + mState.mAxes[axis].abs = diBuff[i].dwData; + axisMoved[axis] = true; + } + else + { + //DX Only defines macros for the JOYSTICK not JOYSTICK2, so we redeclare them to match what we are using + #undef DIJOFS_BUTTON + #undef DIJOFS_POV + #define DIJOFS_BUTTON(n) (FIELD_OFFSET(DIJOYSTATE2, rgbButtons) + (n)) + #define DIJOFS_POV(n) (FIELD_OFFSET(DIJOYSTATE2, rgdwPOV)+(n)*sizeof(DWORD)) + + #define DIJOFS_SLIDER0(n) (FIELD_OFFSET(DIJOYSTATE2, rglSlider)+(n) * sizeof(LONG)) + #define DIJOFS_SLIDER1(n) (FIELD_OFFSET(DIJOYSTATE2, rglVSlider)+(n) * sizeof(LONG)) + #define DIJOFS_SLIDER2(n) (FIELD_OFFSET(DIJOYSTATE2, rglASlider)+(n) * sizeof(LONG)) + #define DIJOFS_SLIDER3(n) (FIELD_OFFSET(DIJOYSTATE2, rglFSlider)+(n) * sizeof(LONG)) + + //This may seem outof order, but is in order of the way these variables + //are declared in the JoyStick State 2 structure. + switch(diBuff[i].dwOfs) + { + //------ slider -// + case DIJOFS_SLIDER0(0): + sliderMoved[0] = true; + mState.mSliders[0].abX = diBuff[i].dwData; + break; + case DIJOFS_SLIDER0(1): + sliderMoved[0] = true; + mState.mSliders[0].abY = diBuff[i].dwData; + break; + //----- Max 4 POVs Next ---------------// + case DIJOFS_POV(0): + if(!_changePOV(0,diBuff[i])) + return; + break; + case DIJOFS_POV(1): + if(!_changePOV(1,diBuff[i])) + return; + break; + case DIJOFS_POV(2): + if(!_changePOV(2,diBuff[i])) + return; + break; + case DIJOFS_POV(3): + if(!_changePOV(3,diBuff[i])) + return; + break; + case DIJOFS_SLIDER1(0): + sliderMoved[1] = true; + mState.mSliders[1].abX = diBuff[i].dwData; + break; + case DIJOFS_SLIDER1(1): + sliderMoved[1] = true; + mState.mSliders[1].abY = diBuff[i].dwData; + break; + case DIJOFS_SLIDER2(0): + sliderMoved[2] = true; + mState.mSliders[2].abX = diBuff[i].dwData; + break; + case DIJOFS_SLIDER2(1): + sliderMoved[2] = true; + mState.mSliders[2].abY = diBuff[i].dwData; + break; + case DIJOFS_SLIDER3(0): + sliderMoved[3] = true; + mState.mSliders[3].abX = diBuff[i].dwData; + break; + case DIJOFS_SLIDER3(1): + sliderMoved[3] = true; + mState.mSliders[3].abY = diBuff[i].dwData; + break; + //-----------------------------------------// + default: + //Handle Button Events Easily using the DX Offset Macros + if( diBuff[i].dwOfs >= DIJOFS_BUTTON(0) && diBuff[i].dwOfs <= DIJOFS_BUTTON(31) ) + { + if(!_doButtonClick((diBuff[i].dwOfs - DIJOFS_BUTTON(0)), diBuff[i])) + return; + } + break; + } //end case + } //End else + } //end for + + //Check to see if any of the axes values have changed.. if so send events + if( mBuffered && listener && entries > 0 ) + { + JoyStickEvent temp(this, mState); + + //Update axes + for( int i = 0; i < 24; ++i ) + if( axisMoved[i] ) + if( listener->axisMoved( temp, i ) == false ) + return; + + //Now update sliders + for( int i = 0; i < 4; ++i ) + if( sliderMoved[i] ) + if( listener->sliderMoved( temp, i ) == false ) + return; + } +} + +//--------------------------------------------------------------------------------------------------// +bool Win32JoyStick::_doButtonClick( int button, DIDEVICEOBJECTDATA& di ) +{ + if( di.dwData & 0x80 ) + { + mState.buttons |= 1 << button; //turn the bit flag on + if( mBuffered && listener ) + return listener->buttonPressed( JoyStickEvent( this, mState ), button ); + } + else + { + mState.buttons &= ~(1 << button); //turn the bit flag off + if( mBuffered && listener ) + return listener->buttonReleased( JoyStickEvent( this, mState ), button ); + } + + return true; +} + +//--------------------------------------------------------------------------------------------------// +bool Win32JoyStick::_changePOV( int pov, DIDEVICEOBJECTDATA& di ) +{ + //Some drivers report a value of 65,535, instead of \x971, + //for the center position + if(LOWORD(di.dwData) == 0xFFFF) + { + mState.mPOV[pov].direction = Pov::Centered; + } + else + { + switch(di.dwData) + { + case 0: mState.mPOV[pov].direction = Pov::North; break; + case 4500: mState.mPOV[pov].direction = Pov::NorthEast; break; + case 9000: mState.mPOV[pov].direction = Pov::East; break; + case 13500: mState.mPOV[pov].direction = Pov::SouthEast; break; + case 18000: mState.mPOV[pov].direction = Pov::South; break; + case 22500: mState.mPOV[pov].direction = Pov::SouthWest; break; + case 27000: mState.mPOV[pov].direction = Pov::West; break; + case 31500: mState.mPOV[pov].direction = Pov::NorthWest; break; + } + } + + if( mBuffered && listener ) + return listener->povMoved( JoyStickEvent( this, mState ), pov ); + + return true; +} + +//--------------------------------------------------------------------------------------------------// +void Win32JoyStick::setBuffered(bool buffered) +{ + mBuffered = buffered; +} + +//--------------------------------------------------------------------------------------------------// +JoyStickInfo Win32JoyStick::_getJoyInfo() +{ + JoyStickInfo js; + js.deviceID = deviceGuid; + js.devId = mDevID; + js.vendor = mVendor; + + return js; +} + +//--------------------------------------------------------------------------------------------------// +Interface* Win32JoyStick::queryInterface(Interface::IType type) +{ + //Thought about using covariant return type here.. however, + //some devices may allow LED light changing, or other interface stuff + + if( ff_device && type == Interface::ForceFeedback ) + return ff_device; + else + return 0; +} Property changes on: branches/ogsector/externals/ois-1.0/src/win32/Win32JoyStick.cpp ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/win32/Win32KeyBoard.cpp =================================================================== --- branches/ogsector/externals/ois-1.0/src/win32/Win32KeyBoard.cpp (rev 0) +++ branches/ogsector/externals/ois-1.0/src/win32/Win32KeyBoard.cpp 2007-08-16 21:15:05 UTC (rev 662) @@ -0,0 +1,332 @@ +/* +The zlib/libpng License + +Copyright (c) 2006 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. +*/ +#include "Win32/Win32InputManager.h" +#include "Win32/Win32KeyBoard.h" +#include "OISException.h" +#include "OISEvents.h" +#include <sstream> + +using namespace OIS; + +//--------------------------------------------------------------------------------------------------// +Win32Keyboard::Win32Keyboard( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings ) +{ + mCreator = creator; + mBuffered = buffered; + mKeyboard = 0; + mDirectInput = pDI; + coopSetting = coopSettings; + mType = OISKeyboard; + listener = 0; + + //Clear our keyboard state buffer + memset( &KeyBuffer, 0, 256 ); + deadKey = '\0'; +} + +//--------------------------------------------------------------------------------------------------// +void Win32Keyboard::_initialize() +{ + mModifiers = 0; + deadKey = '\0'; + + if(FAILED(mDirectInput->CreateDevice(GUID_SysKeyboard, &mKeyboard, NULL))) + OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> Could not init device!"); + + if(FAILED(mKeyboard->SetDataFormat(&c_dfDIKeyboard))) + OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> format error!"); + + HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle(); + + if(FAILED(mKeyboard->SetCooperativeLevel( hwin, coopSetting))) + OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> coop error!"); + + if( mBuffered ) + { + DIPROPDWORD dipdw; + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = KEYBOARD_DX_BUFFERSIZE; + + if (FAILED(mKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ))) + OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> buffer error!"); + } + + HRESULT hr = mKeyboard->Acquire(); + if(FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO) + OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> aquire error!"); +} + +//--------------------------------------------------------------------------------------------------// +Win32Keyboard::~Win32Keyboard() +{ + if(mKeyboard) + { + mKeyboard->Unacquire(); + mKeyboard->Release(); + mKeyboard = 0; + } +} + +//--------------------------------------------------------------------------------------------------// +void Win32Keyboard::capture() +{ + if( mBuffered ) + _readBuffered(); + else + _read(); +} + +//--------------------------------------------------------------------------------------------------// +void Win32Keyboard::_readBuffered() +{ + DIDEVICEOBJECTDATA diBuff[KEYBOARD_DX_BUFFERSIZE]; + DWORD entries = KEYBOARD_DX_BUFFERSIZE; + HRESULT hr; + //Only one keyboard allowed per app, so static is ok + static bool verifyAfterAltTab = false; + + hr = mKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); + if( hr != DI_OK ) + { + hr = mKeyboard->Acquire(); + if (hr == E_ACCESSDENIED) + verifyAfterAltTab = true; + + while( hr == DIERR_INPUTLOST ) + hr = mKeyboard->Acquire(); + + return; + } + + //Update keyboard and modifier states.. And, if listener, fire events + for(unsigned int i = 0; i < entries; ++i ) + { + //If the listener returns false, that means that we are probably deleted... + //send no more events and just leave as the this pointer is invalid now... + bool ret = true; + KeyCode kc = (KeyCode)diBuff[ i ].dwOfs; + + //Store result in our keyBuffer too + KeyBuffer[kc] = static_cast<unsigned char>(diBuff[ i ].dwData); + + if( diBuff[ i ].dwData & 0x80 ) + { + //Turn on modifier + if( kc == KC_LCONTROL || kc == KC_RCONTROL ) + mModifiers |= Ctrl; + else if( kc == KC_LSHIFT || kc == KC_RSHIFT ) + mModifiers |= Shift; + else if( kc == KC_LMENU || kc == KC_RMENU ) + mModifiers |= Alt; + + if( listener ) + ret = listener->keyPressed( KeyEvent( this, kc, _translateText(kc) ) ); + } + else + { + //Turn off modifier + if( kc == KC_LCONTROL || kc == KC_RCONTROL ) + mModifiers &= ~Ctrl; + else if( kc == KC_LSHIFT || kc == KC_RSHIFT ) + mModifiers &= ~Shift; + else if( kc == KC_LMENU || kc == KC_RMENU ) + mModifiers &= ~Alt; + + if( listener ) + ret = listener->keyReleased( KeyEvent( this, kc, 0 ) ); + } + + //If user returned false from callback, return immediately + if(ret == false) + return; + } + + // If a lost device/access denied was detected, recover gracefully with new events + if(verifyAfterAltTab) + { + bool ret = true; + + //Copy old buffer to temp location to compare against + unsigned char keyBufferCopy[256]; + memcpy(keyBufferCopy, KeyBuffer, 256); + + //Update new state + _read(); + + for (unsigned i = 0; i < 256; i++) + { + if (keyBufferCopy[i] != KeyBuffer[i]) + { + if (listener) + { + if (KeyBuffer[i]) + ret = listener->keyPressed( KeyEvent( this, (KeyCode)i, _translateText((KeyCode)i) ) ); + else + ret = listener->keyReleased( KeyEvent( this, (KeyCode)i, 0 ) ); + } + } + + //If user returned false from callback, return immediately + if(ret == false) + return; + } + + verifyAfterAltTab = false; + } +} + +//--------------------------------------------------------------------------------------------------// +void Win32Keyboard::_read() +{ + HRESULT hr = mKeyboard->GetDeviceState( sizeof(KeyBuffer), &KeyBuffer ); + + if( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED ) + { + hr = mKeyboard->Acquire(); + if (hr != DIERR_OTHERAPPHASPRIO) + mKeyboard->GetDeviceState(sizeof(KeyBuffer), &KeyBuffer); + } + + //Set Shift, Ctrl, Alt + mModifiers = 0; + if( isKeyDown(KC_LCONTROL) || isKeyDown(KC_RCONTROL) ) + mModifiers |= Ctrl; + if( isKeyDown(KC_LSHIFT) || isKeyDown(KC_RSHIFT) ) + mModifiers |= Shift; + if( isKeyDown(KC_LMENU) || isKeyDown(KC_RMENU) ) + mModifiers |= Alt; +} + +//--------------------------------------------------------------------------------------------------// +int Win32Keyboard::_translateText( KeyCode kc ) +{ + if( mTextMode == Off ) + return 0; + + BYTE keyState[256]; + HKL layout = GetKeyboardLayout(0); + if( GetKeyboardState(keyState) == 0 ) + return 0; + + unsigned int vk = MapVirtualKeyEx(kc, 3, layout); + if( vk == 0 ) + return 0; + + unsigned char buff[3] = {0,0,0}; + int ascii = ToAsciiEx(vk, kc, keyState, (LPWORD) buff, 0, layout); + //WCHAR wide[3]; + //int ascii = ToUnicodeEx(vk, kc, keyState, wide, 3, 0, layout); + if(ascii == 1 && deadKey != '\0' ) + { + // A dead key is stored and we have just converted a character key + // Combine the two into a single character + WCHAR wcBuff[3] = {buff[0], deadKey, '\0'}; + WCHAR out[3]; + + deadKey = '\0'; + if(FoldStringW(MAP_PRECOMPOSED, (LPWSTR)wcBuff, 3, (LPWSTR)out, 3)) + return out[0]; + } + else if (ascii == 1) + { // We have a single character + deadKey = '\0'; + return buff[0]; + } + else if(ascii == 2) + { // Convert a non-combining diacritical mark into a combining diacritical mark + // Combining versions range from 0x300 to 0x36F; only 5 (for French) have been mapped below + // http://www.fileformat.info/info/unicode/block/combining_diacritical_marks/images.htm + switch(buff[0]) { + case 0x5E: // Circumflex accent: \xE2 + deadKey = 0x302; break; + case 0x60: // Grave accent: \xE0 + deadKey = 0x300; break; + case 0xA8: // Diaeresis: \xFC + deadKey = 0x308; break; + case 0xB4: // Acute accent: \xE9 + deadKey = 0x301; break; + case 0xB8: // Cedilla: \xE7 + deadKey = 0x327; break; + default: + deadKey = buff[0]; break; + } + } + + return 0; +} + +//--------------------------------------------------------------------------------------------------// +bool Win32Keyboard::isKeyDown( KeyCode key ) +{ + return (KeyBuffer[key] & 0x80) != 0; +} + +//--------------------------------------------------------------------------------------------------// +const std::string& Win32Keyboard::getAsString( KeyCode kc ) +{ + char temp[256]; + + DIPROPSTRING prop; + prop.diph.dwSize = sizeof(DIPROPSTRING); + prop.diph.dwHeaderSize = sizeof(DIPROPHEADER); + prop.diph.dwObj = static_cast<DWORD>(kc); + prop.diph.dwHow = DIPH_BYOFFSET; + + if ( SUCCEEDED( mKeyboard->GetProperty( DIPROP_KEYNAME, &prop.diph ) ) ) + { + // convert the WCHAR in "wsz" to multibyte + if ( WideCharToMultiByte( CP_ACP, 0, prop.wsz, -1, temp, sizeof(temp), NULL, NULL) ) + return mGetString.assign( temp ); + } + + std::stringstream ss; + ss << "Key_" << (int)kc; + return mGetString.assign( ss.str() ); +} + +//--------------------------------------------------------------------------------------------------// +void Win32Keyboard::copyKeyStates( char keys[256] ) +{ + for(int i = 0; i < 256; ++i) + keys[i] = KeyBuffer[i] > 0; //Normalise the DX values (0x80) +} + +//--------------------------------------------------------------------------------------------------// +void Win32Keyboard::setBuffered(bool buffered) +{ + if( buffered != mBuffered ) + { + if(mKeyboard) + { + mKeyboard->Unacquire(); + mKeyboard->Release(); + mKeyboard = 0; + } + + mBuffered = buffered; + _initialize(); + } +} Property changes on: branches/ogsector/externals/ois-1.0/src/win32/Win32KeyBoard.cpp ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-c++src Name: svn:eol-style + native Added: branches/ogsector/externals/ois-1.0/src/win32/Win32Mouse.cpp =================================================================== --- branches/ogsec... [truncated message content] |