00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "GASProtoMapper.h"
00014 #include "CATDirectInput.h"
00015 #include "CATDIJoystick.h"
00016
00017 GASProtoMapper::GASProtoMapper()
00018 {
00019 fDirectInput = 0;
00020 fController = 0;
00021 fMap = 0;
00022 fPollFreq = 50;
00023 fValidAxis = 0;
00024 fFilterXLow = 0;
00025 fFilterXHigh = 0;
00026 fFilterZLow = 0;
00027 fFilterZHigh = 0;
00028 fFilterXRotLow = 0;
00029 fFilterXRotHigh = 0;
00030 fFilterYRotLow = 0;
00031 fFilterYRotHigh = 0;
00032 fCToggle = false;
00033 fLSToggle = false;
00034 fLCToggle = false;
00035 fWPovKeyDown = false;
00036 fSPovKeyDown = false;
00037 fWKeyDown = false;
00038 fSKeyDown = false;
00039 fAKeyDown = false;
00040 fDKeyDown = false;
00041 fSpeedToggle = false;
00042 fInitialized = false;
00043 }
00044
00045 GASProtoMapper::~GASProtoMapper()
00046 {
00047 if (fInitialized)
00048 (void)Uninitialize();
00049 }
00050
00051 CATResult GASProtoMapper::Initialize()
00052 {
00053 if (fInitialized)
00054 return CAT_SUCCESS;
00055
00056 CATResult result;
00057
00058 fDirectInput = new CATDirectInput();
00059 result = fDirectInput->Init();
00060 if (CATFAILED(result))
00061 Uninitialize();
00062 else
00063 fInitialized = true;
00064
00065 return result;
00066 }
00067
00068 CATResult GASProtoMapper::Uninitialize()
00069 {
00070 StopMapping();
00071
00072 if (fDirectInput)
00073 {
00074 delete fDirectInput;
00075 fDirectInput = 0;
00076 }
00077 if (fFilterXLow)
00078 {
00079 delete fFilterXLow;
00080 fFilterXLow = 0;
00081 }
00082 if (fFilterXHigh)
00083 {
00084 delete fFilterXHigh;
00085 fFilterXHigh = 0;
00086 }
00087 if (fFilterZLow)
00088 {
00089 delete fFilterZLow;
00090 fFilterZLow = 0;
00091 }
00092 if (fFilterZHigh)
00093 {
00094 delete fFilterZHigh;
00095 fFilterZHigh = 0;
00096 }
00097 if (fFilterXRotLow)
00098 {
00099 delete fFilterXRotLow;
00100 fFilterXRotLow = 0;
00101 }
00102 if (fFilterXRotHigh)
00103 {
00104 delete fFilterXRotHigh;
00105 fFilterXRotHigh = 0;
00106 }
00107 if (fFilterYRotLow)
00108 {
00109 delete fFilterYRotLow;
00110 fFilterYRotLow = 0;
00111 }
00112 if (fFilterYRotHigh)
00113 {
00114 delete fFilterYRotHigh;
00115 fFilterYRotHigh = 0;
00116 }
00117
00118 fInitialized = false;
00119 return CAT_SUCCESS;
00120 }
00121
00122
00123 void JoystickListCB(const CATWChar* name, void* userParam)
00124 {
00125 std::vector<CATString>* joystickList = (std::vector<CATString>*)userParam;
00126 joystickList->push_back(name);
00127 }
00128
00129
00130 CATResult GASProtoMapper::GetControllerList( std::vector<CATString>& controllerList )
00131 {
00132 if (!fInitialized)
00133 return CATRESULT(CAT_ERR_NOT_INITIALIZED);
00134
00135 fDirectInput->EnumJoysticks(JoystickListCB,&controllerList);
00136
00137 return CAT_SUCCESS;
00138 }
00139
00140 CATResult GASProtoMapper::GetMappingList( const CATString& controllerName,
00141 std::vector<CATString>& mappingList)
00142 {
00143 return CAT_SUCCESS;
00144 }
00145
00146 CATResult GASProtoMapper::StartMapping( const CATString& controllerName,
00147 const CATString& mappingName)
00148 {
00149 fController = fDirectInput->CreateJoystick(controllerName);
00150
00151 if (!fController)
00152 return CAT_ERROR;
00153
00154 fValidAxis = fController->GetValidAxis();
00155
00156 fController->GetStatus(fLastStatus);
00157 fMap = new CATControlMap();
00158
00159 if (fFilterXLow)
00160 fFilterXLow->Reset();
00161 else
00162 fFilterXLow = new CATFilterAttackDecay(0.99f,0.1f);
00163
00164 if (fFilterXHigh)
00165 fFilterXHigh->Reset();
00166 else
00167 fFilterXHigh = new CATFilterAttackDecay(0.99f,0.1f);
00168
00169 if (fFilterZLow)
00170 fFilterZLow->Reset();
00171 else
00172 fFilterZLow = new CATFilterAttackDecay(0.99f,0.01f);
00173
00174 if (fFilterZHigh)
00175 fFilterZHigh->Reset();
00176 else
00177 fFilterZHigh = new CATFilterAttackDecay(0.99f,0.01f);
00178
00179 if (fFilterXRotLow)
00180 fFilterXRotLow->Reset();
00181 else
00182 fFilterXRotLow = new CATFilterAttackDecay(0.99f,0.01f);
00183
00184 if (fFilterXRotHigh)
00185 fFilterXRotHigh->Reset();
00186 else
00187 fFilterXRotHigh = new CATFilterAttackDecay(0.99f,0.01f);
00188
00189 if (fFilterYRotLow)
00190 fFilterYRotLow->Reset();
00191 else
00192 fFilterYRotLow = new CATFilterAttackDecay(0.99f,0.01f);
00193
00194 if (fFilterYRotHigh)
00195 fFilterYRotHigh->Reset();
00196 else
00197 fFilterYRotHigh = new CATFilterAttackDecay(0.99f,0.01f);
00198
00199 this->Start(fPollFreq);
00200
00201 return CAT_SUCCESS;
00202 }
00203
00204 CATResult GASProtoMapper::StopMapping()
00205 {
00206 this->Stop();
00207
00208 if (fController)
00209 {
00210 delete fController;
00211 fController = 0;
00212 }
00213
00214 if (fMap)
00215 {
00216 delete fMap;
00217 fMap = 0;
00218 }
00219 return CAT_SUCCESS;
00220 }
00221
00222
00223 void GASProtoMapper::OnThreadIdle()
00224 {
00225 if (fController)
00226 {
00227 CATJOYSTICKSTRUCT status;
00228
00229 if (fController->GetStatus(status))
00230 {
00231 for (CATUInt32 i = 0; i < kCATJOYSTICKBTNMAX; i++)
00232 {
00233 if ((status.buttonMap & (1 << i)) != (fLastStatus.buttonMap & (1 << i)))
00234 {
00235 OnButtonChange( 0 != (status.buttonMap & (1 << i)), i);
00236 }
00237 }
00238
00239
00240
00241 OnAxis(status.xHigh, CATJoystick::X_AXIS_HIGH);
00242 OnAxis(status.xLow, CATJoystick::X_AXIS_LOW);
00243 OnAxis(status.xRot, CATJoystick::X_ROT);
00244 OnAxis(status.xRotLow, CATJoystick::X_ROT_LOW);
00245 OnAxis(status.xRotHigh, CATJoystick::X_ROT_HIGH);
00246 OnAxis(status.yAxis, CATJoystick::Y_AXIS);
00247 OnAxis(status.yRot, CATJoystick::Y_ROT);
00248 OnAxis(status.yRotLow, CATJoystick::Y_ROT_LOW);
00249 OnAxis(status.yRotHigh, CATJoystick::Y_ROT_HIGH);
00250 OnAxis(status.zAxis, CATJoystick::Z_AXIS);
00251 OnAxis(status.zHigh, CATJoystick::Z_AXIS_HIGH);
00252 OnAxis(status.zLow, CATJoystick::Z_AXIS_LOW);
00253 OnAxis(status.zRot, CATJoystick::Z_ROT);
00254 OnAxis(status.zRotLow, CATJoystick::Z_ROT_LOW);
00255 OnAxis(status.zRotHigh, CATJoystick::Z_ROT_HIGH);
00256 OnAxis(status.xPov, CATJoystick::X_POV);
00257 OnAxis(status.yPov, CATJoystick::Y_POV);
00258
00259 fLastStatus = status;
00260
00261
00262
00263
00264
00265
00266
00267
00268 }
00269
00270 }
00271 }
00272
00273 CATUInt32 GASProtoMapper::OnThreadMessage(CATUInt32 msg, CATUInt32 wParam, CATUInt32 lParam)
00274 {
00275 return 0;
00276 }
00277
00278 void GASProtoMapper::OnAxis(CATInt32 val, CATJoystick::AXIS_TYPE axisType)
00279 {
00280
00281 CATInt32 xChange, yChange, wChange;
00282 xChange = yChange = wChange = 0;
00283
00284 CATFloat32 sensitivity = 1.0f;
00285 CATInt32 xThresh = 14;
00286 CATInt32 yThresh = 14;
00287
00288 switch (axisType)
00289 {
00290 case CATJoystick::X_AXIS_LOW:
00291 {
00292 if (abs(val) < xThresh)
00293 val = 0;
00294
00295 xChange = -fFilterXLow->Filter(val)* sensitivity;
00296 mouse_event(MOUSEEVENTF_MOVE, xChange, 0, 0, 0);
00297 }
00298 break;
00299 case CATJoystick::X_AXIS_HIGH:
00300 {
00301 if (abs(val) < xThresh)
00302 val = 0;
00303
00304 xChange = fFilterXHigh->Filter(val)* sensitivity;
00305 mouse_event(MOUSEEVENTF_MOVE, xChange, 0, 0, 0);
00306 }
00307 break;
00308
00309 case CATJoystick::Y_POV:
00310 {
00311 if (val > 50+yThresh)
00312 {
00313 if (!fSPovKeyDown)
00314 {
00315 fSPovKeyDown = true;
00316 PushChar(DIKEYBOARD_S,true);
00317 }
00318
00319 if (fWPovKeyDown)
00320 {
00321 fWPovKeyDown = false;
00322 PushChar(DIKEYBOARD_W,false);
00323
00324 }
00325 }
00326 else if (val < 50-yThresh)
00327 {
00328 if (!fWPovKeyDown)
00329 {
00330 fWPovKeyDown = true;
00331 PushChar(DIKEYBOARD_W,true);
00332 }
00333
00334 if (fSPovKeyDown)
00335 {
00336 fSPovKeyDown = false;
00337 PushChar(DIKEYBOARD_S,false);
00338
00339 }
00340 }
00341 else
00342 {
00343 if (fSPovKeyDown)
00344 {
00345 fSPovKeyDown = false;
00346 PushChar(DIKEYBOARD_S,false);
00347
00348 }
00349 if (fWPovKeyDown)
00350 {
00351 fWPovKeyDown = false;
00352 PushChar(DIKEYBOARD_W,false);
00353
00354 }
00355 }
00356 }
00357 break;
00358
00359 case CATJoystick::Y_AXIS:
00360 {
00361 if (val > 50+yThresh)
00362 {
00363 if (!fSKeyDown)
00364 {
00365 fSKeyDown = true;
00366 PushChar(DIKEYBOARD_S,true);
00367 }
00368
00369 if (fWKeyDown)
00370 {
00371 fWKeyDown = false;
00372 PushChar(DIKEYBOARD_W,false);
00373
00374 }
00375 }
00376 else if (val < 50-yThresh)
00377 {
00378 if (!fWKeyDown)
00379 {
00380 fWKeyDown = true;
00381 PushChar(DIKEYBOARD_W,true);
00382 }
00383
00384 if (fSKeyDown)
00385 {
00386 fSKeyDown = false;
00387 PushChar(DIKEYBOARD_S,false);
00388
00389 }
00390 }
00391 else
00392 {
00393 if (fSKeyDown)
00394 {
00395 fSKeyDown = false;
00396 PushChar(DIKEYBOARD_S,false);
00397
00398 }
00399 if (fWKeyDown)
00400 {
00401 fWKeyDown = false;
00402 PushChar(DIKEYBOARD_W,false);
00403
00404 }
00405 }
00406 }
00407 break;
00408 case CATJoystick::X_POV:
00409 {
00410 if (val > 50+xThresh)
00411 {
00412 if (!fAKeyDown)
00413 {
00414 fAKeyDown = true;
00415 PushChar(DIKEYBOARD_A,true);
00416 }
00417
00418 if (fDKeyDown)
00419 {
00420 fDKeyDown = false;
00421 PushChar(DIKEYBOARD_D,false);
00422 }
00423 }
00424 else if (val < 50-xThresh)
00425 {
00426 if (!fDKeyDown)
00427 {
00428 fDKeyDown = true;
00429 PushChar(DIKEYBOARD_D,true);
00430 }
00431
00432 if (fAKeyDown)
00433 {
00434 fAKeyDown = false;
00435 PushChar(DIKEYBOARD_A,false);
00436 }
00437 }
00438 else
00439 {
00440 if (fAKeyDown)
00441 {
00442 fAKeyDown = false;
00443 PushChar(DIKEYBOARD_A,false);
00444 }
00445 if (fDKeyDown)
00446 {
00447 fDKeyDown = false;
00448 PushChar(DIKEYBOARD_D,false);
00449 }
00450 }
00451 }
00452 break;
00453
00454
00455 case CATJoystick::Z_AXIS_LOW:
00456 {
00457 if (abs(val) < yThresh)
00458 val = 0;
00459
00460 yChange = -fFilterZLow->Filter(val)* sensitivity;
00461 mouse_event(MOUSEEVENTF_MOVE, 0, yChange, 0, 0);
00462 }
00463 break;
00464 case CATJoystick::Z_AXIS_HIGH:
00465 {
00466 if (abs(val) < yThresh)
00467 val = 0;
00468 yChange = fFilterZHigh->Filter(val)* sensitivity;
00469 mouse_event(MOUSEEVENTF_MOVE, 0, yChange, 0, 0);
00470 }
00471 break;
00472
00473
00474 case CATJoystick::X_ROT_LOW:
00475 {
00476 if (abs(val) < xThresh)
00477 val = 0;
00478
00479 xChange = -fFilterXRotLow->Filter(val)* sensitivity;
00480 mouse_event(MOUSEEVENTF_MOVE, xChange, 0, 0, 0);
00481 }
00482 break;
00483 case CATJoystick::X_ROT_HIGH:
00484 {
00485 if (abs(val) < xThresh)
00486 val = 0;
00487
00488 xChange = fFilterXRotHigh->Filter(val)* sensitivity;
00489 mouse_event(MOUSEEVENTF_MOVE, xChange, 0, 0, 0);
00490 }
00491 break;
00492 case CATJoystick::Y_ROT_LOW:
00493 {
00494 if (abs(val) < yThresh)
00495 val = 0;
00496
00497 yChange = -fFilterYRotLow->Filter(val)* sensitivity;
00498 mouse_event(MOUSEEVENTF_MOVE, 0, yChange, 0, 0);
00499 }
00500 break;
00501 case CATJoystick::Y_ROT_HIGH:
00502 {
00503 if (abs(val) < yThresh)
00504 val = 0;
00505 yChange = fFilterYRotHigh->Filter(val)* sensitivity;
00506 mouse_event(MOUSEEVENTF_MOVE, 0, yChange, 0, 0);
00507 }
00508 break;
00509 }
00510
00511 }
00512
00513
00514 void GASProtoMapper::OnButtonChange(bool state, CATUInt32 button)
00515 {
00516 enum QUADCONTROL_BUTTONS
00517 {
00518 QC_LOWERLEFT = 0,
00519 QC_CENTERSIP = 1,
00520 QC_CENTERPUFF = 2,
00521 QC_UPPERLEFT = 3,
00522 QC_LEFTPUFF = 4,
00523 QC_RIGHTPUFF = 5,
00524 QC_STARTSIP = 6,
00525 QC_STARTPUFF = 7,
00526 QC_LEFTSIP = 8,
00527 QC_RIGHTSIP = 9,
00528 QC_UPPERRIGHT = 10,
00529
00530
00531 QC_X = 0x7fffffff
00532 };
00533
00534 CATString dbg;
00535 dbg.Format(L"Button: %d state: %d\n",button,state?1:0);
00536 ::OutputDebugString(dbg);
00537 switch (button)
00538 {
00539 case QC_LOWERLEFT:
00540 if (state)
00541 {
00542 if (fSpeedToggle)
00543 PushChar(DIKEYBOARD_F13,true);
00544 else
00545 PushChar(DIKEYBOARD_F14,true);
00546 }
00547 else
00548 {
00549 if (fSpeedToggle)
00550 PushChar(DIKEYBOARD_F13,false);
00551 else
00552 PushChar(DIKEYBOARD_F14,false);
00553
00554 fSpeedToggle ^= 1;
00555 }
00556 break;
00557 case QC_CENTERSIP:
00558 if (state)
00559 {
00560 mouse_event( MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
00561 }
00562 else
00563 {
00564 mouse_event( MOUSEEVENTF_RIGHTUP,0,0,0,0);
00565 }
00566 break;
00567 case QC_CENTERPUFF:
00568 if (state)
00569 {
00570 mouse_event( MOUSEEVENTF_LEFTDOWN,0,0,0,0);
00571 }
00572 else
00573 {
00574 mouse_event( MOUSEEVENTF_LEFTUP,0,0,0,0);
00575 }
00576
00577 break;
00578 case QC_UPPERLEFT:
00579 PushChar(DIKEYBOARD_F,state);
00580 break;
00581 case QC_LEFTPUFF:
00582 if (state)
00583 {
00584 if (fCToggle)
00585 {
00586 PushChar(DIKEYBOARD_C,true);
00587 }
00588 else
00589 {
00590 PushChar(DIKEYBOARD_C,false);
00591 }
00592 fCToggle ^= 1;
00593 }
00594 PushChar(DIKEYBOARD_R,state);
00595 break;
00596 case QC_RIGHTPUFF:
00597 if (state)
00598 {
00599 if (fLSToggle)
00600 {
00601 PushChar(DIKEYBOARD_LSHIFT,true);
00602 }
00603 else
00604 {
00605 PushChar(DIKEYBOARD_LSHIFT,false);
00606 }
00607 fLSToggle ^= 1;
00608 }
00609 break;
00610 case QC_STARTSIP:
00611
00612 PushChar(DIKEYBOARD_ESCAPE,state);
00613 {
00614 if (fWKeyDown || fWPovKeyDown)
00615 {
00616 PushChar(DIKEYBOARD_W,false);
00617 fWKeyDown = false;
00618 fWPovKeyDown = false;
00619 }
00620 if (fSKeyDown || fSKeyDown)
00621 {
00622 PushChar(DIKEYBOARD_S,false);
00623 fSKeyDown = false;
00624 fSPovKeyDown = false;
00625 }
00626 if (fAKeyDown)
00627 {
00628 PushChar(DIKEYBOARD_A,false);
00629 fAKeyDown = false;
00630 }
00631 if (fDKeyDown)
00632 {
00633 PushChar(DIKEYBOARD_D,false);
00634 fDKeyDown = false;
00635 }
00636 if (fSpeedToggle)
00637 {
00638 PushChar(DIKEYBOARD_F14,true);
00639 PushChar(DIKEYBOARD_F14,false);
00640 fSpeedToggle = false;
00641 }
00642 if (fCToggle)
00643 {
00644 PushChar(DIKEYBOARD_C,false);
00645 fCToggle = false;
00646 }
00647 if (fLSToggle)
00648 {
00649 PushChar(DIKEYBOARD_LSHIFT,false);
00650 fLSToggle = false;
00651 }
00652 if (fLCToggle)
00653 {
00654 PushChar(DIKEYBOARD_LCONTROL,false);
00655 fLCToggle = false;
00656 }
00657 }
00658
00659 break;
00660 case QC_STARTPUFF:
00661 PushChar(DIKEYBOARD_TAB,state);
00662 Sleep(100);
00663 PushChar(DIKEYBOARD_E,state);
00664 break;
00665 case QC_LEFTSIP:
00666 if (state)
00667 {
00668 mouse_event(MOUSEEVENTF_WHEEL | MOUSEEVENTF_ABSOLUTE, 0,0, WHEEL_DELTA, 0);
00669 }
00670 break;
00671 case QC_RIGHTSIP:
00672 if (state)
00673 {
00674 if (fLCToggle)
00675 {
00676 PushChar(DIKEYBOARD_LCONTROL,true);
00677 }
00678 else
00679 {
00680 PushChar(DIKEYBOARD_LCONTROL,false);
00681 }
00682 fLCToggle ^= 1;
00683 }
00684 break;
00685 }
00686 }
00687
00688 void GASProtoMapper::PushChar(CATUInt32 scanCode, bool keydown)
00689 {
00690 INPUT input;
00691 input.type = INPUT_KEYBOARD;
00692 input.ki.dwExtraInfo = 0;
00693 input.ki.dwFlags = KEYEVENTF_SCANCODE | (keydown ? 0 : KEYEVENTF_KEYUP);
00694 input.ki.wScan = scanCode;
00695 input.ki.wVk = 0;
00696 input.ki.time = 0;
00697 SendInput(1,&input,sizeof(INPUT));
00698 }