Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2236 lines
71 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Xbox controller implementation for inputsystem.dll
  4. //
  5. //===========================================================================//
  6. #include "inputsystem.h"
  7. #ifdef _PS3
  8. #include <sysutil/sysutil_common.h>
  9. #include <sysutil/sysutil_sysparam.h>
  10. #include <cell/mouse.h>
  11. #include <cell/keyboard.h>
  12. #include "movecontroller_ps3.h"
  13. #include "key_translation.h"
  14. #include <cell/gcm.h>
  15. #endif
  16. #include "vstdlib/IKeyValuesSystem.h"
  17. #include "materialsystem/imaterialsystem.h"
  18. #include "vgui/isurface.h"
  19. #include "vgui_controls/controls.h"
  20. // NOTE: This has to be the last file included!
  21. #include "tier0/memdbgon.h"
  22. #include "input_device.h"
  23. //-----------------------------------------------------------------------------
  24. // Xbox helpers
  25. //-----------------------------------------------------------------------------
  26. #ifdef PLATFORM_PS3
  27. #define XBX_MAX_MOTOR_SPEED 255
  28. #define PS3_MAX_MOUSE 2 //Max PS3 mouse connections
  29. #define PS3_MAX_KEYBOARD 2 //Max PS3 keyboard connections
  30. #define PS3_MOUSE_LEFT ( 1<<0 )
  31. #define PS3_MOUSE_RIGHT ( 1<<1 )
  32. #define PS3_MOUSE_WHEEL ( 1<<2 )
  33. #define GetTickCount Plat_MSTime
  34. ConVar ps3_joy_ss( "ps3_joy_ss", "0", FCVAR_DEVELOPMENTONLY, "" );
  35. extern ConVar ps3_move_enabled;
  36. extern ConVar ps3_move_roll_trigger;
  37. #else
  38. #define XBX_MAX_MOTOR_SPEED 65535
  39. #endif
  40. #define XBX_MAX_BUTTONSAMPLE 32768
  41. #define XBX_MAX_ANALOGSAMPLE 255
  42. #define XBX_MAX_STICKSAMPLE_LEFT 32768
  43. #define XBX_MAX_STICKSAMPLE_RIGHT 32767
  44. #define XBX_MAX_STICKSAMPLE_DOWN 32768
  45. #define XBX_MAX_STICKSAMPLE_UP 32767
  46. #define XBX_STICK_SCALE_LEFT(x) ( ( float )XBX_MAX_STICKSAMPLE_LEFT/( float )( XBX_MAX_STICKSAMPLE_LEFT-(x) ) )
  47. #define XBX_STICK_SCALE_RIGHT(x) ( ( float )XBX_MAX_STICKSAMPLE_RIGHT/( float )( XBX_MAX_STICKSAMPLE_RIGHT-(x) ) )
  48. #define XBX_STICK_SCALE_DOWN(x) ( ( float )XBX_MAX_STICKSAMPLE_DOWN/( float )( XBX_MAX_STICKSAMPLE_DOWN-(x) ) )
  49. #define XBX_STICK_SCALE_UP(x) ( ( float )XBX_MAX_STICKSAMPLE_UP/( float )( XBX_MAX_STICKSAMPLE_UP-(x) ) )
  50. #define XBX_STICK_SMALL_THRESHOLD ((int)( 0.20f * XBX_MAX_STICKSAMPLE_LEFT ))
  51. // Threshold for counting analog movement as a button press
  52. #define JOYSTICK_ANALOG_BUTTON_THRESHOLD XBX_MAX_STICKSAMPLE_LEFT * 0.4f
  53. // Xbox key translation
  54. typedef struct
  55. {
  56. int xinput;
  57. int xkey;
  58. } xInputToXKey_t;
  59. xInputToXKey_t g_digitalXKeyTable[] =
  60. {
  61. {XINPUT_GAMEPAD_DPAD_UP, XK_BUTTON_UP},
  62. {XINPUT_GAMEPAD_DPAD_DOWN, XK_BUTTON_DOWN},
  63. {XINPUT_GAMEPAD_DPAD_LEFT, XK_BUTTON_LEFT},
  64. {XINPUT_GAMEPAD_DPAD_RIGHT, XK_BUTTON_RIGHT},
  65. {XINPUT_GAMEPAD_START, XK_BUTTON_START},
  66. {XINPUT_GAMEPAD_BACK, XK_BUTTON_BACK},
  67. {XINPUT_GAMEPAD_LEFT_THUMB, XK_BUTTON_STICK1},
  68. {XINPUT_GAMEPAD_RIGHT_THUMB, XK_BUTTON_STICK2},
  69. {XINPUT_GAMEPAD_LEFT_SHOULDER, XK_BUTTON_LEFT_SHOULDER},
  70. {XINPUT_GAMEPAD_RIGHT_SHOULDER, XK_BUTTON_RIGHT_SHOULDER},
  71. {XINPUT_GAMEPAD_A, XK_BUTTON_A},
  72. {XINPUT_GAMEPAD_B, XK_BUTTON_B},
  73. {XINPUT_GAMEPAD_X, XK_BUTTON_X},
  74. {XINPUT_GAMEPAD_Y, XK_BUTTON_Y},
  75. };
  76. #if !defined( _GAMECONSOLE )
  77. typedef DWORD (WINAPI *XInputGetState_t)
  78. (
  79. DWORD dwUserIndex, // [in] Index of the gamer associated with the device
  80. XINPUT_STATE* pState // [out] Receives the current state
  81. );
  82. typedef DWORD (WINAPI *XInputSetState_t)
  83. (
  84. DWORD dwUserIndex, // [in] Index of the gamer associated with the device
  85. XINPUT_VIBRATION* pVibration // [in, out] The vibration information to send to the controller
  86. );
  87. typedef DWORD (WINAPI *XInputGetCapabilities_t)
  88. (
  89. DWORD dwUserIndex, // [in] Index of the gamer associated with the device
  90. DWORD dwFlags, // [in] Input flags that identify the device type
  91. XINPUT_CAPABILITIES* pCapabilities // [out] Receives the capabilities
  92. );
  93. XInputGetState_t PC_XInputGetState;
  94. XInputSetState_t PC_XInputSetState;
  95. XInputGetCapabilities_t PC_XInputGetCapabilities;
  96. #define XINPUTGETSTATE PC_XInputGetState
  97. #define XINPUTSETSTATE PC_XInputSetState
  98. #define XINPUTGETCAPABILITIES PC_XInputGetCapabilities
  99. #elif defined( PLATFORM_PS3 )
  100. #define XINPUTGETSTATE PS3_XInputGetState
  101. #define XINPUTSETSTATE PS3_XInputSetState
  102. #define XINPUTGETCAPABILITIES PS3_XInputGetCapabilities
  103. #else
  104. #define XINPUTGETSTATE XInputGetState
  105. #define XINPUTSETSTATE XInputSetState
  106. #define XINPUTGETCAPABILITIES XInputGetCapabilities
  107. #endif
  108. #if defined( PLATFORM_PS3 )
  109. // PS3 key modifier translation
  110. // CTRL/SHIFT/ALT provided as modifiers instead of keycodes, so need a separate table
  111. typedef struct
  112. {
  113. int modifier;
  114. ButtonCode_t buttonCode;
  115. } ps3ModifierToButtonCode_t;
  116. static ps3ModifierToButtonCode_t s_ps3ModifierTable[] =
  117. {
  118. {CELL_KB_MKEY_L_SHIFT, KEY_LSHIFT},
  119. {CELL_KB_MKEY_R_SHIFT, KEY_RSHIFT},
  120. {CELL_KB_MKEY_L_CTRL, KEY_LCONTROL},
  121. {CELL_KB_MKEY_R_CTRL, KEY_RCONTROL},
  122. {CELL_KB_MKEY_L_ALT, KEY_LALT},
  123. {CELL_KB_MKEY_R_ALT, KEY_RALT}
  124. };
  125. static int PS3_SetupKb(int i);
  126. static class PS3_XInputInfo_t
  127. {
  128. public:
  129. PS3_XInputInfo_t()
  130. {
  131. ps3_move_roll_old = 0.0f;
  132. ps3_move_rumble_value = 0;
  133. ps3_move_rumble_queued = false;
  134. }
  135. // Global information about all controllers connection and settings state
  136. CellPadInfo2 m_CellPadInfo2;
  137. float m_flLastConnectedTime[ MAX( XUSER_MAX_COUNT, CELL_PAD_MAX_PORT_NUM ) ];
  138. // Information about each controller button and stick data
  139. CellPadData m_CellPadData[ MAX( XUSER_MAX_COUNT, CELL_PAD_MAX_PORT_NUM ) ];
  140. CellPadData m_lastCellPadData[ MAX( XUSER_MAX_COUNT, CELL_PAD_MAX_PORT_NUM ) ];
  141. // Packet number is incremented every time data is successfully obtained from each controller
  142. DWORD m_dwPacketNumber[ MAX( XUSER_MAX_COUNT, CELL_PAD_MAX_PORT_NUM ) ];
  143. DWORD m_dwPadPortSettingPressOn;
  144. // Global setting whether "ACCEPT" input is CIRCLE button - at the lowest level when
  145. // CIRCLE is pressed we return it as A button and when CROSS is pressed as B button
  146. bool m_bInputJapaneseSwapAB;
  147. // In single-controller mode where multiple controllers can control the game we need
  148. // to keep tracking of who is the "active" controller for vibration
  149. int m_iActiveSingleControllerIndex;
  150. float m_flLastActiveSingleControllerTime;
  151. MoveControllerState m_moveControllerState;
  152. MoveControllerState m_moveControllerStateOld;
  153. // Mouse connections
  154. CellMouseInfo m_CellMouseInfo;
  155. CellMouseInfo m_CellMouseInfoOld; // Previous mouse status
  156. CellMouseData m_CellMouseData[PS3_MAX_MOUSE];
  157. CellMouseData m_CellMouseDataOld[PS3_MAX_MOUSE];
  158. // Keyboard connections
  159. CellKbInfo m_CellKbInfo;
  160. CellKbInfo m_CellKbInfoOld; // Previous kb status
  161. CellKbData m_CellKbData[PS3_MAX_KEYBOARD];
  162. CellKbData m_CellKbDataOld[PS3_MAX_KEYBOARD];
  163. float ps3_move_roll_old;
  164. WORD ps3_move_rumble_value;
  165. bool ps3_move_rumble_queued;
  166. }
  167. g_PS3_XInputInfo;
  168. float display_aspect_ratio;
  169. // [HARDWARE CURSOR] : hardware cursor address in local memory for 64x64x4 argb cursor image (2k aligned)
  170. static uint32_t *s_cursorBufferAddress = NULL; // currently active cursor
  171. void createCursorImage_SolidColor(void *cursorImage, const uint32_t argbColor)
  172. {
  173. uint32_t *argb = (uint32_t*)cursorImage;
  174. const int w=64, h=64;
  175. for (int i=0; i<(w*h); i++)
  176. argb[i]=argbColor;
  177. }
  178. void initCursor()
  179. {
  180. // load the Prx module needed for cellVideoOutConvertCursorColor
  181. int ret = cellSysmoduleLoadModule(CELL_SYSMODULE_AVCONF_EXT);
  182. if( ret<0 ) { printf("cellSysmoduleLoadModule(CELL_SYSMODULE_AVCONF_EXT) failed (0x%x)\n", ret); exit(-1); }
  183. if ( cellGcmInitCursor() != CELL_OK )
  184. {
  185. Msg("Error initializing hardware cursor\n");
  186. }
  187. }
  188. void CInputSystem::DisableHardwareCursor()
  189. {
  190. cellGcmSetCursorDisable();
  191. cellGcmUpdateCursor();
  192. }
  193. void CInputSystem::ExitHardwareCursor()
  194. {
  195. DisableHardwareCursor();
  196. cellSysmoduleUnloadModule(CELL_SYSMODULE_AVCONF_EXT);
  197. }
  198. void loadCursorImage(const void *cursorImage, uint32_t *cursorBufferAddress)
  199. {
  200. assert(( (intptr_t) cursorBufferAddress % (2*1024) )==0); // must be 2k aligned
  201. cellVideoOutConvertCursorColor(CELL_VIDEO_OUT_PRIMARY, CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8, 1.0f, CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8, (void*)cursorImage, cursorBufferAddress, 64*64);
  202. }
  203. // set the active hardware cursor address (can only set active on a loaded cursor image)
  204. void setActiveCursor( uint32_t *cursorBufferAddress)
  205. {
  206. assert(( (intptr_t) cursorBufferAddress % (2*1024))==0); // must be 2k aligned
  207. uint32_t cursorOffset;
  208. cellGcmAddressToOffset( cursorBufferAddress, &cursorOffset );
  209. if( cellGcmSetCursorImageOffset(cursorOffset) != CELL_OK )
  210. {
  211. Msg( "Hardware Cursor Error: setting up hardware cursor offset\n" );
  212. }
  213. }
  214. #if defined( _PS3 )
  215. void CInputSystem::EnableHardwareCursor()
  216. {
  217. if (cellGcmSetCursorEnable() != CELL_OK )
  218. {
  219. Msg( "Hardware Cursor Error: trouble with enable\n" );
  220. }
  221. if ( cellGcmUpdateCursor() != CELL_OK )
  222. {
  223. Msg( "Hardware Cursor Error: trouble with update\n" );
  224. }
  225. }
  226. #endif
  227. #define CELL_PAD_DEADZONE_PROPORTION 0.2
  228. #define CELL_PAD_ACTIVE_CONTROL_TIME 0.2
  229. void PS3_XInputActiveSingleControllerSet( int iActiveSingleControllerIndex )
  230. {
  231. if ( iActiveSingleControllerIndex == g_PS3_XInputInfo.m_iActiveSingleControllerIndex )
  232. {
  233. g_PS3_XInputInfo.m_flLastActiveSingleControllerTime = Plat_FloatTime();
  234. return; // remember when was last time of activity on the original controller
  235. }
  236. // Request is coming in to activate a different controller
  237. if ( ( iActiveSingleControllerIndex > 0 ) &&
  238. ( Plat_FloatTime() - g_PS3_XInputInfo.m_flLastActiveSingleControllerTime < CELL_PAD_ACTIVE_CONTROL_TIME ) )
  239. {
  240. return; // let the original controller remain in control
  241. }
  242. // Deactivate vibration on the previously active controller
  243. if ( g_PS3_XInputInfo.m_iActiveSingleControllerIndex > 0 )
  244. {
  245. CellPadActParam param;
  246. memset( &param, 0, sizeof( param ) );
  247. cellPadSetActDirect( g_PS3_XInputInfo.m_iActiveSingleControllerIndex - 1, &param );
  248. }
  249. g_PS3_XInputInfo.m_iActiveSingleControllerIndex = iActiveSingleControllerIndex;
  250. }
  251. // [HARDWARE CURSOR] allocate cursor buffer in local memory (multiple of 2k pages, aligned on 2k boundaries)
  252. static uint32_t *allocateCursorBuffer()
  253. {
  254. CellGcmConfig config;
  255. cellGcmGetConfiguration(&config);
  256. return (uint32_t*)config.localAddress;
  257. }
  258. void UpdatePS3Mouse( int i )
  259. {
  260. int res;
  261. CellMouseData msData;
  262. res = cellMouseGetData(i, &msData);
  263. if (res == CELL_MOUSE_OK)
  264. {
  265. if(g_PS3_XInputInfo.m_CellMouseData[i].update == CELL_MOUSE_DATA_UPDATE)
  266. {
  267. // Keep copy of last valid mouse data
  268. g_PS3_XInputInfo.m_CellMouseDataOld[i] = g_PS3_XInputInfo.m_CellMouseData[i];
  269. }
  270. g_PS3_XInputInfo.m_CellMouseData[i] = msData;
  271. }
  272. }
  273. // sets x and y screen coordinates for mouse and PS move input devices
  274. bool CInputSystem::GetPS3CursorPos( int &x, int &y )
  275. {
  276. bool result = false;
  277. #ifndef _PS3
  278. // only defined under PS3
  279. Assert(0);
  280. #endif
  281. InputDevice_t currentDevice = GetCurrentInputDevice();
  282. if ( ( IsInputDeviceConnected( INPUT_DEVICE_KEYBOARD_MOUSE ) ) &&
  283. ( currentDevice == INPUT_DEVICE_KEYBOARD_MOUSE || currentDevice == INPUT_DEVICE_NONE) )
  284. {
  285. for(int i=0;i<PS3_MAX_MOUSE;i++)
  286. {
  287. UpdatePS3Mouse( i );
  288. }
  289. PollXMouse( );
  290. if((!(g_PS3_XInputInfo.m_CellMouseInfo.info & CELL_MOUSE_INFO_INTERCEPTED)) &&
  291. (g_PS3_XInputInfo.m_CellMouseInfo.status[0] == CELL_MOUSE_STATUS_CONNECTED) &&
  292. (g_PS3_XInputInfo.m_CellMouseData[0].update == CELL_MOUSE_DATA_UPDATE))
  293. {
  294. x = g_PS3_XInputInfo.m_CellMouseData[0].x_axis;
  295. y = g_PS3_XInputInfo.m_CellMouseData[0].y_axis;
  296. }
  297. else
  298. {
  299. x = g_PS3_XInputInfo.m_CellMouseDataOld[0].x_axis;
  300. y = g_PS3_XInputInfo.m_CellMouseDataOld[0].y_axis;
  301. }
  302. x = m_mouseRawAccumX;
  303. y = m_mouseRawAccumY;
  304. result = true;
  305. }
  306. else if ( ( IsInputDeviceConnected( INPUT_DEVICE_PLAYSTATION_MOVE ) &&
  307. ( currentDevice == INPUT_DEVICE_PLAYSTATION_MOVE || currentDevice == INPUT_DEVICE_NONE ) )
  308. ||
  309. ( IsInputDeviceConnected( INPUT_DEVICE_SHARPSHOOTER ) &&
  310. ( currentDevice == INPUT_DEVICE_SHARPSHOOTER || currentDevice == INPUT_DEVICE_NONE ) ) )
  311. {
  312. int nScreenWidth, nScreenHeight;
  313. materials->GetBackBufferDimensions( nScreenWidth, nScreenHeight );
  314. x = nScreenWidth * ( ( GetMotionControllerPosX() + 1.0f ) * 0.5f );
  315. y = nScreenHeight * ( 1.0 - ( ( GetMotionControllerPosY() + 1.0f ) * 0.5f ) );
  316. if ( vgui::surface()->IsCursorVisible() )
  317. {
  318. PostEvent( IE_AnalogValueChanged, m_nLastSampleTick, MOUSE_XY, x, y );
  319. }
  320. result = true;
  321. }
  322. return result;
  323. }
  324. void CInputSystem::PS3SetupHardwareCursor( void* image )
  325. {
  326. if( image == NULL )
  327. {
  328. // [dkorus] using our old default block cursor for testing!
  329. uint32_t solidCursorImage[64*64]; // original cursor images:
  330. image = solidCursorImage;
  331. createCursorImage_SolidColor( image, 0xa0ffffff );
  332. }
  333. s_cursorBufferAddress = allocateCursorBuffer();
  334. initCursor();
  335. loadCursorImage( image, s_cursorBufferAddress );
  336. setActiveCursor( s_cursorBufferAddress );
  337. }
  338. void CInputSystem::PS3_PollMouse()
  339. {
  340. int res;
  341. CellMouseData msData;
  342. CellMouseInfo* pMsInfo = &g_PS3_XInputInfo.m_CellMouseInfo;
  343. CellMouseInfo* pMsInfoOld = &g_PS3_XInputInfo.m_CellMouseInfoOld;
  344. *pMsInfoOld = *pMsInfo;
  345. if (CELL_OK != (res = cellMouseGetInfo(pMsInfo))) {
  346. Msg("Error%08X : cellMouseGetInfo\n", res);
  347. }
  348. else
  349. {
  350. // Check info field for monitoring the INTERCEPTED state (when system grabs ownership of the mouse data).
  351. bool bIntercepted = pMsInfo->info & CELL_MOUSE_INFO_INTERCEPTED;
  352. if( bIntercepted && (!(pMsInfoOld->info & CELL_MOUSE_INFO_INTERCEPTED)))
  353. {
  354. Msg("Lost the ownership of the mouse data\n");
  355. }
  356. else if(!bIntercepted && (pMsInfoOld->info & CELL_MOUSE_INFO_INTERCEPTED))
  357. {
  358. Msg("Regained ownership of the mouse data\n");
  359. for(int i=0;i<PS3_MAX_MOUSE;i++)
  360. {
  361. cellMouseClearBuf(i);
  362. }
  363. }
  364. if(!bIntercepted)
  365. {
  366. for(int i=0;i<PS3_MAX_MOUSE;i++)
  367. {
  368. // Check for mouse device insertion and removal */
  369. if (pMsInfo->status[i] == CELL_MOUSE_STATUS_CONNECTED)
  370. {
  371. if (pMsInfoOld->status[i] == CELL_MOUSE_STATUS_DISCONNECTED)
  372. {
  373. Msg("Mouse[%d] connected.\n", i);
  374. cellMouseClearBuf(i);
  375. // testing the hardware cursor
  376. m_PS3MouseConnected = true;
  377. EnableHardwareCursor();
  378. }
  379. UpdatePS3Mouse( i );
  380. }
  381. else if(pMsInfo->status[i] == CELL_MOUSE_STATUS_DISCONNECTED)
  382. {
  383. if(pMsInfoOld->status[i] == CELL_MOUSE_STATUS_CONNECTED)
  384. {
  385. // call these when we're done:
  386. // disableCursor();
  387. // exitCursor();
  388. Msg("Mouse[%d] disconnected.\n", i);
  389. m_PS3MouseConnected = false; // ?
  390. }
  391. }
  392. SetInputDeviceConnected( INPUT_DEVICE_KEYBOARD_MOUSE, ( m_PS3KeyboardConnected && m_PS3MouseConnected ) );
  393. }
  394. }
  395. }
  396. }
  397. void CInputSystem::PS3_PollKeyboard()
  398. {
  399. int res;
  400. CellKbData kbData;
  401. CellKbInfo* pKbInfo = &g_PS3_XInputInfo.m_CellKbInfo;
  402. CellKbInfo* pKbInfoOld = &g_PS3_XInputInfo.m_CellKbInfoOld;
  403. *pKbInfoOld = *pKbInfo;
  404. if (CELL_OK != (res = cellKbGetInfo(pKbInfo))) {
  405. Msg("Error%08X : cellKbGetInfo\n", res);
  406. }
  407. else
  408. {
  409. // Check info field for monitoring the INTERCEPTED state (when system grabs ownership of the keyboard data).
  410. bool bIntercepted = pKbInfo->info & CELL_KB_INFO_INTERCEPTED;
  411. if( bIntercepted && (!(pKbInfoOld->info & CELL_KB_INFO_INTERCEPTED)))
  412. {
  413. Msg("Lost the ownership of the keyboard data\n");
  414. }
  415. else if(!bIntercepted && (pKbInfoOld->info & CELL_KB_INFO_INTERCEPTED))
  416. {
  417. Msg("Regained ownership of the keyboard data\n");
  418. for(int i=0;i<PS3_MAX_KEYBOARD;i++)
  419. {
  420. cellKbClearBuf(i);
  421. }
  422. }
  423. if(!bIntercepted)
  424. {
  425. for(int i=0;i<PS3_MAX_KEYBOARD;i++)
  426. {
  427. // Check for keyboard insertion and removal */
  428. if (pKbInfo->status[i] == CELL_KB_STATUS_CONNECTED)
  429. {
  430. if (pKbInfoOld->status[i] == CELL_KB_STATUS_DISCONNECTED)
  431. {
  432. Msg("Keyboard[%d] connected.\n", i);
  433. m_PS3KeyboardConnected = true;
  434. PS3_SetupKb(i);
  435. }
  436. res = cellKbRead(i, &kbData);
  437. if (res == CELL_KB_OK)
  438. {
  439. // Keep copy of last valid keyboard data
  440. if(g_PS3_XInputInfo.m_CellKbData[i].len > 0)
  441. {
  442. g_PS3_XInputInfo.m_CellKbDataOld[i] = g_PS3_XInputInfo.m_CellKbData[i];
  443. }
  444. g_PS3_XInputInfo.m_CellKbData[i] = kbData;
  445. }
  446. }
  447. else if(pKbInfo->status[i] == CELL_KB_STATUS_DISCONNECTED)
  448. {
  449. if(pKbInfoOld->status[i] == CELL_KB_STATUS_CONNECTED)
  450. {
  451. Msg("Keyboard[%d] disconnected.\n", i);
  452. m_PS3KeyboardConnected = false; // ?
  453. }
  454. }
  455. SetInputDeviceConnected( INPUT_DEVICE_KEYBOARD_MOUSE, ( m_PS3KeyboardConnected && m_PS3MouseConnected ) );
  456. }
  457. }
  458. }
  459. }
  460. bool HandleMoveControllerSelectButtonHack( CellPadData &data, int controllerIndex )
  461. {
  462. // [dkorus] hacky solution to let steam overlay open with SELECT button from the last frame's input
  463. bool usingMoveControllerSelectBtn = (g_PS3_XInputInfo.m_moveControllerStateOld.m_aCellGemState[0].pad.digitalbuttons & CELL_GEM_CTRL_SELECT);
  464. // need to track whether we were using the move controller select button last time we ran this code
  465. static bool wasUsingMoveControllerSelectBtn = false;
  466. if ( usingMoveControllerSelectBtn || wasUsingMoveControllerSelectBtn )
  467. {
  468. if ( data.len <= 0 )
  469. {
  470. // fill in valid data from our last successful pad sample
  471. data = g_PS3_XInputInfo.m_lastCellPadData[ controllerIndex ];
  472. }
  473. }
  474. if ( usingMoveControllerSelectBtn )
  475. {
  476. // force in a button value for select
  477. data.button[ CELL_PAD_BTN_OFFSET_DIGITAL1 ] |= CELL_PAD_CTRL_SELECT;
  478. // give a valid length (this is just the value in the data structure when SELECT is normally pressed)
  479. data.len = MAX(20, data.len);
  480. }
  481. else if ( wasUsingMoveControllerSelectBtn )
  482. {
  483. // force in a button value for select
  484. data.button[ CELL_PAD_BTN_OFFSET_DIGITAL1 ] &= ~(CELL_PAD_CTRL_SELECT);
  485. // give a valid length (this is just the value in the data structure when SELECT is normally pressed)
  486. data.len = MAX(20,data.len);
  487. }
  488. wasUsingMoveControllerSelectBtn = usingMoveControllerSelectBtn;
  489. return usingMoveControllerSelectBtn;
  490. }
  491. void CInputSystem::PS3_XInputPollEverything( BCellPadDataHook_t hookFunc, BCellPadNoDataHook_t hookNoDataFunc )
  492. {
  493. memset( &g_PS3_XInputInfo.m_CellPadInfo2, 0, sizeof( g_PS3_XInputInfo.m_CellPadInfo2 ) );
  494. int res = cellPadGetInfo2( &g_PS3_XInputInfo.m_CellPadInfo2 );
  495. if ( res < CELL_OK )
  496. {
  497. if ( hookNoDataFunc )
  498. hookNoDataFunc();
  499. PS3_XInputActiveSingleControllerSet( 0 );
  500. return;
  501. }
  502. if ( g_PS3_XInputInfo.m_CellPadInfo2.system_info & CELL_PAD_INFO_INTERCEPTED )
  503. {
  504. // OS is intercepting all controller input
  505. if ( hookNoDataFunc )
  506. hookNoDataFunc();
  507. PS3_XInputActiveSingleControllerSet( 0 );
  508. return;
  509. }
  510. int iActiveControllerDetected = ( XBX_GetNumGameUsers() == 1 ) ? 0 : -1;
  511. float flCurrentTime = Plat_FloatTime();
  512. for ( int k = 0; k < ARRAYSIZE( g_PS3_XInputInfo.m_CellPadInfo2.port_status ); ++ k )
  513. {
  514. if ( g_PS3_XInputInfo.m_CellPadInfo2.port_status[k] & CELL_PAD_STATUS_CONNECTED )
  515. {
  516. if ( 0 == ( g_PS3_XInputInfo.m_dwPadPortSettingPressOn & ( 1 << k ) ) )
  517. {
  518. res = cellPadSetPortSetting( k, CELL_PAD_SETTING_PRESS_ON ); // Set pad to all-analog mode
  519. if ( res == CELL_PAD_OK )
  520. {
  521. g_PS3_XInputInfo.m_CellPadInfo2.port_setting[k] |= CELL_PAD_SETTING_PRESS_ON;
  522. g_PS3_XInputInfo.m_dwPadPortSettingPressOn |= ( 1 << k );
  523. }
  524. }
  525. CellPadData data;
  526. res = cellPadGetData( k, &data );
  527. // [dkorus] this func checks/adds select button data from the move controller to the CellPadData we're passing through. Used for the steam overlay on PS3
  528. // please remove when steam overlay is reworked to correctly sample move controller data!
  529. HandleMoveControllerSelectButtonHack( data, k );
  530. if ( res < CELL_OK )
  531. {
  532. // Failed to obtain data - mark ctrlr as disconnected!
  533. g_PS3_XInputInfo.m_CellPadInfo2.port_status[k] &=~ CELL_PAD_STATUS_CONNECTED;
  534. }
  535. else if ( data.len > 0 )
  536. {
  537. // New data obtained!
  538. bool bDiscard = false;
  539. if ( hookFunc )
  540. {
  541. bDiscard = hookFunc( data );
  542. }
  543. if ( !bDiscard )
  544. {
  545. Q_memcpy( &g_PS3_XInputInfo.m_CellPadData[k], &data, sizeof( CellPadData ) );
  546. ++ g_PS3_XInputInfo.m_dwPacketNumber[k];
  547. if ( ( g_PS3_XInputInfo.m_iActiveSingleControllerIndex - 1 == k ) ||
  548. !iActiveControllerDetected )
  549. iActiveControllerDetected = k + 1;
  550. }
  551. g_PS3_XInputInfo.m_lastCellPadData[k] = data;
  552. }
  553. }
  554. if ( ( g_PS3_XInputInfo.m_CellPadInfo2.port_status[k] & CELL_PAD_STATUS_CONNECTED ) != CELL_PAD_STATUS_CONNECTED )
  555. {
  556. // PS3 controllers can get disconnected for brief periods of time
  557. // when they transition between charging and wireless modes :(
  558. if ( flCurrentTime - g_PS3_XInputInfo.m_flLastConnectedTime[k] > CELL_PAD_ACTIVE_CONTROL_TIME )
  559. {
  560. // Controller is treated as disconnected, reset data state
  561. memset( &g_PS3_XInputInfo.m_CellPadData[k], 0, sizeof( CellPadData ) );
  562. }
  563. else
  564. {
  565. // Pretend like it's still connected, just no state changes
  566. g_PS3_XInputInfo.m_CellPadInfo2.port_status[k] |= CELL_PAD_STATUS_CONNECTED;
  567. }
  568. }
  569. else
  570. {
  571. // Remember when this controller was last connected
  572. g_PS3_XInputInfo.m_flLastConnectedTime[k] = flCurrentTime;
  573. }
  574. }
  575. if(g_pMoveController->m_bEnabled)
  576. {
  577. g_PS3_XInputInfo.m_moveControllerStateOld = g_PS3_XInputInfo.m_moveControllerState;
  578. g_pMoveController->ReadState(&g_PS3_XInputInfo.m_moveControllerState);
  579. }
  580. PS3_PollMouse();
  581. PS3_PollKeyboard();
  582. if ( iActiveControllerDetected )
  583. {
  584. PS3_XInputActiveSingleControllerSet( iActiveControllerDetected );
  585. }
  586. }
  587. // [dkorus] mode masks and button masks for sharpshooter straight from sharpshooter sdk demo
  588. #define CUSTOM0_MODE_1 (1 << 0)
  589. #define CUSTOM0_MODE_2 (1 << 1)
  590. #define CUSTOM0_MODE_3 (1 << 2)
  591. #define CUSTOM0_MODE_MASK (CUSTOM0_MODE_1 | CUSTOM0_MODE_2 | CUSTOM0_MODE_3)
  592. #define CUSTOM0_T_BUTTON_TRIGGER (1 << 6)
  593. #define CUSTOM0_RL_RELOAD_BUTTON (1 << 7)
  594. class CSharpshooterButtonData
  595. {
  596. public:
  597. CSharpshooterButtonData()
  598. {
  599. prev_mode = 0;
  600. m_reloadPressedLastFrame = false;
  601. m_triggerPressedLastFrame = false;
  602. m_pumpActionPressedLastFrame = false;
  603. }
  604. unsigned char prev_mode;
  605. bool m_reloadPressedLastFrame;
  606. bool m_triggerPressedLastFrame;
  607. bool m_pumpActionPressedLastFrame;
  608. };
  609. CSharpshooterButtonData g_sharpshooterData;
  610. void CInputSystem::HandlePS3SharpshooterButtons( void )
  611. {
  612. // we have a sharpshooter, read in the special buttons
  613. static const unsigned char num_dots_lookup[8] = {0, 1, 2, 0, 3, 0, 0, 0};
  614. unsigned char mode = num_dots_lookup[g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].ext.custom[0] & CUSTOM0_MODE_MASK];
  615. if ( mode != g_sharpshooterData.prev_mode )
  616. {
  617. // fire mode selector changed
  618. ButtonCode_t prev_mode_button = KEY_XBUTTON_FIREMODE_SELECTOR_1;
  619. switch ( g_sharpshooterData.prev_mode )
  620. {
  621. case 1:
  622. prev_mode_button = KEY_XBUTTON_FIREMODE_SELECTOR_1;
  623. break;
  624. case 2:
  625. prev_mode_button = KEY_XBUTTON_FIREMODE_SELECTOR_2;
  626. break;
  627. case 3:
  628. prev_mode_button = KEY_XBUTTON_FIREMODE_SELECTOR_3;
  629. break;
  630. default: Msg( "Button prev_mode %d unhandled\n",g_sharpshooterData.prev_mode );
  631. };
  632. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, prev_mode_button, prev_mode_button );
  633. ButtonCode_t new_mode_button = KEY_XBUTTON_FIREMODE_SELECTOR_1;
  634. switch ( mode )
  635. {
  636. case 1:
  637. new_mode_button = KEY_XBUTTON_FIREMODE_SELECTOR_1;
  638. break;
  639. case 2:
  640. new_mode_button = KEY_XBUTTON_FIREMODE_SELECTOR_2;
  641. break;
  642. case 3:
  643. new_mode_button = KEY_XBUTTON_FIREMODE_SELECTOR_3;
  644. break;
  645. default: Msg( "Button mode %d unhandled\n",mode );
  646. };
  647. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, new_mode_button, new_mode_button );
  648. g_sharpshooterData.prev_mode = mode;
  649. }
  650. if ( g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].ext.custom[0] & CUSTOM0_RL_RELOAD_BUTTON )
  651. {
  652. // reload button pressed
  653. if ( !g_sharpshooterData.m_reloadPressedLastFrame )
  654. {
  655. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, KEY_XBUTTON_RELOAD, KEY_XBUTTON_RELOAD );
  656. }
  657. g_sharpshooterData.m_reloadPressedLastFrame = true;
  658. }
  659. else
  660. {
  661. if ( g_sharpshooterData.m_reloadPressedLastFrame )
  662. {
  663. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, KEY_XBUTTON_RELOAD, KEY_XBUTTON_RELOAD );
  664. }
  665. g_sharpshooterData.m_reloadPressedLastFrame = false;
  666. }
  667. if ( g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].ext.custom[0] & CUSTOM0_T_BUTTON_TRIGGER ) // custom T button trigger takes priority over actual Move T button
  668. {
  669. // trigger pressed
  670. if ( !g_sharpshooterData.m_triggerPressedLastFrame )
  671. {
  672. if( m_setCurrentInputDeviceOnNextButtonPress )
  673. {
  674. // [dkorus] since this is a move specific button, it's either triggered by the move or the sharpshooter
  675. if ( IsInputDeviceConnected( INPUT_DEVICE_SHARPSHOOTER ) )
  676. SetCurrentInputDevice( INPUT_DEVICE_SHARPSHOOTER );
  677. else
  678. SetCurrentInputDevice( INPUT_DEVICE_PLAYSTATION_MOVE );
  679. m_setCurrentInputDeviceOnNextButtonPress = false;
  680. }
  681. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, KEY_XBUTTON_TRIGGER, KEY_XBUTTON_TRIGGER );
  682. }
  683. g_sharpshooterData.m_triggerPressedLastFrame = true;
  684. }
  685. else
  686. {
  687. if ( g_sharpshooterData.m_triggerPressedLastFrame )
  688. {
  689. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, KEY_XBUTTON_TRIGGER, KEY_XBUTTON_TRIGGER );
  690. }
  691. g_sharpshooterData.m_triggerPressedLastFrame = false;
  692. if ( g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].pad.digitalbuttons & CELL_GEM_CTRL_T )
  693. {
  694. if ( !g_sharpshooterData.m_pumpActionPressedLastFrame )
  695. {
  696. // pump action grip pulled
  697. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, KEY_XBUTTON_PUMP_ACTION, KEY_XBUTTON_PUMP_ACTION );
  698. }
  699. g_sharpshooterData.m_pumpActionPressedLastFrame = true;
  700. }
  701. else
  702. {
  703. if ( g_sharpshooterData.m_pumpActionPressedLastFrame )
  704. {
  705. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, KEY_XBUTTON_PUMP_ACTION, KEY_XBUTTON_PUMP_ACTION );
  706. }
  707. g_sharpshooterData.m_pumpActionPressedLastFrame = false;
  708. }
  709. }
  710. }
  711. void CInputSystem::HandlePS3Move( PXINPUT_STATE& pState )
  712. {
  713. // handling controller buttons
  714. CellGemPadData gemPadDataOld = g_PS3_XInputInfo.m_moveControllerStateOld.m_aCellGemState[0].pad;
  715. CellGemPadData gemPadData = g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].pad;
  716. if ( IsDeviceReadingInput( INPUT_DEVICE_SHARPSHOOTER ) && IsInputDeviceConnected( INPUT_DEVICE_SHARPSHOOTER ) )
  717. {
  718. HandlePS3SharpshooterButtons( );
  719. }
  720. // check for queued rumble
  721. if ( g_PS3_XInputInfo.ps3_move_rumble_queued )
  722. {
  723. g_pMoveController->Rumble( g_PS3_XInputInfo.ps3_move_rumble_value );
  724. g_PS3_XInputInfo.ps3_move_rumble_queued = false;
  725. }
  726. if (gemPadData.digitalbuttons & CELL_GEM_CTRL_START)
  727. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_START;
  728. if (gemPadData.digitalbuttons & CELL_GEM_CTRL_SELECT)
  729. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_BACK;
  730. if ( (gemPadData.digitalbuttons & CELL_GEM_CTRL_CROSS) ||
  731. ( gemPadData.analog_T>0 && !g_sharpshooterData.m_pumpActionPressedLastFrame ) )
  732. {
  733. if( m_setCurrentInputDeviceOnNextButtonPress )
  734. {
  735. if ( IsInputDeviceConnected( INPUT_DEVICE_SHARPSHOOTER ) )
  736. SetCurrentInputDevice( INPUT_DEVICE_SHARPSHOOTER );
  737. else
  738. SetCurrentInputDevice( INPUT_DEVICE_PLAYSTATION_MOVE );
  739. m_setCurrentInputDeviceOnNextButtonPress = false;
  740. }
  741. }
  742. if ( ( gemPadData.digitalbuttons & CELL_GEM_CTRL_CROSS ) )
  743. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_A;
  744. if (gemPadData.digitalbuttons & CELL_GEM_CTRL_CIRCLE)
  745. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_B;
  746. if (gemPadData.digitalbuttons & CELL_GEM_CTRL_TRIANGLE)
  747. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_Y;
  748. if (gemPadData.digitalbuttons & CELL_GEM_CTRL_SQUARE)
  749. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_X;
  750. if ( !IsInputDeviceConnected( INPUT_DEVICE_SHARPSHOOTER ) )
  751. {
  752. if ( gemPadData.analog_T>0 && !g_sharpshooterData.m_pumpActionPressedLastFrame )
  753. {
  754. if ( gemPadDataOld.analog_T <= 0 )
  755. {
  756. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, KEY_XBUTTON_TRIGGER, KEY_XBUTTON_TRIGGER );
  757. }
  758. }
  759. else if ( gemPadDataOld.analog_T > 0)
  760. {
  761. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, KEY_XBUTTON_TRIGGER, KEY_XBUTTON_TRIGGER );
  762. }
  763. }
  764. gemPadDataOld.analog_T = gemPadData.analog_T;
  765. // Get roll from Quaternion
  766. Quaternion qMc = Quaternion(-g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].quat[2],
  767. -g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].quat[0],
  768. g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].quat[1],
  769. g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].quat[3]);
  770. float fRoll = 0.0f;
  771. float m23 = ( 2.0f * qMc.y * qMc.z ) + ( 2.0f * qMc.w * qMc.x );
  772. float m33 = ( 2.0f * qMc.w * qMc.w ) + ( 2.0f * qMc.z * qMc.z ) - 1.0f;
  773. if(!(m23==0 && m33==0))
  774. {
  775. fRoll = RAD2DEG(atan2(m23,m33));
  776. }
  777. float fRollTrigger = ps3_move_roll_trigger.GetFloat();
  778. if ( fRoll > fRollTrigger )
  779. {
  780. if ( g_PS3_XInputInfo.ps3_move_roll_old <= fRollTrigger )
  781. {
  782. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, KEY_XBUTTON_ROLL_RIGHT, KEY_XBUTTON_ROLL_RIGHT );
  783. }
  784. }
  785. else if ( g_PS3_XInputInfo.ps3_move_roll_old > fRollTrigger )
  786. {
  787. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, KEY_XBUTTON_ROLL_RIGHT, KEY_XBUTTON_ROLL_RIGHT );
  788. }
  789. if(fRoll < (fRollTrigger*-1.0f))
  790. {
  791. if ( g_PS3_XInputInfo.ps3_move_roll_old >= ( fRollTrigger * -1.0f ) )
  792. {
  793. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, KEY_XBUTTON_ROLL_LEFT, KEY_XBUTTON_ROLL_LEFT );
  794. }
  795. }
  796. else if ( g_PS3_XInputInfo.ps3_move_roll_old < ( fRollTrigger * -1.0f ) )
  797. {
  798. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, KEY_XBUTTON_ROLL_LEFT, KEY_XBUTTON_ROLL_LEFT );
  799. }
  800. g_PS3_XInputInfo.ps3_move_roll_old = fRoll;
  801. }
  802. DWORD CInputSystem::PS3_XInputGetState(
  803. DWORD dwUserIndex,
  804. PXINPUT_STATE pState
  805. )
  806. {
  807. if ( !( g_PS3_XInputInfo.m_CellPadInfo2.port_status[dwUserIndex] & CELL_PAD_STATUS_CONNECTED ) )
  808. return ERROR_DEVICE_NOT_CONNECTED;
  809. CellPadData const padData = g_PS3_XInputInfo.m_CellPadData[ dwUserIndex ];
  810. // Convert cellPad state to Valve (x360) gamepad state
  811. memset(&pState->Gamepad.wButtons, 0, sizeof(pState->Gamepad.wButtons));
  812. if ( !IsDeviceReadingInput( INPUT_DEVICE_GAMEPAD ) &&
  813. !IsDeviceReadingInput( INPUT_DEVICE_PLAYSTATION_MOVE ) &&
  814. !IsDeviceReadingInput( INPUT_DEVICE_SHARPSHOOTER ) &&
  815. !IsDeviceReadingInput( INPUT_DEVICE_MOVE_NAV_CONTROLLER ) )
  816. {
  817. return ERROR_SUCCESS;
  818. }
  819. // Analog-only cell pad buttons
  820. // pState->Gamepad.sThumbLX = (short)( ( (unsigned int) ( ( ( short) padData.button[ CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X ] ) << 8 ) - 1 ) - 0x7fff );
  821. // pState->Gamepad.sThumbLY = (short)( ( (unsigned int) ( ( ( short) padData.button[ CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y ] ) << 8 ) - 1 ) - 0x7fff );
  822. // pState->Gamepad.sThumbRX = (short)( ( (unsigned int) ( ( ( short) padData.button[ CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X ] ) << 8 ) - 1 ) - 0x7fff );
  823. // pState->Gamepad.sThumbRY = (short)( ( (unsigned int) ( ( ( short) padData.button[ CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y ] ) << 8 ) - 1 ) - 0x7fff );
  824. int lx,ly,rx,ry;
  825. lx = padData.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] &0xff;
  826. ly = padData.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] &0xff;
  827. rx = 0;
  828. ry = 0;
  829. // don't use right stick input when using move controller.
  830. if ( IsDeviceReadingInput( INPUT_DEVICE_GAMEPAD ) || IsDeviceReadingInput( INPUT_DEVICE_MOVE_NAV_CONTROLLER ) )
  831. {
  832. rx = padData.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] &0xff;
  833. ry = padData.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] &0xff;
  834. rx = (rx * 65535) / 255;
  835. ry = (ry * 65535) / 255;
  836. rx -= 0x8000;
  837. ry = 0x7FFF - ry;
  838. }
  839. lx = (lx * 65535) / 255;
  840. ly = (ly * 65535) / 255;
  841. lx -= 0x8000;
  842. ly = 0x7FFF - ly;
  843. pState->Gamepad.sThumbLX = (signed short)lx;
  844. pState->Gamepad.sThumbLY = (signed short)ly;
  845. pState->Gamepad.sThumbRX = (signed short)rx;
  846. pState->Gamepad.sThumbRY = (signed short)ry;
  847. // Digital-only cell pad buttons
  848. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_START)
  849. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_START;
  850. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_SELECT)
  851. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_BACK;
  852. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_L3)
  853. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_LEFT_THUMB;
  854. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_R3)
  855. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_RIGHT_THUMB;
  856. // Buttons which can be either analog or digital
  857. bool bAllAnalog = !!( g_PS3_XInputInfo.m_CellPadInfo2.port_setting[ dwUserIndex ] & CELL_PAD_SETTING_PRESS_ON );
  858. if (bAllAnalog)
  859. {
  860. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] > CELL_PAD_DEADZONE_PROPORTION)
  861. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
  862. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_UP] > CELL_PAD_DEADZONE_PROPORTION)
  863. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP;
  864. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] > CELL_PAD_DEADZONE_PROPORTION)
  865. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
  866. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] > CELL_PAD_DEADZONE_PROPORTION)
  867. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
  868. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] > CELL_PAD_DEADZONE_PROPORTION)
  869. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_A;
  870. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] > CELL_PAD_DEADZONE_PROPORTION)
  871. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_B;
  872. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] > CELL_PAD_DEADZONE_PROPORTION)
  873. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_Y;
  874. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] > CELL_PAD_DEADZONE_PROPORTION)
  875. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_X;
  876. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_L1] > CELL_PAD_DEADZONE_PROPORTION)
  877. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_LEFT_SHOULDER;
  878. if (padData.button[CELL_PAD_BTN_OFFSET_PRESS_R1] > CELL_PAD_DEADZONE_PROPORTION)
  879. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_RIGHT_SHOULDER;
  880. pState->Gamepad.bLeftTrigger = padData.button[CELL_PAD_BTN_OFFSET_PRESS_L2];
  881. pState->Gamepad.bRightTrigger = padData.button[CELL_PAD_BTN_OFFSET_PRESS_R2];
  882. }
  883. else
  884. {
  885. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_LEFT)
  886. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
  887. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_UP)
  888. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP;
  889. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_DOWN)
  890. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
  891. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_RIGHT)
  892. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
  893. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_CROSS)
  894. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_A;
  895. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_CIRCLE)
  896. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_B;
  897. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_TRIANGLE)
  898. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_Y;
  899. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_SQUARE)
  900. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_X;
  901. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_L1)
  902. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_LEFT_SHOULDER;
  903. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_R1)
  904. pState->Gamepad.wButtons |= XINPUT_GAMEPAD_RIGHT_SHOULDER;
  905. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_L2)
  906. pState->Gamepad.bLeftTrigger = 0xFF;
  907. else
  908. pState->Gamepad.bLeftTrigger = 0x00;
  909. if (padData.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_R2)
  910. {
  911. pState->Gamepad.bRightTrigger = 0xFF;
  912. }
  913. else
  914. {
  915. pState->Gamepad.bRightTrigger = 0x00;
  916. }
  917. }
  918. if ( g_PS3_XInputInfo.m_bInputJapaneseSwapAB )
  919. {
  920. pState->Gamepad.wButtons
  921. =
  922. ( pState->Gamepad.wButtons & ~( XINPUT_GAMEPAD_A | XINPUT_GAMEPAD_B ) )
  923. |
  924. ( ( pState->Gamepad.wButtons & XINPUT_GAMEPAD_A ) ? XINPUT_GAMEPAD_B : 0 )
  925. |
  926. ( ( pState->Gamepad.wButtons & XINPUT_GAMEPAD_B ) ? XINPUT_GAMEPAD_A : 0 );
  927. }
  928. pState->dwPacketNumber = g_PS3_XInputInfo.m_dwPacketNumber[dwUserIndex];
  929. // Add motion controller button states (overwrite gamepad data)
  930. // If motion controller connected and calibrated...
  931. if( g_pMoveController->m_bEnabled &&
  932. (g_PS3_XInputInfo.m_moveControllerState.m_CellGemInfo.status[0]==CELL_GEM_STATUS_READY) &&
  933. (g_PS3_XInputInfo.m_moveControllerState.m_aStatus[0] == CELL_OK) &&
  934. ( IsDeviceReadingInput( INPUT_DEVICE_PLAYSTATION_MOVE ) || IsDeviceReadingInput( INPUT_DEVICE_SHARPSHOOTER ) ) )
  935. {
  936. // [dkorus] pState passed by reference for ease of use, it may change inside of this func
  937. HandlePS3Move( pState );
  938. }
  939. return ERROR_SUCCESS;
  940. }
  941. DWORD PS3_XInputSetState(
  942. DWORD dwUserIndex,
  943. PXINPUT_VIBRATION pVibration
  944. )
  945. {
  946. CellPadActParam param;
  947. memset( &param, 0, sizeof( param ) );
  948. if ( XBX_GetNumGameUsers() )
  949. {
  950. if ( g_PS3_XInputInfo.m_iActiveSingleControllerIndex > 0 )
  951. // single player vibration override
  952. dwUserIndex = g_PS3_XInputInfo.m_iActiveSingleControllerIndex - 1;
  953. param.motor[0] = !!pVibration->wLeftMotorSpeed;
  954. param.motor[1] = pVibration->wRightMotorSpeed;
  955. }
  956. cellPadSetActDirect( dwUserIndex, &param );
  957. return ERROR_SUCCESS;
  958. }
  959. DWORD PS3_XInputGetCapabilities( DWORD dwUserIndex, DWORD dwFlags, PXINPUT_CAPABILITIES pCapabilities )
  960. {
  961. // [dkorus] in the future it would make sense to move PS3 device information here
  962. // note, this might be complicated for some devices as some input types have their capabilitys change on the fly
  963. // for exmaple, a standard controller has rumble, but it's disabled if the move controller is set to the
  964. // current controller.
  965. pCapabilities->Type = XINPUT_DEVTYPE_GAMEPAD;
  966. pCapabilities->SubType = XINPUT_DEVSUBTYPE_GAMEPAD;
  967. pCapabilities->Flags = 0;
  968. return ( g_PS3_XInputInfo.m_CellPadInfo2.port_status[dwUserIndex] & CELL_PAD_STATUS_CONNECTED ) ? ERROR_SUCCESS : ERROR_DEVICE_NOT_CONNECTED;
  969. }
  970. void PS3_XInputShutdown()
  971. {
  972. cellPadEnd();
  973. g_pMoveController->Shutdown();
  974. cellMouseEnd();
  975. cellKbEnd();
  976. }
  977. //--------------------------------------------------------------------------------------------------
  978. // PS3_InitMouse
  979. // Init the PS3 mouse library
  980. //--------------------------------------------------------------------------------------------------
  981. static int PS3_InitMouse()
  982. {
  983. int ret = cellMouseInit(PS3_MAX_MOUSE);
  984. if (ret != CELL_MOUSE_OK)
  985. {
  986. Msg("Error(%08X) : PS3 cellMouseInit error\n", ret);
  987. return (ret);
  988. }
  989. return (CELL_OK);
  990. }
  991. //--------------------------------------------------------------------------------------------------
  992. // PS3_SetupKb
  993. // Setup initial keyboard state
  994. //--------------------------------------------------------------------------------------------------
  995. static int PS3_SetupKb(int i)
  996. {
  997. int ret = cellKbSetLEDStatus(i, CELL_KB_LED_NUM_LOCK | CELL_KB_LED_CAPS_LOCK | CELL_KB_LED_SCROLL_LOCK );
  998. if (ret != CELL_KB_OK)
  999. {
  1000. Msg("Error(%08X) : cellKbSetLEDStatus, kb no = %d\n", ret, i);
  1001. }
  1002. ret = cellKbSetReadMode(i, CELL_KB_RMODE_PACKET);
  1003. if (ret != CELL_KB_OK)
  1004. {
  1005. Msg("Error(%08X) : cellKbSetReadMode, kb no = %d\n", ret, i);
  1006. cellKbEnd();
  1007. return (ret);
  1008. }
  1009. ret = cellKbSetCodeType(i, CELL_KB_CODETYPE_RAW);
  1010. if (ret != CELL_KB_OK)
  1011. {
  1012. Msg("Error(%08X) : cellKbSetCodeType, kb no = %d\n", ret, i);
  1013. cellKbEnd();
  1014. return (ret);
  1015. }
  1016. ret = cellKbClearBuf(i);
  1017. if (ret != CELL_KB_OK)
  1018. {
  1019. Msg("Error(%08X) : cellKbClearBuf, kb no = %d\n", ret, i);
  1020. cellKbEnd();
  1021. return (ret);
  1022. }
  1023. return ret;
  1024. }
  1025. //--------------------------------------------------------------------------------------------------
  1026. // PS3_InitKb
  1027. // Init the PS3 keyboard library
  1028. //--------------------------------------------------------------------------------------------------
  1029. static int PS3_InitKb()
  1030. {
  1031. int ret = cellKbInit(PS3_MAX_KEYBOARD);
  1032. if (ret != CELL_KB_OK)
  1033. {
  1034. Msg("Error(%08X) : PS3 cellKbInit error\n", ret);
  1035. return (ret);
  1036. }
  1037. CellKbInfo kbInfo;
  1038. ret = cellKbGetInfo(&kbInfo);
  1039. if (ret != CELL_KB_OK)
  1040. {
  1041. Msg("Error%08X : cellKbGetInfo\n", ret);
  1042. return (ret);
  1043. }
  1044. if(!(kbInfo.info & CELL_KB_INFO_INTERCEPTED))
  1045. {
  1046. for (int i = 0; i < PS3_MAX_KEYBOARD; i++)
  1047. {
  1048. if(kbInfo.status[i]==CELL_KB_STATUS_CONNECTED)
  1049. {
  1050. PS3_SetupKb(i);
  1051. }
  1052. }
  1053. }
  1054. return (CELL_OK);
  1055. }
  1056. #endif
  1057. //-----------------------------------------------------------------------------
  1058. // Purpose: Initialize all Xbox controllers
  1059. //-----------------------------------------------------------------------------
  1060. void CInputSystem::InitializeXDevices( void )
  1061. {
  1062. bool bInputSwapAB = false;
  1063. #ifdef PLATFORM_PS3
  1064. memset( &g_PS3_XInputInfo, 0, sizeof( g_PS3_XInputInfo ) );
  1065. cellPadInit( XUSER_MAX_COUNT );
  1066. int bEnterAssignment = CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CROSS; // default to western standard assignment
  1067. if ( CELL_OK == cellSysutilGetSystemParamInt( CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN, &bEnterAssignment ) &&
  1068. bEnterAssignment == CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CIRCLE )
  1069. {
  1070. g_PS3_XInputInfo.m_bInputJapaneseSwapAB = true;
  1071. bInputSwapAB = true;
  1072. }
  1073. // Init Move Controller
  1074. g_pMoveController->Init();
  1075. // Init mouse lib
  1076. PS3_InitMouse();
  1077. // Init keyboard lib
  1078. PS3_InitKb();
  1079. #endif
  1080. KeyValuesSystem()->SetKeyValuesExpressionSymbol( "INPUTSWAPAB", bInputSwapAB );
  1081. int i;
  1082. xdevice_t* pXDevice;
  1083. // assume no joystick
  1084. m_nJoystickCount = 0;
  1085. #if !defined( _GAMECONSOLE )
  1086. PC_XInputGetState = (XInputGetState_t)GetProcAddress( (HMODULE)m_pXInputDLL, "XInputGetState" );
  1087. PC_XInputSetState = (XInputSetState_t)GetProcAddress( (HMODULE)m_pXInputDLL, "XInputSetState" );
  1088. PC_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress( (HMODULE)m_pXInputDLL, "XInputGetCapabilities" );
  1089. if ( !PC_XInputGetState || !PC_XInputSetState || !PC_XInputGetCapabilities )
  1090. return;
  1091. #endif
  1092. // query gamepads
  1093. pXDevice = m_XDevices;
  1094. for ( i = 0; i < XUSER_MAX_COUNT; ++i, ++pXDevice )
  1095. {
  1096. OpenXDevice( pXDevice, i );
  1097. //Msg( "UserID %d: %s\n", i+1, pXDevice->userId != INVALID_USER_ID ? "GamePad" : "???" );
  1098. }
  1099. }
  1100. bool PS3IsNavController( int userId )
  1101. {
  1102. #if defined( _PS3 )
  1103. CellPadPeriphInfo padPeriphInfo;
  1104. int ret = cellPadPeriphGetInfo( &padPeriphInfo);
  1105. if ( ret == CELL_PAD_OK && padPeriphInfo.pclass_type[ userId ] == CELL_PAD_PCLASS_TYPE_NAVIGATION )
  1106. return true;
  1107. #endif
  1108. return false;
  1109. }
  1110. //-----------------------------------------------------------------------------
  1111. // Purpose: Open an Xbox controller
  1112. //-----------------------------------------------------------------------------
  1113. void CInputSystem::OpenXDevice( xdevice_t* pXDevice, int userId )
  1114. {
  1115. XINPUT_CAPABILITIES capabilities;
  1116. // Invalidate device properties
  1117. pXDevice->userId = INVALID_USER_ID;
  1118. pXDevice->active = false;
  1119. DWORD result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
  1120. if ( result == ERROR_SUCCESS )
  1121. {
  1122. bool bIsSupported = false;
  1123. if ( IsGameConsole() )
  1124. {
  1125. // TCR says that we cannot restrict input based on subtype, so don't check it
  1126. bIsSupported = ( capabilities.Type == XINPUT_DEVTYPE_GAMEPAD );
  1127. }
  1128. else
  1129. {
  1130. // Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad.
  1131. bIsSupported = ( capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD );
  1132. }
  1133. if ( !bIsSupported )
  1134. {
  1135. // TBD: This may not be sufficient to not crash us later
  1136. Assert( 0 && "Unsupported XDevice Type" );
  1137. return;
  1138. }
  1139. #if defined ( _PS3 )
  1140. if ( PS3IsNavController( userId ) )
  1141. {
  1142. SetInputDeviceConnected( INPUT_DEVICE_MOVE_NAV_CONTROLLER );
  1143. }
  1144. else
  1145. #endif
  1146. {
  1147. SetInputDeviceConnected( INPUT_DEVICE_GAMEPAD );
  1148. }
  1149. // valid
  1150. pXDevice->type = capabilities.Type;
  1151. pXDevice->subtype = capabilities.SubType;
  1152. pXDevice->flags = capabilities.Flags;
  1153. pXDevice->userId = userId;
  1154. pXDevice->active = true;
  1155. pXDevice->quitTimeout = 0;
  1156. pXDevice->dpadLock = 0;
  1157. // left stick, default to narrow zone
  1158. pXDevice->stickThreshold[STICK1_AXIS_X] = XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
  1159. pXDevice->stickScale[STICK1_AXIS_X] = XBX_STICK_SCALE_LEFT( XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE );
  1160. pXDevice->stickThreshold[STICK1_AXIS_Y] = XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
  1161. pXDevice->stickScale[STICK1_AXIS_Y] = XBX_STICK_SCALE_DOWN( XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE );
  1162. // right stick, default to narrow zone
  1163. pXDevice->stickThreshold[STICK2_AXIS_X] = XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
  1164. pXDevice->stickScale[STICK2_AXIS_X] = XBX_STICK_SCALE_LEFT( XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE );
  1165. pXDevice->stickThreshold[STICK2_AXIS_Y] = XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
  1166. pXDevice->stickScale[STICK2_AXIS_Y] = XBX_STICK_SCALE_DOWN( XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE );
  1167. pXDevice->vibration.wLeftMotorSpeed = WORD( 0 );
  1168. pXDevice->vibration.wRightMotorSpeed = WORD( 0 );
  1169. pXDevice->pendingRumbleUpdate = false;
  1170. ++m_nJoystickCount;
  1171. }
  1172. }
  1173. //-----------------------------------------------------------------------------
  1174. // Purpose: Close an Xbox controller
  1175. //-----------------------------------------------------------------------------
  1176. void CInputSystem::CloseXDevice( xdevice_t* pXDevice )
  1177. {
  1178. pXDevice->userId = INVALID_USER_ID;
  1179. pXDevice->active = false;
  1180. --m_nJoystickCount;
  1181. }
  1182. //-----------------------------------------------------------------------------
  1183. // Purpose: Sample the console mouse (currently only implemented for PS3).
  1184. //-----------------------------------------------------------------------------
  1185. void CInputSystem::PollXMouse()
  1186. {
  1187. #ifdef _PS3
  1188. if( (!(g_PS3_XInputInfo.m_CellMouseInfo.info & CELL_MOUSE_INFO_INTERCEPTED)) &&
  1189. (g_PS3_XInputInfo.m_CellMouseInfo.status[0] == CELL_MOUSE_STATUS_CONNECTED) &&
  1190. (g_PS3_XInputInfo.m_CellMouseData[0].update == CELL_MOUSE_DATA_UPDATE) &&
  1191. IsDeviceReadingInput( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1192. {
  1193. int oldMouseX = m_mouseRawAccumX;
  1194. int oldMouseY = m_mouseRawAccumY;
  1195. m_mouseRawAccumX += g_PS3_XInputInfo.m_CellMouseData[0].x_axis;
  1196. m_mouseRawAccumY += g_PS3_XInputInfo.m_CellMouseData[0].y_axis;
  1197. // handle positional values
  1198. bool bXChanged = ( m_mouseRawAccumX != oldMouseX );
  1199. bool bYChanged = ( m_mouseRawAccumY != oldMouseY );
  1200. if ( bXChanged )
  1201. {
  1202. PostEvent( IE_AnalogValueChanged, m_nLastSampleTick, MOUSE_X, m_mouseRawAccumX, 0 );
  1203. }
  1204. if ( bYChanged )
  1205. {
  1206. PostEvent( IE_AnalogValueChanged, m_nLastSampleTick, MOUSE_Y, m_mouseRawAccumY, 0 );
  1207. }
  1208. if ( bXChanged || bYChanged )
  1209. {
  1210. PostEvent( IE_AnalogValueChanged, m_nLastSampleTick, MOUSE_XY, m_mouseRawAccumX, m_mouseRawAccumY );
  1211. }
  1212. // handle buttons
  1213. if((g_PS3_XInputInfo.m_CellMouseData[0].buttons & PS3_MOUSE_LEFT) &&
  1214. !(g_PS3_XInputInfo.m_CellMouseDataOld[0].buttons & PS3_MOUSE_LEFT))
  1215. {
  1216. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, MOUSE_LEFT, MOUSE_LEFT );
  1217. // [dkorus] check whether we're trying to set the current controller
  1218. if( m_setCurrentInputDeviceOnNextButtonPress )
  1219. {
  1220. if( IsInputDeviceConnected( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1221. {
  1222. SetCurrentInputDevice( INPUT_DEVICE_KEYBOARD_MOUSE );
  1223. m_setCurrentInputDeviceOnNextButtonPress = false;
  1224. }
  1225. }
  1226. }
  1227. if((!(g_PS3_XInputInfo.m_CellMouseData[0].buttons & PS3_MOUSE_LEFT)) &&
  1228. (g_PS3_XInputInfo.m_CellMouseDataOld[0].buttons & PS3_MOUSE_LEFT))
  1229. {
  1230. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, MOUSE_LEFT, MOUSE_LEFT );
  1231. }
  1232. if((g_PS3_XInputInfo.m_CellMouseData[0].buttons & PS3_MOUSE_RIGHT) &&
  1233. !(g_PS3_XInputInfo.m_CellMouseDataOld[0].buttons & PS3_MOUSE_RIGHT))
  1234. {
  1235. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, MOUSE_RIGHT, MOUSE_RIGHT );
  1236. }
  1237. if((!(g_PS3_XInputInfo.m_CellMouseData[0].buttons & PS3_MOUSE_RIGHT)) &&
  1238. (g_PS3_XInputInfo.m_CellMouseDataOld[0].buttons & PS3_MOUSE_RIGHT))
  1239. {
  1240. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, MOUSE_RIGHT, MOUSE_RIGHT );
  1241. }
  1242. if((g_PS3_XInputInfo.m_CellMouseData[0].buttons & PS3_MOUSE_WHEEL) &&
  1243. !(g_PS3_XInputInfo.m_CellMouseDataOld[0].buttons & PS3_MOUSE_WHEEL))
  1244. {
  1245. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, MOUSE_MIDDLE, MOUSE_MIDDLE );
  1246. }
  1247. if((!(g_PS3_XInputInfo.m_CellMouseData[0].buttons & PS3_MOUSE_WHEEL)) &&
  1248. (g_PS3_XInputInfo.m_CellMouseDataOld[0].buttons & PS3_MOUSE_WHEEL))
  1249. {
  1250. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, MOUSE_MIDDLE, MOUSE_MIDDLE );
  1251. }
  1252. if(g_PS3_XInputInfo.m_CellMouseData[0].wheel > 0)
  1253. {
  1254. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, MOUSE_WHEEL_UP, MOUSE_WHEEL_UP);
  1255. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, MOUSE_WHEEL_UP, MOUSE_WHEEL_UP);
  1256. }
  1257. else if(g_PS3_XInputInfo.m_CellMouseData[0].wheel < 0)
  1258. {
  1259. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, MOUSE_WHEEL_DOWN, MOUSE_WHEEL_DOWN);
  1260. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, MOUSE_WHEEL_DOWN, MOUSE_WHEEL_DOWN);
  1261. }
  1262. }
  1263. #endif
  1264. }
  1265. //-----------------------------------------------------------------------------
  1266. // Purpose: Sample the console keyboard (currently only implemented for PS3).
  1267. //-----------------------------------------------------------------------------
  1268. void CInputSystem::PollXKeyboard()
  1269. {
  1270. #ifdef _PS3
  1271. if( (!(g_PS3_XInputInfo.m_CellKbInfo.info & CELL_KB_INFO_INTERCEPTED)) &&
  1272. (g_PS3_XInputInfo.m_CellKbInfo.status[0] == CELL_KB_STATUS_CONNECTED) &&
  1273. (g_PS3_XInputInfo.m_CellKbData[0].len > 0) &&
  1274. IsDeviceReadingInput( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1275. {
  1276. CBitVec<256> keysPressed;
  1277. keysPressed.Init(0);
  1278. // Check for key presses
  1279. for(int i=0; i<g_PS3_XInputInfo.m_CellKbData[0].len; ++i)
  1280. {
  1281. int iKeycode = g_PS3_XInputInfo.m_CellKbData[0].keycode[i] & 0x00ff;
  1282. ButtonCode_t virtualCode = ButtonCode_VirtualKeyToButtonCode( iKeycode );
  1283. if ( iKeycode != 0 )
  1284. {
  1285. keysPressed.Set( iKeycode );
  1286. // TODO:: Get scan code (see CInputSystem::WindowProc)
  1287. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, virtualCode, virtualCode );
  1288. }
  1289. // [dkorus] check whether we're trying to set the current controller
  1290. if( ( virtualCode & KEY_SPACE || virtualCode & KEY_ENTER )
  1291. && m_setCurrentInputDeviceOnNextButtonPress )
  1292. {
  1293. if( IsInputDeviceConnected( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1294. {
  1295. SetCurrentInputDevice( INPUT_DEVICE_KEYBOARD_MOUSE );
  1296. m_setCurrentInputDeviceOnNextButtonPress = false;
  1297. }
  1298. }
  1299. // TODO:: Deal with capslock/scrolllock/numlock (see CInputSystem::WindowProc)
  1300. // TODO:: IE_KeyCodeTyped events (see CInputSystem::WindowProc)
  1301. }
  1302. // Check for key releases
  1303. for(int i=0; i<g_PS3_XInputInfo.m_CellKbDataOld[0].len; ++i)
  1304. {
  1305. int iKeycode = g_PS3_XInputInfo.m_CellKbDataOld[0].keycode[i] & 0x00ff;
  1306. if ( !keysPressed.IsBitSet(iKeycode) )
  1307. {
  1308. ButtonCode_t virtualCode = ButtonCode_VirtualKeyToButtonCode( iKeycode );
  1309. PostButtonReleasedEvent(IE_ButtonReleased, m_nLastSampleTick, virtualCode, virtualCode);
  1310. }
  1311. }
  1312. // Shift/CTRL/Alt
  1313. int iMkey = g_PS3_XInputInfo.m_CellKbData[0].mkey;
  1314. int iMkeyOld = g_PS3_XInputInfo.m_CellKbDataOld[0].mkey;
  1315. for(int i=0; i<ARRAYSIZE(s_ps3ModifierTable); ++i)
  1316. {
  1317. if(iMkey & s_ps3ModifierTable[i].modifier)
  1318. {
  1319. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, s_ps3ModifierTable[i].buttonCode, s_ps3ModifierTable[i].buttonCode );
  1320. }
  1321. else if(iMkeyOld & s_ps3ModifierTable[i].modifier)
  1322. {
  1323. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, s_ps3ModifierTable[i].buttonCode, s_ps3ModifierTable[i].buttonCode );
  1324. }
  1325. }
  1326. }
  1327. #endif
  1328. }
  1329. //-----------------------------------------------------------------------------
  1330. // Purpose: Sample the Xbox controllers.
  1331. //-----------------------------------------------------------------------------
  1332. void CInputSystem::PollXDevices( void )
  1333. {
  1334. float flCheckDelay = (m_bIsInGame && !m_bXController) ? 20 : 0.5;
  1335. if ( m_bXController )
  1336. flCheckDelay = 0;
  1337. static ConVarRef joystick_force_disabled( "joystick_force_disabled" );
  1338. if ( joystick_force_disabled.IsValid() && joystick_force_disabled.GetBool() )
  1339. {
  1340. if ( m_bXController )
  1341. {
  1342. xdevice_t* pXDevice = m_XDevices;
  1343. m_bXController = false;
  1344. for ( int userId = 0; userId < XUSER_MAX_COUNT; ++userId, ++pXDevice )
  1345. {
  1346. // Get input data in the form of Xbox controller data (for PS3, map onto Xbox struct)
  1347. DWORD result = XINPUTGETSTATE( userId, &pXDevice->states[pXDevice->newState] );
  1348. if ( result == ERROR_SUCCESS )
  1349. {
  1350. ReleaseAllButtons( JOYSTICK_BUTTON_INTERNAL( pXDevice->userId, JOYSTICK_FIRST ), JOYSTICK_BUTTON_INTERNAL( pXDevice->userId + 1, JOYSTICK_FIRST ) - 1 );
  1351. ZeroAnalogState( JOYSTICK_AXIS_INTERNAL( pXDevice->userId, JOYSTICK_FIRST_AXIS ), JOYSTICK_AXIS_INTERNAL( pXDevice->userId, JOYSTICK_FIRST_AXIS ) - 1 );
  1352. memset( &m_appXKeys[pXDevice->userId][0], 0, XK_MAX_KEYS * sizeof(appKey_t) );
  1353. }
  1354. }
  1355. }
  1356. m_flLastControllerPollTime = -1;
  1357. return;
  1358. }
  1359. else if ( m_flLastControllerPollTime != -1 && m_flLastControllerPollTime + flCheckDelay <= Plat_FloatTime() )
  1360. {
  1361. bool bAnyActive = false;
  1362. #ifdef PLATFORM_PS3
  1363. if ( g_pMoveController->m_bEnabled && !ps3_move_enabled.GetBool() )
  1364. {
  1365. g_pMoveController->Disable();
  1366. }
  1367. else if ( !g_pMoveController->m_bEnabled && ps3_move_enabled.GetBool() )
  1368. {
  1369. g_pMoveController->Enable();
  1370. }
  1371. PS3_XInputPollEverything( m_pPS3CellPadDataHook, m_pPS3CellNoPadDataHook ); // update all the joysticks
  1372. // Read move controller data
  1373. if( g_pMoveController->m_bEnabled &&
  1374. (g_PS3_XInputInfo.m_moveControllerState.m_CellGemInfo.status[0]==CELL_GEM_STATUS_READY) &&
  1375. (g_PS3_XInputInfo.m_moveControllerState.m_aStatus[0] == CELL_OK)
  1376. )
  1377. {
  1378. m_bMotionControllerActive = true;
  1379. bool bMcVisible = g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].tracking_flags & CELL_GEM_TRACKING_FLAG_VISIBLE;
  1380. if (bMcVisible)
  1381. {
  1382. m_qMotionControllerOrientation =
  1383. Quaternion( -g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].quat[2],
  1384. -g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].quat[0],
  1385. g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].quat[1],
  1386. g_PS3_XInputInfo.m_moveControllerState.m_aCellGemState[0].quat[3]);
  1387. //m_vecMotionControllerAngle = g_PS3_XInputInfo.m_moveControllerState.m_aAngle[0];
  1388. m_vecMotionControllerPos = g_PS3_XInputInfo.m_moveControllerState.m_pos[0];
  1389. m_fMotionControllerPosX = g_PS3_XInputInfo.m_moveControllerState.m_posX[0];
  1390. m_fMotionControllerPosY = g_PS3_XInputInfo.m_moveControllerState.m_posY[0];
  1391. }
  1392. else
  1393. {
  1394. // If not visible, set screen x and y position to be 0.0
  1395. m_fMotionControllerPosX = m_fMotionControllerPosX*0.85f;
  1396. m_fMotionControllerPosY = m_fMotionControllerPosY*0.85f;
  1397. }
  1398. }
  1399. else
  1400. {
  1401. m_bMotionControllerActive = false;
  1402. }
  1403. m_nMotionControllerStatusFlags = g_PS3_XInputInfo.m_moveControllerState.m_aStatusFlags[0];
  1404. #endif
  1405. PollXMouse();
  1406. PollXKeyboard();
  1407. xdevice_t* pXDevice = m_XDevices;
  1408. for ( int userId = 0; userId < XUSER_MAX_COUNT; ++userId, ++pXDevice )
  1409. {
  1410. // Get input data in the form of Xbox controller data (for PS3, map onto Xbox struct)
  1411. DWORD result = XINPUTGETSTATE( userId, &pXDevice->states[pXDevice->newState] );
  1412. switch ( result )
  1413. {
  1414. case ERROR_SUCCESS:
  1415. if ( !pXDevice->active )
  1416. {
  1417. // just inserted
  1418. OpenXDevice( pXDevice, userId );
  1419. int openedPort = userId;
  1420. #ifdef _PS3
  1421. if ( ( XBX_GetNumGameUsers() <= 1 ) && !ps3_joy_ss.GetBool() )
  1422. openedPort = 0;
  1423. #endif
  1424. PostEvent( IE_ControllerInserted, m_nLastSampleTick, openedPort );
  1425. #if defined( _PS3 )
  1426. if ( PS3IsNavController( userId ) )
  1427. {
  1428. SetInputDeviceConnected( INPUT_DEVICE_MOVE_NAV_CONTROLLER, true );
  1429. }
  1430. else
  1431. #endif
  1432. {
  1433. SetInputDeviceConnected( INPUT_DEVICE_GAMEPAD, true );
  1434. ConVarRef var( "joystick" );
  1435. if ( var.IsValid() && var.GetBool() == false )
  1436. var.SetValue( 1 );
  1437. }
  1438. }
  1439. bAnyActive = true;
  1440. // See if primary user has been set, and if so then block all other input
  1441. // if ( pXDevice->userId == m_PrimaryUserId || m_PrimaryUserId == INVALID_USER_ID )
  1442. {
  1443. ReadXDevice( pXDevice );
  1444. WriteToXDevice( pXDevice );
  1445. }
  1446. break;
  1447. case ERROR_DEVICE_NOT_CONNECTED:
  1448. if ( pXDevice->active )
  1449. {
  1450. // just removed
  1451. int closedPort = pXDevice->userId;
  1452. CloseXDevice( pXDevice );
  1453. #ifdef _X360
  1454. if ( XBX_GetSlotByUserId( closedPort ) >= 0 )
  1455. #else
  1456. if ( 1 )
  1457. #endif
  1458. {
  1459. // Controller unplugged - game needs to take action
  1460. // Release buttons of the specific joystick that was unplugged
  1461. ReleaseAllButtons( JOYSTICK_BUTTON_INTERNAL( closedPort, JOYSTICK_FIRST ), JOYSTICK_BUTTON_INTERNAL( closedPort + 1, JOYSTICK_FIRST ) - 1 );
  1462. ZeroAnalogState( JOYSTICK_AXIS_INTERNAL( closedPort, JOYSTICK_FIRST_AXIS ), JOYSTICK_AXIS_INTERNAL( closedPort, JOYSTICK_FIRST_AXIS ) - 1 );
  1463. memset( &m_appXKeys[closedPort][0], 0, XK_MAX_KEYS * sizeof(appKey_t) );
  1464. #ifdef _PS3
  1465. if ( ( XBX_GetNumGameUsers() <= 1 ) && !ps3_joy_ss.GetBool() &&
  1466. ( closedPort + 1 == g_PS3_XInputInfo.m_iActiveSingleControllerIndex ) )
  1467. {
  1468. closedPort = 0;
  1469. PostEvent( IE_ControllerUnplugged, m_nLastSampleTick, closedPort );
  1470. }
  1471. #else
  1472. PostEvent( IE_ControllerUnplugged, m_nLastSampleTick, closedPort );
  1473. #endif
  1474. #if defined( _PS3 )
  1475. if ( PS3IsNavController( userId ) )
  1476. {
  1477. SetInputDeviceConnected( INPUT_DEVICE_MOVE_NAV_CONTROLLER, false );
  1478. }
  1479. else
  1480. #endif
  1481. {
  1482. SetInputDeviceConnected( INPUT_DEVICE_GAMEPAD, false );
  1483. }
  1484. }
  1485. }
  1486. break;
  1487. }
  1488. }
  1489. // We don't need to check every frame if nothing is connected
  1490. if ( bAnyActive )
  1491. {
  1492. m_bXController = true;
  1493. ConVarRef var( "joy_xcontroller_found" );
  1494. if ( var.IsValid() && var.GetBool() == false )
  1495. var.SetValue( 1 );
  1496. }
  1497. else
  1498. {
  1499. m_bXController = false;
  1500. }
  1501. m_flLastControllerPollTime = Plat_FloatTime();
  1502. }
  1503. }
  1504. #ifdef _PS3
  1505. static float g_ps3_flTimeStartButtonIdentificationMode = 0.0f;
  1506. void CInputSystem::SetPS3StartButtonIdentificationMode()
  1507. {
  1508. g_ps3_flTimeStartButtonIdentificationMode = Plat_FloatTime();
  1509. }
  1510. #endif
  1511. //-----------------------------------------------------------------------------
  1512. // Purpose: Post Xbox events, ignoring key repeats
  1513. //-----------------------------------------------------------------------------
  1514. void CInputSystem::PostXKeyEvent( int userId, xKey_t xKey, int nSample )
  1515. {
  1516. AnalogCode_t code = ANALOG_CODE_LAST;
  1517. float value = 0.f;
  1518. // Map the physical controller slot to the split screen slot
  1519. #if defined( _GAMECONSOLE )
  1520. int nMsgSlot = XBX_GetSlotByUserId( userId );
  1521. #ifdef _PS3
  1522. if ( ( XBX_GetNumGameUsers() <= 1 ) && !ps3_joy_ss.GetBool() )
  1523. {
  1524. // In PS3 START button identification mode START key notification
  1525. // is replaced with INACTIVE_START notification that can identify
  1526. // controller that pressed the button
  1527. if ( ( xKey == XK_BUTTON_START ) && ( nMsgSlot < 0 )
  1528. && ( ( Plat_FloatTime() - g_ps3_flTimeStartButtonIdentificationMode ) < 0.5f ) )
  1529. {
  1530. xKey = XK_BUTTON_INACTIVE_START;
  1531. nMsgSlot = userId;
  1532. }
  1533. else
  1534. {
  1535. // When we don't have splitscreen then any controller can
  1536. // play and will be visible as controller #0
  1537. nMsgSlot = 0;
  1538. }
  1539. }
  1540. #endif
  1541. if ( nMsgSlot < 0 )
  1542. {
  1543. // special case, that if you press start on a controller we've marked inactive, switch it to an
  1544. // XK_BUTTON_INACTIVE_START which you can handle joins from inactive controllers
  1545. if ( xKey == XK_BUTTON_START )
  1546. {
  1547. xKey = XK_BUTTON_INACTIVE_START;
  1548. nMsgSlot = userId;
  1549. }
  1550. else
  1551. {
  1552. return; // We are not listening to this controller (not signed in and assigned)
  1553. }
  1554. }
  1555. #else //defined( _GAMECONSOLE )
  1556. int nMsgSlot = userId;
  1557. #endif //defined( _GAMECONSOLE )
  1558. int nSampleThreshold = 0;
  1559. // Look for changes on the analog axes
  1560. switch( xKey )
  1561. {
  1562. case XK_STICK1_LEFT:
  1563. case XK_STICK1_RIGHT:
  1564. {
  1565. code = (AnalogCode_t)JOYSTICK_AXIS( nMsgSlot, JOY_AXIS_X );
  1566. value = ( xKey == XK_STICK1_LEFT ) ? -nSample : nSample;
  1567. nSampleThreshold = ( int )( JOYSTICK_ANALOG_BUTTON_THRESHOLD );
  1568. }
  1569. break;
  1570. case XK_STICK1_UP:
  1571. case XK_STICK1_DOWN:
  1572. {
  1573. code = (AnalogCode_t)JOYSTICK_AXIS( nMsgSlot, JOY_AXIS_Y );
  1574. value = ( xKey == XK_STICK1_UP ) ? -nSample : nSample;
  1575. nSampleThreshold = ( int )( JOYSTICK_ANALOG_BUTTON_THRESHOLD );
  1576. }
  1577. break;
  1578. case XK_STICK2_LEFT:
  1579. case XK_STICK2_RIGHT:
  1580. {
  1581. code = (AnalogCode_t)JOYSTICK_AXIS( nMsgSlot, JOY_AXIS_U );
  1582. value = ( xKey == XK_STICK2_LEFT ) ? -nSample : nSample;
  1583. nSampleThreshold = ( int )( JOYSTICK_ANALOG_BUTTON_THRESHOLD );
  1584. }
  1585. break;
  1586. case XK_STICK2_UP:
  1587. case XK_STICK2_DOWN:
  1588. {
  1589. code = (AnalogCode_t)JOYSTICK_AXIS( nMsgSlot, JOY_AXIS_R );
  1590. value = ( xKey == XK_STICK2_UP ) ? -nSample : nSample;
  1591. nSampleThreshold = ( int )( JOYSTICK_ANALOG_BUTTON_THRESHOLD );
  1592. }
  1593. break;
  1594. }
  1595. // Store the analog event
  1596. if ( ANALOG_CODE_LAST != code )
  1597. {
  1598. InputState_t &state = m_InputState[ m_bIsPolling ];
  1599. state.m_pAnalogDelta[ code ] = ( int )( value - state.m_pAnalogValue[ code ] );
  1600. state.m_pAnalogValue[ code ] = ( int )value;
  1601. if ( state.m_pAnalogDelta[ code ] != 0 )
  1602. {
  1603. PostEvent( IE_AnalogValueChanged, m_nLastSampleTick, code, ( int )value, state.m_pAnalogDelta[ code ] );
  1604. }
  1605. }
  1606. // store the key
  1607. m_appXKeys[userId][xKey].sample = nSample;
  1608. if ( nSample > nSampleThreshold )
  1609. {
  1610. m_appXKeys[userId][xKey].repeats++;
  1611. }
  1612. else
  1613. {
  1614. m_appXKeys[userId][xKey].repeats = 0;
  1615. nSample = 0;
  1616. }
  1617. if ( m_appXKeys[userId][xKey].repeats > 1 )
  1618. {
  1619. // application cannot handle streaming keys
  1620. // first keypress is the only edge trigger
  1621. return;
  1622. }
  1623. // package the key
  1624. ButtonCode_t buttonCode = XKeyToButtonCode( nMsgSlot, xKey );
  1625. if ( nSample )
  1626. {
  1627. PostButtonPressedEvent( IE_ButtonPressed, m_nLastSampleTick, buttonCode, buttonCode );
  1628. // [dkorus] check whether we're trying to set the current controller
  1629. if( ( buttonCode == KEY_XBUTTON_A || buttonCode == XK_BUTTON_START )
  1630. && m_setCurrentInputDeviceOnNextButtonPress )
  1631. {
  1632. #if defined( _PS3 )
  1633. if ( PS3IsNavController( userId ) )
  1634. {
  1635. if ( IsInputDeviceConnected( INPUT_DEVICE_MOVE_NAV_CONTROLLER ) )
  1636. {
  1637. // [dkorus] if someone trys to lock input with the nav controller...
  1638. // select the sharpshooter if it's available
  1639. // otherwise select the MOVE if it's available
  1640. if ( IsInputDeviceConnected( INPUT_DEVICE_SHARPSHOOTER ) )
  1641. {
  1642. SetCurrentInputDevice( INPUT_DEVICE_SHARPSHOOTER );
  1643. m_setCurrentInputDeviceOnNextButtonPress = false;
  1644. }
  1645. else if ( IsInputDeviceConnected( INPUT_DEVICE_PLAYSTATION_MOVE ) )
  1646. {
  1647. SetCurrentInputDevice( INPUT_DEVICE_PLAYSTATION_MOVE );
  1648. m_setCurrentInputDeviceOnNextButtonPress = false;
  1649. }
  1650. }
  1651. }
  1652. else
  1653. #endif
  1654. {
  1655. if ( IsInputDeviceConnected( INPUT_DEVICE_GAMEPAD ) )
  1656. {
  1657. SetCurrentInputDevice( INPUT_DEVICE_GAMEPAD );
  1658. ConVarRef var( "joystick" );
  1659. if( var.IsValid( ) )
  1660. var.SetValue( 1 );
  1661. m_setCurrentInputDeviceOnNextButtonPress = false;
  1662. }
  1663. }
  1664. }
  1665. }
  1666. else
  1667. {
  1668. PostButtonReleasedEvent( IE_ButtonReleased, m_nLastSampleTick, buttonCode, buttonCode );
  1669. }
  1670. }
  1671. //-----------------------------------------------------------------------------
  1672. // Purpose: Send force feedback to an Xbox controller
  1673. //-----------------------------------------------------------------------------
  1674. void CInputSystem::WriteToXDevice( xdevice_t* pXDevice )
  1675. {
  1676. if ( pXDevice->pendingRumbleUpdate )
  1677. {
  1678. XINPUTSETSTATE( pXDevice->userId, &pXDevice->vibration );
  1679. pXDevice->pendingRumbleUpdate = false;
  1680. }
  1681. }
  1682. static int NormalizeStickValue_Cross( int nValue, int nThreshold, float flScale )
  1683. {
  1684. if ( nValue >= -nThreshold )
  1685. {
  1686. if ( nValue <= nThreshold )
  1687. {
  1688. return 0;
  1689. }
  1690. else
  1691. {
  1692. return ( int )( ( nValue - nThreshold ) * flScale );
  1693. }
  1694. }
  1695. else
  1696. {
  1697. return ( int )( ( nValue + nThreshold ) * flScale );
  1698. }
  1699. }
  1700. static void NormalizeStickValue_Square( int nX, int nY, int nThresholdX, int nThresholdY, int *pX, int *pY )
  1701. {
  1702. if ( nX >= -nThresholdX && nX <= nThresholdX && nY >= -nThresholdY && nY <= nThresholdY )
  1703. {
  1704. *pX = 0;
  1705. *pY = 0;
  1706. }
  1707. else
  1708. {
  1709. *pX = nX;
  1710. *pY = nY;
  1711. }
  1712. }
  1713. void CInputSystem::HandleXDeviceAxis( xdevice_t *pXDevice, int nAxisValue, xKey_t negativeKey, xKey_t positiveKey, int axisID )
  1714. {
  1715. xKey_t key;
  1716. // Queue stick axis push response
  1717. if ( nAxisValue < 0 )
  1718. {
  1719. PostXKeyEvent( pXDevice->userId, negativeKey, -nAxisValue );
  1720. key = negativeKey;
  1721. }
  1722. else if ( nAxisValue > 0 )
  1723. {
  1724. PostXKeyEvent( pXDevice->userId, positiveKey, nAxisValue );
  1725. key = positiveKey;
  1726. }
  1727. else
  1728. {
  1729. key = XK_NULL;
  1730. }
  1731. if ( pXDevice->lastStickKeys[axisID] && pXDevice->lastStickKeys[axisID] != key )
  1732. {
  1733. // Queue stick axis release response
  1734. PostXKeyEvent( pXDevice->userId, pXDevice->lastStickKeys[axisID], 0 );
  1735. }
  1736. pXDevice->lastStickKeys[axisID] = key;
  1737. }
  1738. //-----------------------------------------------------------------------------
  1739. // Purpose: Queue input key events for a device
  1740. //-----------------------------------------------------------------------------
  1741. void CInputSystem::ReadXDevice( xdevice_t* pXDevice )
  1742. {
  1743. XINPUT_STATE* oldStatePtr;
  1744. XINPUT_STATE* newStatePtr;
  1745. int mask;
  1746. int buttons;
  1747. int sample;
  1748. oldStatePtr = &pXDevice->states[pXDevice->newState ^ 1];
  1749. newStatePtr = &pXDevice->states[pXDevice->newState];
  1750. // forceful exit
  1751. if ( newStatePtr->Gamepad.wButtons == ( XINPUT_GAMEPAD_START|XINPUT_GAMEPAD_BACK ) )
  1752. {
  1753. if ( !pXDevice->quitTimeout )
  1754. {
  1755. pXDevice->quitTimeout = GetTickCount();
  1756. }
  1757. else if ( GetTickCount() - pXDevice->quitTimeout > 2*1000 )
  1758. {
  1759. // mandatory 2sec hold
  1760. pXDevice->quitTimeout = 0;
  1761. ProcessEvent( WM_XREMOTECOMMAND, 0, (LPARAM)"quit_gameconsole" );
  1762. }
  1763. }
  1764. else
  1765. {
  1766. // reset
  1767. pXDevice->quitTimeout = 0;
  1768. }
  1769. // No changes if packet numbers match
  1770. if (( oldStatePtr->dwPacketNumber == newStatePtr->dwPacketNumber ) && !m_bMotionControllerActive)
  1771. return;
  1772. // PS3 builds allow gamepad input even if we're using another device
  1773. // move and other controllers use the same gamepad button presses
  1774. #if !defined ( _PS3 )
  1775. if ( !IsDeviceReadingInput( INPUT_DEVICE_GAMEPAD ) )
  1776. return;
  1777. #endif
  1778. // digital events
  1779. buttons = newStatePtr->Gamepad.wButtons ^ oldStatePtr->Gamepad.wButtons;
  1780. if ( buttons )
  1781. {
  1782. // determine if dpad press is axial or diagonal combos
  1783. bool bDpadIsAxial = IsPowerOfTwo( newStatePtr->Gamepad.wButtons & (XINPUT_GAMEPAD_DPAD_UP|XINPUT_GAMEPAD_DPAD_DOWN|XINPUT_GAMEPAD_DPAD_LEFT|XINPUT_GAMEPAD_DPAD_RIGHT) );
  1784. // determine digital difference - up or down?
  1785. for ( int i = 0; i < sizeof( g_digitalXKeyTable )/sizeof( g_digitalXKeyTable[0] ); ++i )
  1786. {
  1787. mask = buttons & g_digitalXKeyTable[i].xinput;
  1788. if ( !mask )
  1789. continue;
  1790. if ( mask & newStatePtr->Gamepad.wButtons )
  1791. {
  1792. // down event
  1793. sample = XBX_MAX_BUTTONSAMPLE;
  1794. }
  1795. else
  1796. {
  1797. // up event
  1798. sample = 0;
  1799. }
  1800. // due to rocker mechanics, allow only 1 of 4 behavior
  1801. // the last down axial event trumps, preventing diagonals causing multiple events
  1802. if ( mask & (XINPUT_GAMEPAD_DPAD_UP|XINPUT_GAMEPAD_DPAD_DOWN|XINPUT_GAMEPAD_DPAD_LEFT|XINPUT_GAMEPAD_DPAD_RIGHT) )
  1803. {
  1804. if ( !bDpadIsAxial )
  1805. {
  1806. // diagonal dpad event, discard any dpad event that isn't the lock
  1807. if ( pXDevice->dpadLock && pXDevice->dpadLock != mask )
  1808. continue;
  1809. }
  1810. else if ( sample )
  1811. {
  1812. // axial dpad down event, set the lock
  1813. pXDevice->dpadLock = mask;
  1814. }
  1815. }
  1816. PostXKeyEvent( pXDevice->userId, (xKey_t)g_digitalXKeyTable[i].xkey, sample );
  1817. }
  1818. }
  1819. // analog events
  1820. // queue left trigger axis analog response
  1821. if ( newStatePtr->Gamepad.bLeftTrigger <= XINPUT_GAMEPAD_TRIGGER_THRESHOLD )
  1822. {
  1823. newStatePtr->Gamepad.bLeftTrigger = 0;
  1824. }
  1825. sample = newStatePtr->Gamepad.bLeftTrigger;
  1826. if ( sample != oldStatePtr->Gamepad.bLeftTrigger )
  1827. {
  1828. PostXKeyEvent( pXDevice->userId, XK_BUTTON_LTRIGGER, ( int )( sample * ( float )XBX_MAX_BUTTONSAMPLE/( float )XBX_MAX_ANALOGSAMPLE ) );
  1829. }
  1830. // queue right trigger axis analog response
  1831. if ( newStatePtr->Gamepad.bRightTrigger <= XINPUT_GAMEPAD_TRIGGER_THRESHOLD )
  1832. {
  1833. newStatePtr->Gamepad.bRightTrigger = 0;
  1834. }
  1835. sample = newStatePtr->Gamepad.bRightTrigger;
  1836. if ( sample != oldStatePtr->Gamepad.bRightTrigger )
  1837. {
  1838. PostXKeyEvent( pXDevice->userId, XK_BUTTON_RTRIGGER, ( int )( sample * ( float )XBX_MAX_BUTTONSAMPLE/( float )XBX_MAX_ANALOGSAMPLE ) );
  1839. }
  1840. int nX1 = 0, nY1 = 0, nX2 = 0, nY2 = 0;
  1841. extern ConVar joy_deadzone_mode;
  1842. switch ( joy_deadzone_mode.GetInt() )
  1843. {
  1844. case JOYSTICK_DEADZONE_CROSS:
  1845. nX1 = NormalizeStickValue_Cross( newStatePtr->Gamepad.sThumbLX, pXDevice->stickThreshold[STICK1_AXIS_X], pXDevice->stickScale[STICK1_AXIS_X] );
  1846. nY1 = NormalizeStickValue_Cross( newStatePtr->Gamepad.sThumbLY, pXDevice->stickThreshold[STICK1_AXIS_Y], pXDevice->stickScale[STICK1_AXIS_Y] );
  1847. nX2 = NormalizeStickValue_Cross( newStatePtr->Gamepad.sThumbRX, pXDevice->stickThreshold[STICK2_AXIS_X], pXDevice->stickScale[STICK2_AXIS_X] );
  1848. nY2 = NormalizeStickValue_Cross( newStatePtr->Gamepad.sThumbRY, pXDevice->stickThreshold[STICK2_AXIS_Y], pXDevice->stickScale[STICK2_AXIS_Y] );
  1849. break;
  1850. case JOYSTICK_DEADZONE_SQUARE:
  1851. NormalizeStickValue_Square( newStatePtr->Gamepad.sThumbLX, newStatePtr->Gamepad.sThumbLY, pXDevice->stickThreshold[STICK1_AXIS_X], pXDevice->stickThreshold[STICK1_AXIS_Y], &nX1, &nY1 );
  1852. NormalizeStickValue_Square( newStatePtr->Gamepad.sThumbRX, newStatePtr->Gamepad.sThumbRY, pXDevice->stickThreshold[STICK2_AXIS_X], pXDevice->stickThreshold[STICK2_AXIS_Y], &nX2, &nY2 );
  1853. break;
  1854. default:
  1855. UNREACHABLE();
  1856. }
  1857. HandleXDeviceAxis( pXDevice, nX1, XK_STICK1_LEFT, XK_STICK1_RIGHT, STICK1_AXIS_X );
  1858. HandleXDeviceAxis( pXDevice, nY1, XK_STICK1_DOWN, XK_STICK1_UP, STICK1_AXIS_Y );
  1859. HandleXDeviceAxis( pXDevice, nX2, XK_STICK2_LEFT, XK_STICK2_RIGHT, STICK2_AXIS_X );
  1860. HandleXDeviceAxis( pXDevice, nY2, XK_STICK2_DOWN, XK_STICK2_UP, STICK2_AXIS_Y );
  1861. // toggle the states
  1862. pXDevice->newState ^= 1;
  1863. }
  1864. void CInputSystem::QueueMoveControllerRumble( float fRightMotor )
  1865. {
  1866. #if defined( _PS3 )
  1867. WORD wNewRight = ( WORD )( XBX_MAX_MOTOR_SPEED * fRightMotor );
  1868. if ( wNewRight > XBX_MAX_MOTOR_SPEED )
  1869. wNewRight = XBX_MAX_MOTOR_SPEED;
  1870. if ( fRightMotor != g_PS3_XInputInfo.ps3_move_rumble_value )
  1871. {
  1872. g_PS3_XInputInfo.ps3_move_rumble_value = wNewRight;
  1873. g_PS3_XInputInfo.ps3_move_rumble_queued = true;
  1874. }
  1875. #endif
  1876. }
  1877. //-----------------------------------------------------------------------------
  1878. // Purpose: Queues a left and right motor value for the Xbox controller
  1879. //-----------------------------------------------------------------------------
  1880. void CInputSystem::SetXDeviceRumble( float fLeftMotor, float fRightMotor, int userId )
  1881. {
  1882. WORD wOldLeft, wOldRight;// Last values we sent
  1883. WORD wNewLeft, wNewRight;// Values we're about to send.
  1884. xdevice_t* pXDevice;
  1885. if ( IsDeviceReadingInput( INPUT_DEVICE_PLAYSTATION_MOVE ) ||
  1886. IsDeviceReadingInput( INPUT_DEVICE_SHARPSHOOTER ) )
  1887. {
  1888. // [dkorus] route move controller commands seperately, no need for an pXDevice for the move controller
  1889. // note: move controller only needs one motor setting
  1890. QueueMoveControllerRumble( fRightMotor );
  1891. return;
  1892. }
  1893. if ( userId == INVALID_USER_ID )
  1894. return;
  1895. pXDevice = &m_XDevices[userId];
  1896. // can only set rumble on active controllers
  1897. if ( pXDevice->userId == INVALID_USER_ID )
  1898. {
  1899. return;
  1900. }
  1901. wNewLeft = ( WORD )( XBX_MAX_MOTOR_SPEED * fLeftMotor );
  1902. wNewRight = ( WORD )( XBX_MAX_MOTOR_SPEED * fRightMotor );
  1903. if ( wNewLeft > XBX_MAX_MOTOR_SPEED )
  1904. wNewLeft = XBX_MAX_MOTOR_SPEED;
  1905. if ( wNewRight > XBX_MAX_MOTOR_SPEED )
  1906. wNewRight = XBX_MAX_MOTOR_SPEED;
  1907. wOldLeft = pXDevice->vibration.wLeftMotorSpeed;
  1908. wOldRight = pXDevice->vibration.wRightMotorSpeed;
  1909. if ( wNewLeft != wOldLeft || wNewRight != wOldRight )
  1910. {
  1911. pXDevice->vibration.wLeftMotorSpeed = wNewLeft;
  1912. pXDevice->vibration.wRightMotorSpeed = wNewRight;
  1913. pXDevice->pendingRumbleUpdate = true;
  1914. }
  1915. }
  1916. void CInputSystem::SetMotionControllerCalibrationInvalid( void )
  1917. {
  1918. #if defined( PLATFORM_PS3 )
  1919. g_pMoveController->InvalidateCalibration();
  1920. #endif // PLATFORM_PS3
  1921. }
  1922. void CInputSystem::StepMotionControllerCalibration( void )
  1923. {
  1924. #if defined( PLATFORM_PS3 )
  1925. g_pMoveController->StepMotionControllerCalibration();
  1926. #endif // PLATFORM_PS3
  1927. }
  1928. void CInputSystem::ResetMotionControllerScreenCalibration( void )
  1929. {
  1930. #if defined( PLATFORM_PS3 )
  1931. g_pMoveController->ResetMotionControllerScreenCalibration();
  1932. #endif // PLATFORM_PS3
  1933. }