From: Oliver O. <fr...@us...> - 2007-07-24 01:00:42
|
Update of /cvsroot/simspark/simspark/spark/utility/ois/win32 In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv13856/win32 Added Files: Tag: projectx Win32ForceFeedback.cpp Win32ForceFeedback.h Win32InputManager.cpp Win32InputManager.h Win32JoyStick.cpp Win32JoyStick.h Win32KeyBoard.cpp Win32KeyBoard.h Win32Mouse.cpp Win32Mouse.h Win32Prereqs.h Log Message: added OIS Library sources --- NEW FILE: Win32InputManager.cpp --- /* 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; } --- NEW FILE: Win32JoyStick.cpp --- /* 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))) OIS_EXCEPT( E_General, "Win32JoyStick::_DIEnumDeviceObjectsCallback >> Failed to set mapping ptr property" ); //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 ) { assert( _this->ff_device && "Force Feedback axis found, but this device did not report any effects?"); 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(30) ) { 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 1, //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; } --- NEW FILE: Win32ForceFeedback.cpp --- /* 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 } --- NEW FILE: Win32ForceFeedback.h --- /* 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. */ #ifndef OIS_Win32ForceFeedBack_H #define OIS_Win32ForceFeedBack_H #include "OISPrereqs.h" #include "OISForceFeedback.h" #include "Win32/Win32Prereqs.h" namespace OIS { class Win32ForceFeedback : public ForceFeedback { Win32ForceFeedback() {} public: Win32ForceFeedback(IDirectInputDevice8* joy); ~Win32ForceFeedback(); /** @copydoc ForceFeedback::upload */ void upload( const Effect* effect ); /** @copydoc ForceFeedback::modify */ void modify( const Effect* effect ); /** @copydoc ForceFeedback::remove */ void remove( const Effect* effect ); /** @copydoc ForceFeedback::setMasterGain */ void setMasterGain( float level ); /** @copydoc ForceFeedback::setAutoCenterMode */ void setAutoCenterMode( bool auto_on ); /** @copydoc ForceFeedback::getFFAxesNumber xxx todo - Actually return correct number */ short getFFAxesNumber() {return 1;} /** @remarks Internal use.. Used during enumeration to build a list of a devices support effects. */ void _addEffectSupport( LPCDIEFFECTINFO pdei ); protected: //Specific Effect Settings void _updateConstantEffect( const Effect* effect ); void _updateRampEffect( const Effect* effect ); void _updatePeriodicEffect( const Effect* effect ); void _updateConditionalEffect( const Effect* effect ); void _updateCustomEffect( const Effect* effect ); //Sets the common properties to all effects void _setCommonProperties( DIEFFECT* diEffect, DWORD* rgdwAxes, LONG* rglDirection, DWORD struct_size, LPVOID struct_type, const Effect* effect ); //Actually do the upload void _upload( GUID, DIEFFECT*, const Effect* ); typedef std::map<int,LPDIRECTINPUTEFFECT> EffectList; EffectList mEffectList; //Simple unique handle creation - allows for upto 2+ million effects //during the lifetime of application. Hopefully, that is enough. int mHandles; IDirectInputDevice8* mJoyStick; }; } #endif //OIS_Win32ForceFeedBack_H --- NEW FILE: Win32Prereqs.h --- /* 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. */ #ifndef _WIN32_INPUTSYSTEM_PREREQS_H #define _WIN32_INPUTSYSTEM_PREREQS_H //Some WIndows Defines #define WIN32_LEAN_AND_MEAN //Using DirectInput8 #define DIRECTINPUT_VERSION 0x0800 #include <windows.h> #include <dinput.h> //! Max number of elements to collect from buffered input #define KEYBOARD_DX_BUFFERSIZE 17 #define MOUSE_DX_BUFFERSIZE 64 #define JOYSTICK_DX_BUFFERSIZE 124 #if defined(OIS_MINGW_COMPILER) # undef FIELD_OFFSET # define FIELD_OFFSET offsetof #endif namespace OIS { class Win32InputManager; class Win32Keyboard; class Win32JoyStick; class Win32Mouse; class Win32ForceFeedback; struct JoyStickInfo { int devId; GUID deviceID; std::string vendor; }; typedef std::vector< JoyStickInfo > JoyStickInfoList; } #endif //_WIN32_INPUTSYSTEM_PREREQS_H --- NEW FILE: Win32InputManager.h --- /* 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. */ #ifndef OIS_Win32InputManager_H #define OIS_Win32InputManager_H #include "OISInputManager.h" #include "Win32/Win32Prereqs.h" namespace OIS { /** "Win32" InputManager specialization - Using DirectInput8 */ class Win32InputManager : public InputManager { public: Win32InputManager(); virtual ~Win32InputManager(); /** @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 ); //! Returns HWND needed by DirectInput Device Object HWND getWindowHandle() { return hWnd; } /** @copydoc InputManager::_initialize */ void _initialize( ParamList ¶mList ); protected: //! internal class method for dealing with param list void _parseConfigSettings( ParamList ¶mList ); //! internal class method for finding attached devices void _enumerateDevices(); static BOOL CALLBACK _DIEnumKbdCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); JoyStickInfoList unusedJoyStickList; static const std::string iName; HWND hWnd; //Direct Input Interface IDirectInput8* mDirectInput; //Used for setting device properties - as read in from paramlist DWORD kbSettings; DWORD mouseSettings; DWORD joySettings; char joySticks; }; } #endif --- NEW FILE: Win32JoyStick.h --- /* 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. */ #ifndef _WIN32_JOYSTICK_H_EADER_ #define _WIN32_JOYSTICK_H_EADER_ #include "OISJoyStick.h" #include "Win32/Win32Prereqs.h" namespace OIS { class Win32JoyStick : public JoyStick { public: Win32JoyStick( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings, const JoyStickInfo &info ); virtual ~Win32JoyStick(); /** @copydoc Object::setBuffered */ virtual void setBuffered(bool buffered); /** @copydoc Object::capture */ virtual void capture(); /** @copydoc Object::queryInterface */ virtual Interface* queryInterface(Interface::IType type); /** @copydoc Object::_initialize */ virtual void _initialize(); /** @remarks For internal use only... Returns a strucure to the manager, to make the device availiable for use again */ JoyStickInfo _getJoyInfo(); protected: Win32JoyStick() {} //! Enumerates all things void _enumerate(); //! Enumerate axis callback static BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); //! Enumerate Force Feedback callback static BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef); bool _doButtonClick( int button, DIDEVICEOBJECTDATA& di ); bool _changePOV( int pov, DIDEVICEOBJECTDATA& di ); IDirectInput8* mDirectInput; IDirectInputDevice8* mJoyStick; DWORD coopSetting; GUID deviceGuid; //! A force feedback device Win32ForceFeedback* ff_device; //! Mapping int _AxisNumber; }; } #endif //_WIN32_JOYSTICK_H_EADER_ --- NEW FILE: Win32KeyBoard.h --- /* 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. */ #ifndef _WIN32_KEYBOARD_H_EADER_ #define _WIN32_KEYBOARD_H_EADER_ #include "OISKeyboard.h" #include "Win32/Win32Prereqs.h" namespace OIS { class Win32Keyboard : public Keyboard { public: /** @remarks Constructor @param pDI Valid DirectInput8 Interface @param buffered True for buffered input mode @param coopSettings A combination of DI Flags (see DX Help for info on input device settings) */ Win32Keyboard( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings ); virtual ~Win32Keyboard(); /** @copydoc Keyboard::isKeyDown */ virtual bool isKeyDown( KeyCode key ); /** @copydoc Keyboard::getAsString */ virtual const std::string& getAsString( KeyCode kc ); /** @copydoc Keyboard::copyKeyStates */ virtual void copyKeyStates( char keys[256] ); /** @copydoc Object::setBuffered */ virtual void setBuffered(bool buffered); /** @copydoc Object::capture */ virtual void capture(); /** @copydoc Object::queryInterface */ virtual Interface* queryInterface(Interface::IType type) {return 0;} /** @copydoc Object::_initialize */ virtual void _initialize(); protected: Win32Keyboard() {} void _readBuffered(); void _read(); IDirectInput8* mDirectInput; IDirectInputDevice8* mKeyboard; DWORD coopSetting; unsigned char KeyBuffer[256]; //! Internal method for translating KeyCodes to Text int _translateText( KeyCode kc ); //! Stored dead key from last translation WCHAR deadKey; //! used for getAsString std::string mGetString; }; } #endif //_WIN32_KEYBOARD_H_EADER_ --- NEW FILE: Win32Mouse.h --- /* 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. */ #ifndef _WIN32_MOUSE_H_EADER_ #define _WIN32_MOUSE_H_EADER_ #include "OISMouse.h" #include "Win32/Win32Prereqs.h" namespace OIS { class Win32Mouse : public Mouse { public: Win32Mouse( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings ); virtual ~Win32Mouse(); /** @copydoc Object::setBuffered */ virtual void setBuffered(bool buffered); /** @copydoc Object::capture */ virtual void capture(); /** @copydoc Object::queryInterface */ virtual Interface* queryInterface(Interface::IType type) {return 0;} /** @copydoc Object::_initialize */ virtual void _initialize(); protected: Win32Mouse() {} bool _doMouseClick( int mouseButton, DIDEVICEOBJECTDATA& di ); IDirectInput8* mDirectInput; IDirectInputDevice8* mMouse; DWORD coopSetting; HWND mHwnd; }; } #endif //_WIN32_MOUSE_H_EADER_ --- NEW FILE: Win32Mouse.cpp --- /* 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/Win32Mouse.h" #include "Win32/Win32InputManager.h" #include "OISException.h" #include "OISEvents.h" using namespace OIS; //--------------------------------------------------------------------------------------------------// Win32Mouse::Win32Mouse( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings ) { mCreator = creator; mBuffered = buffered; mMouse = 0; mDirectInput = pDI; coopSetting = coopSettings; mType = OISMouse; listener = 0; mHwnd = 0; } //--------------------------------------------------------------------------------------------------// void Win32Mouse::_initialize() { DIPROPDWORD dipdw; //Clear old state mState.clear(); dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = MOUSE_DX_BUFFERSIZE; if( FAILED(mDirectInput->CreateDevice(GUID_SysMouse, &mMouse, NULL)) ) OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to create device" ); if( FAILED(mMouse->SetDataFormat(&c_dfDIMouse2)) ) OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set format" ); mHwnd = ((Win32InputManager*)mCreator)->getWindowHandle(); if( FAILED(mMouse->SetCooperativeLevel(mHwnd, coopSetting)) ) OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set coop level" ); if( FAILED(mMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph )) ) OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set property" ); HRESULT hr = mMouse->Acquire(); if (FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO) OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to aquire mouse!" ); } //--------------------------------------------------------------------------------------------------// Win32Mouse::~Win32Mouse() { if (mMouse) { mMouse->Unacquire(); mMouse->Release(); mMouse = 0; } } //--------------------------------------------------------------------------------------------------// void Win32Mouse::capture() { //Clear old relative values mState.X.rel = mState.Y.rel = mState.Z.rel = 0; DIDEVICEOBJECTDATA diBuff[MOUSE_DX_BUFFERSIZE]; DWORD entries = MOUSE_DX_BUFFERSIZE; HRESULT hr = mMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); if( hr != DI_OK ) { hr = mMouse->Acquire(); while( hr == DIERR_INPUTLOST ) hr = mMouse->Acquire(); hr = mMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); //Perhaps the user just tabbed away, and coop settings //are nonexclusive..so just ignore if( FAILED(hr) ) return; } bool axesMoved = false; //Accumulate all axis movements for one axesMove message.. //Buttons are fired off as they are found for(unsigned int i = 0; i < entries; ++i ) { switch( diBuff[i].dwOfs ) { case DIMOFS_BUTTON0: if(!_doMouseClick(0, diBuff[i])) return; break; case DIMOFS_BUTTON1: if(!_doMouseClick(1, diBuff[i])) return; break; case DIMOFS_BUTTON2: if(!_doMouseClick(2, diBuff[i])) return; break; case DIMOFS_BUTTON3: if(!_doMouseClick(3, diBuff[i])) return; break; case DIMOFS_BUTTON4: if(!_doMouseClick(4, diBuff[i])) return; break; case DIMOFS_BUTTON5: if(!_doMouseClick(5, diBuff[i])) return; break; case DIMOFS_BUTTON6: if(!_doMouseClick(6, diBuff[i])) return; break; case DIMOFS_BUTTON7: if(!_doMouseClick(7, diBuff[i])) return; break; case DIMOFS_X: mState.X.rel += diBuff[i].dwData; axesMoved = true; break; case DIMOFS_Y: mState.Y.rel += diBuff[i].dwData; axesMoved = true; break; case DIMOFS_Z: mState.Z.rel += diBuff[i].dwData; axesMoved = true; break; default: break; } //end switch }//end for if( axesMoved ) { if( coopSetting & DISCL_NONEXCLUSIVE ) { //DirectInput provides us with meaningless values, so correct that POINT point; GetCursorPos(&point); ScreenToClient(mHwnd, &point); mState.X.abs = point.x; mState.Y.abs = point.y; } else { mState.X.abs += mState.X.rel; mState.Y.abs += mState.Y.rel; } mState.Z.abs += mState.Z.rel; //Clip values to window if( mState.X.abs < 0 ) mState.X.abs = 0; else if( mState.X.abs > mState.width ) mState.X.abs = mState.width; if( mState.Y.abs < 0 ) mState.Y.abs = 0; else if( mState.Y.abs > mState.height ) mState.Y.abs = mState.height; //Do the move if( listener && mBuffered ) listener->mouseMoved( MouseEvent( this, mState ) ); } } //--------------------------------------------------------------------------------------------------// bool Win32Mouse::_doMouseClick( int mouseButton, DIDEVICEOBJECTDATA& di ) { if( di.dwData & 0x80 ) { mState.buttons |= 1 << mouseButton; //turn the bit flag on if( listener && mBuffered ) return listener->mousePressed( MouseEvent( this, mState ), (MouseButtonID)mouseButton ); } else { mState.buttons &= ~(1 << mouseButton); //turn the bit flag off if( listener && mBuffered ) return listener->mouseReleased( MouseEvent( this, mState ), (MouseButtonID)mouseButton ); } return true; } //--------------------------------------------------------------------------------------------------// void Win32Mouse::setBuffered(bool buffered) { mBuffered = buffered; } --- NEW FILE: Win32KeyBoard.cpp --- /* 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; hr = mKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); if( hr != DI_OK ) { hr = mKeyboard->Acquire(); while( hr == DIERR_INPUTLOST ) hr = mKeyboard->Acquire(); return; } if( FAILED(hr) ) OIS_EXCEPT( E_General, "Win32Keyboard::_readBuffered() >> Problem with Device!" ); //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; //Fire off event if( listener ) ret = listener->keyReleased( KeyEvent( this, kc, 0 ) ); } if(ret == false) break; } } //--------------------------------------------------------------------------------------------------// 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: â deadKey = 0x302; break; case 0x60: // Grave accent: à deadKey = 0x300; break; case 0xA8: // Diaeresis: ü deadKey = 0x308; break; case 0xB4: // Acute accent: é deadKey = 0x301; break; case 0xB8: // Cedilla: ç 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(DIPROP... [truncated message content] |