Leaked source code of windows server 2003
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.

905 lines
26 KiB

  1. //@doc
  2. /******************************************************
  3. **
  4. ** @module DPACK.CPP | DataPackager implementation file
  5. **
  6. ** Description:
  7. **
  8. ** History:
  9. ** Created 1/05/98 Matthew L. Coill (mlc)
  10. **
  11. ** (c) 1986-1998 Microsoft Corporation. All Rights Reserved.
  12. ******************************************************/
  13. #include "DPack.h"
  14. #include "FFDevice.h"
  15. #include "Midi_Obj.hpp"
  16. #include "joyregst.hpp"
  17. #include "SW_Error.hpp"
  18. #include "Hau_midi.hpp"
  19. #include "CritSec.h"
  20. DataPackager* g_pDataPackager = NULL;
  21. extern CJoltMidi* g_pJoltMidi;
  22. //
  23. // --- MIDI Command codes 200
  24. //
  25. #define PLAYSOLO_OP_200 0x00
  26. #define DESTROY_OP_200 0x01
  27. #define PLAYSUPER_OP_200 0x02
  28. #define STOP_OP_200 0x03
  29. #define STATUS_OP_200 0x04
  30. #define FORCEX_OP_200 0x06
  31. #define FORCEY_OP_200 0x07
  32. //#define MODIFY_CMD_200 0xF1 -- In Header
  33. //#define EFFECT_CMD_200 0xF2 -- In Header
  34. #define DEVICE_CMD_200 0xF3
  35. #define SHUTDOWN_OP_200 0x01
  36. #define ENABLE_OP_200 0x02
  37. #define DISABLE_OP_200 0x03
  38. #define PAUSE_OP_200 0x04
  39. #define CONTINUE_OP_200 0x05
  40. #define STOPALL_OP_200 0x06
  41. #define KILLMIDI_OP_200 0x07
  42. #define GAIN_SCALE_200 78.74
  43. #define PERCENT_SHIFT 10000
  44. #define PERCENT_TO_DEVICE 158
  45. /************** DataPacket class ******************/
  46. DataPacket::DataPacket() :
  47. m_BytesOfData(0),
  48. m_AckNackMethod(0),
  49. m_AckNackDelay(0),
  50. m_AckNackTimeout(0),
  51. m_NumberOfRetries(0)
  52. {
  53. m_pData = m_pFixedData;
  54. }
  55. DataPacket::~DataPacket()
  56. {
  57. if (m_pData != m_pFixedData) {
  58. delete[] m_pData;
  59. }
  60. m_pData = NULL;
  61. m_BytesOfData = 0;
  62. }
  63. BOOL DataPacket::AllocateBytes(DWORD numBytes)
  64. {
  65. if (m_pData != m_pFixedData) {
  66. delete[] m_pData;
  67. }
  68. if (numBytes <= 32) {
  69. m_pData = m_pFixedData;
  70. } else {
  71. m_pData = new BYTE[numBytes];
  72. }
  73. m_BytesOfData = numBytes;
  74. m_AckNackMethod = ACKNACK_NOTHING;
  75. m_AckNackDelay = 0;
  76. m_AckNackTimeout = 0;
  77. m_NumberOfRetries = 0;
  78. return (m_pData != NULL);
  79. }
  80. /************** DataPackeger class ******************/
  81. DataPackager::DataPackager() :
  82. m_NumDataPackets(0),
  83. m_DirectInputVersion(0)
  84. {
  85. m_pDataPackets = m_pStaticPackets;
  86. }
  87. DataPackager::~DataPackager()
  88. {
  89. if (m_pDataPackets != m_pStaticPackets) {
  90. delete[] m_pDataPackets;
  91. }
  92. m_NumDataPackets = 0;
  93. m_pDataPackets = NULL;
  94. }
  95. HRESULT DataPackager::Escape(DWORD effectID, LPDIEFFESCAPE pEscape)
  96. {
  97. ClearPackets();
  98. return SUCCESS;
  99. }
  100. HRESULT DataPackager::SetGain(DWORD gain)
  101. {
  102. ClearPackets();
  103. return SUCCESS;
  104. }
  105. HRESULT DataPackager::SendForceFeedbackCommand(DWORD state)
  106. {
  107. ClearPackets();
  108. return SUCCESS;
  109. }
  110. HRESULT DataPackager::GetForceFeedbackState(DIDEVICESTATE* pDeviceState)
  111. {
  112. ClearPackets();
  113. return SUCCESS;
  114. }
  115. HRESULT DataPackager::CreateEffect(const InternalEffect& effect, DWORD diFlags)
  116. {
  117. if (!AllocateDataPackets(1)) {
  118. return SFERR_DRIVER_ERROR;
  119. }
  120. DataPacket* commandPacket = GetPacket(0);
  121. HRESULT hr = effect.FillCreatePacket(*commandPacket);
  122. if (FAILED(hr)) {
  123. ClearPackets();
  124. }
  125. return hr;
  126. }
  127. HRESULT DataPackager::ModifyEffect(InternalEffect& currentEffect, InternalEffect& newEffect, DWORD modFlags)
  128. {
  129. return currentEffect.Modify(newEffect, modFlags);
  130. }
  131. HRESULT DataPackager::DestroyEffect(DWORD downloadID)
  132. {
  133. ClearPackets();
  134. return SUCCESS;
  135. }
  136. HRESULT DataPackager::StartEffect(DWORD downloadID, DWORD mode, DWORD count)
  137. {
  138. ClearPackets();
  139. return SUCCESS;
  140. }
  141. HRESULT DataPackager::StopEffect(DWORD downloadID)
  142. {
  143. ClearPackets();
  144. return SUCCESS;
  145. }
  146. HRESULT DataPackager::GetEffectStatus(DWORD downloadID)
  147. {
  148. ClearPackets();
  149. return SUCCESS;
  150. }
  151. HRESULT DataPackager::SetMidiChannel(BYTE channel)
  152. {
  153. ClearPackets();
  154. return SUCCESS;
  155. }
  156. HRESULT DataPackager::ForceOut(LONG lForceData, ULONG ulAxisMask)
  157. {
  158. ClearPackets();
  159. return SUCCESS;
  160. }
  161. DataPacket* DataPackager::GetPacket(USHORT packet) const
  162. {
  163. if ((packet >= 0) && (packet < m_NumDataPackets)) {
  164. return (m_pDataPackets + packet);
  165. }
  166. return NULL;
  167. }
  168. BOOL DataPackager::AllocateDataPackets(USHORT numPackets)
  169. {
  170. // Out with the old
  171. if (m_pDataPackets != m_pStaticPackets) { // Allocated, need to deallocate
  172. delete[] m_pDataPackets;
  173. } else { // Static, need to uninitialize
  174. for (int i = 0; i < m_NumDataPackets; i++) {
  175. m_pStaticPackets[i].AllocateBytes(0);
  176. }
  177. }
  178. // In with the new
  179. if (numPackets <= 3) {
  180. m_pDataPackets = m_pStaticPackets;
  181. } else {
  182. m_pDataPackets = new DataPacket[numPackets];
  183. }
  184. m_NumDataPackets = numPackets;
  185. return (m_pDataPackets != NULL);
  186. }
  187. void DataPackager::ClearPackets()
  188. {
  189. if (m_pDataPackets != m_pStaticPackets) { // Were allocated (deallocate)
  190. delete[] m_pDataPackets;
  191. m_pDataPackets = m_pStaticPackets;
  192. } else { // Static, need to uninitialize
  193. for (int i = 0; i < m_NumDataPackets; i++) {
  194. m_pStaticPackets[i].AllocateBytes(0);
  195. }
  196. }
  197. m_NumDataPackets = 0;
  198. }
  199. /************** DataPackeger100 class ******************/
  200. HRESULT DataPackager100::SetGain(DWORD gain)
  201. {
  202. if (!AllocateDataPackets(2)) {
  203. return SFERR_DRIVER_ERROR;
  204. }
  205. // Packet to set index15 (gain) of System Effect
  206. DataPacket* setIndexPacket = GetPacket(0);
  207. if (!setIndexPacket->AllocateBytes(3)) {
  208. ClearPackets();
  209. return SFERR_DRIVER_ERROR;
  210. }
  211. setIndexPacket->m_pData[0] = EFFECT_CMD | DEFAULT_MIDI_CHANNEL;
  212. setIndexPacket->m_pData[1] = SET_INDEX | (BYTE) (INDEX15 << 2);
  213. setIndexPacket->m_pData[2] = SYSTEM_EFFECT_ID;
  214. setIndexPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_SETINDEX);
  215. setIndexPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  216. // Packet to set modify data[index] of current effect
  217. DataPacket* modifyParamPacket = GetPacket(1);
  218. if (!modifyParamPacket->AllocateBytes(3)) {
  219. ClearPackets();
  220. return SFERR_DRIVER_ERROR;
  221. }
  222. modifyParamPacket->m_pData[0] = MODIFY_CMD | DEFAULT_MIDI_CHANNEL;
  223. gain /= SCALE_GAIN;
  224. gain *= DWORD(MAX_SCALE);
  225. modifyParamPacket->m_pData[1] = BYTE(gain & 0x7f);
  226. modifyParamPacket->m_pData[2] = (BYTE) ((gain >> 7) & 0x7f);
  227. modifyParamPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_MODIFYPARAM);
  228. modifyParamPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  229. return SUCCESS;
  230. }
  231. HRESULT DataPackager100::SendForceFeedbackCommand(DWORD state)
  232. {
  233. if (!AllocateDataPackets(1)) {
  234. return SFERR_DRIVER_ERROR;
  235. }
  236. // Packet to set index15 (gain) of System Effect
  237. DataPacket* commandPacket = GetPacket(0);
  238. if (!commandPacket->AllocateBytes(2)) {
  239. ClearPackets();
  240. return SFERR_DRIVER_ERROR;
  241. }
  242. commandPacket->m_pData[0] = SYSTEM_CMD | DEFAULT_MIDI_CHANNEL;
  243. switch (state) {
  244. case DISFFC_SETACTUATORSON:
  245. commandPacket->m_pData[1] = SWDEV_FORCE_ON; break;
  246. case DISFFC_SETACTUATORSOFF:
  247. commandPacket->m_pData[1] = SWDEV_FORCE_OFF; break;
  248. case DISFFC_PAUSE:
  249. commandPacket->m_pData[1] = SWDEV_PAUSE; break;
  250. case DISFFC_CONTINUE:
  251. commandPacket->m_pData[1] = SWDEV_CONTINUE; break;
  252. case DISFFC_STOPALL:
  253. commandPacket->m_pData[1] = SWDEV_STOP_ALL; break;
  254. case DISFFC_RESET:
  255. commandPacket->m_pData[1] = SWDEV_SHUTDOWN; break;
  256. default: {
  257. ClearPackets();
  258. return SFERR_INVALID_PARAM;
  259. }
  260. }
  261. commandPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_SETDEVICESTATE);
  262. if (NULL == g_pJoltMidi) return (SFERR_DRIVER_ERROR);
  263. commandPacket->m_AckNackDelay = g_pJoltMidi->DelayParamsPtrOf()->dwHWResetDelay;
  264. commandPacket->m_AckNackTimeout = ACKNACK_TIMEOUT;
  265. return SUCCESS;
  266. }
  267. HRESULT DataPackager100::GetForceFeedbackState(LPDIDEVICESTATE pDeviceState)
  268. {
  269. return DataPackager::GetForceFeedbackState(pDeviceState);
  270. }
  271. HRESULT DataPackager100::DestroyEffect(DWORD downloadID)
  272. {
  273. ClearPackets();
  274. // Note: Cannot allow actually destroying the SYSTEM Effects - Control panel might call this
  275. if ((downloadID == SYSTEM_FRICTIONCANCEL_ID) || (downloadID == SYSTEM_EFFECT_ID) ||
  276. (downloadID == SYSTEM_RTCSPRING_ALIAS_ID) || (downloadID == SYSTEM_RTCSPRING_ID)) {
  277. ASSUME_NOT_REACHED();
  278. return S_FALSE; // User should have no acces to these
  279. }
  280. { // Check for valid Effect and destroy it
  281. InternalEffect* pEffect = g_ForceFeedbackDevice.RemoveEffect(downloadID);
  282. if (pEffect == NULL) {
  283. ASSUME_NOT_REACHED();
  284. return SFERR_INVALID_OBJECT;
  285. }
  286. delete pEffect;
  287. }
  288. // Allocate DestroyEffect packet
  289. if (!AllocateDataPackets(1)) {
  290. return SFERR_DRIVER_ERROR;
  291. }
  292. // Packet for destroy effect
  293. DataPacket* destroyPacket = GetPacket(0);
  294. if (!destroyPacket->AllocateBytes(3)) {
  295. ClearPackets();
  296. return SFERR_DRIVER_ERROR;
  297. }
  298. destroyPacket->m_pData[0] = EFFECT_CMD | DEFAULT_MIDI_CHANNEL;
  299. destroyPacket->m_pData[1] = DESTROY_EFFECT;
  300. destroyPacket->m_pData[2] = BYTE(downloadID);
  301. destroyPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_DESTROYEFFECT);
  302. if (NULL == g_pJoltMidi) return (SFERR_DRIVER_ERROR);
  303. destroyPacket->m_AckNackDelay = g_pJoltMidi->DelayParamsPtrOf()->dwDestroyEffectDelay;
  304. destroyPacket->m_AckNackTimeout = SHORT_MSG_TIMEOUT;
  305. return SUCCESS;
  306. }
  307. HRESULT DataPackager100::StartEffect(DWORD downloadID, DWORD mode, DWORD count)
  308. {
  309. if (downloadID == SYSTEM_EFFECT_ID) { // start has no meaning for raw force
  310. ClearPackets();
  311. return S_FALSE;
  312. }
  313. if (count != 1) { // Don't support PLAY_LOOP for this version
  314. ClearPackets();
  315. return SFERR_NO_SUPPORT;
  316. }
  317. if (downloadID == SYSTEM_RTCSPRING_ALIAS_ID) { // Remap RTC Spring ID Alias
  318. downloadID = SYSTEM_RTCSPRING_ID;
  319. }
  320. ASSUME(BYTE(downloadID) < MAX_EFFECT_IDS); // Small sanity check
  321. if (g_ForceFeedbackDevice.GetEffect(downloadID) == NULL) { // Check for valid Effect
  322. ClearPackets();
  323. ASSUME_NOT_REACHED();
  324. return SFERR_INVALID_OBJECT;
  325. }
  326. if (!AllocateDataPackets(1)) {
  327. return SFERR_DRIVER_ERROR;
  328. }
  329. // Packet for play effect
  330. DataPacket* playPacket = GetPacket(0);
  331. if (!playPacket->AllocateBytes(3)) {
  332. ClearPackets();
  333. return SFERR_DRIVER_ERROR;
  334. }
  335. playPacket->m_pData[0] = EFFECT_CMD | DEFAULT_MIDI_CHANNEL;
  336. playPacket->m_pData[2] = BYTE(downloadID);
  337. playPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_PLAYEFFECT);
  338. playPacket->m_AckNackTimeout = LONG_MSG_TIMEOUT;
  339. if (mode & DIES_SOLO) { // Is it PLAY_SOLO?
  340. playPacket->m_pData[1] = PLAY_EFFECT_SOLO;
  341. // pMidiEffect->SetPlayMode(PLAY_SOLO); // Update the playback mode for this Effect
  342. } else {
  343. playPacket->m_pData[1] = PLAY_EFFECT_SUPERIMPOSE;
  344. // pMidiEffect->SetPlayMode(PLAY_SUPERIMPOSE); // Update the playback mode for this Effect
  345. }
  346. return SUCCESS;
  347. }
  348. HRESULT DataPackager100::StopEffect(DWORD downloadID)
  349. {
  350. // Special case for putrawforce (Cannot stop - this is up for discussion)
  351. if (downloadID == SYSTEM_EFFECT_ID) {
  352. ClearPackets();
  353. return S_FALSE;
  354. }
  355. // Remap alias ID properly
  356. if (downloadID == SYSTEM_RTCSPRING_ALIAS_ID) {
  357. downloadID = SYSTEM_RTCSPRING_ID; // Jolt returned ID0 for RTC Spring so return send alias ID
  358. }
  359. if (g_ForceFeedbackDevice.GetEffect(downloadID) == NULL) { // Check for valid Effect
  360. ASSUME_NOT_REACHED();
  361. ClearPackets();
  362. return SFERR_INVALID_OBJECT;
  363. }
  364. if (!AllocateDataPackets(1)) {
  365. return SFERR_DRIVER_ERROR;
  366. }
  367. // Packet for stop effect
  368. DataPacket* stopPacket = GetPacket(0);
  369. if (!stopPacket->AllocateBytes(3)) {
  370. ClearPackets();
  371. return SFERR_DRIVER_ERROR;
  372. }
  373. stopPacket->m_pData[0] = EFFECT_CMD | DEFAULT_MIDI_CHANNEL;
  374. stopPacket->m_pData[1] = STOP_EFFECT;
  375. stopPacket->m_pData[2] = BYTE(downloadID);
  376. stopPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_STOPEFFECT);
  377. stopPacket->m_AckNackTimeout = SHORT_MSG_TIMEOUT;
  378. return SUCCESS;
  379. }
  380. HRESULT DataPackager100::GetEffectStatus(DWORD downloadID)
  381. {
  382. // Special case RTC Spring ID
  383. if (downloadID == SYSTEM_RTCSPRING_ALIAS_ID) {
  384. downloadID = SYSTEM_RTCSPRING_ID; // Jolt returned ID0 for RTC Spring so return send alias ID
  385. }
  386. if (!AllocateDataPackets(1)) {
  387. return SFERR_DRIVER_ERROR;
  388. }
  389. // Packet for stop effect
  390. DataPacket* packet = GetPacket(0);
  391. if (!packet->AllocateBytes(2)) {
  392. ClearPackets();
  393. return SFERR_DRIVER_ERROR;
  394. }
  395. packet->m_pData[0] = STATUS_CMD | DEFAULT_MIDI_CHANNEL;
  396. packet->m_pData[1] = BYTE(downloadID);
  397. packet->m_AckNackMethod = ACKNACK_NOTHING;
  398. if (NULL == g_pJoltMidi) return (SFERR_DRIVER_ERROR);
  399. packet->m_AckNackDelay = g_pJoltMidi->DelayParamsPtrOf()->dwGetEffectStatusDelay;
  400. return SUCCESS;
  401. }
  402. HRESULT DataPackager100::SetMidiChannel(BYTE channel)
  403. {
  404. if (!AllocateDataPackets(1)) {
  405. return SFERR_DRIVER_ERROR;
  406. }
  407. // Packet for channel set
  408. DataPacket* packet = GetPacket(0);
  409. if (!packet->AllocateBytes(9)) {
  410. ClearPackets();
  411. return SFERR_DRIVER_ERROR;
  412. }
  413. // SysEx Header
  414. packet->m_pData[0] = SYS_EX_CMD; // SysEX CMD
  415. packet->m_pData[1] = 0; // Escape to Manufacturer ID
  416. packet->m_pData[2] = MS_MANUFACTURER_ID & 0x7f; // Manufacturer High Byte
  417. packet->m_pData[3] = (MS_MANUFACTURER_ID >> 8) & 0x7f; // Manufacturer Low Byte (note shifted 8!)
  418. packet->m_pData[4] = JOLT_PRODUCT_ID; // Product ID
  419. // Midi Assign specific
  420. packet->m_pData[5] = MIDI_ASSIGN; // Opcode, midi assign
  421. packet->m_pData[6] = channel & 0x7F; // 7 bit channel ID
  422. // Midi Footer
  423. packet->m_pData[7] = InternalEffect::ComputeChecksum(*packet, 7); // Checksum
  424. packet->m_pData[8] = MIDI_EOX; // End of SysEX command
  425. packet->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_DEVICEINIT);
  426. packet->m_AckNackTimeout = ACKNACK_TIMEOUT;
  427. return SUCCESS;
  428. }
  429. HRESULT DataPackager100::ForceOut(LONG forceData, ULONG axisMask)
  430. {
  431. if (!AllocateDataPackets(1)) {
  432. return SFERR_DRIVER_ERROR;
  433. }
  434. // Packet to set index15 (gain) of System Effect
  435. DataPacket* pPacket = GetPacket(0);
  436. if (!pPacket->AllocateBytes(3)) {
  437. ClearPackets();
  438. return SFERR_DRIVER_ERROR;
  439. }
  440. pPacket->m_pData[0] = EFFECT_CMD | DEFAULT_MIDI_CHANNEL;
  441. pPacket->m_pData[1] = BYTE(int(forceData) << 2) & 0x7c;
  442. switch (axisMask) {
  443. case X_AXIS: {
  444. pPacket->m_pData[1] |= PUT_FORCE_X; break;
  445. }
  446. case Y_AXIS: {
  447. pPacket->m_pData[1] |= PUT_FORCE_Y; break;
  448. }
  449. // case X_AXIS | Y_AXIS: { // Never Sent!!!
  450. // pPacket->m_pData[1] |= PUT_FORCE_XY; break;
  451. // }
  452. default: {
  453. ClearPackets();
  454. return SFERR_INVALID_PARAM;
  455. }
  456. }
  457. pPacket->m_pData[2] = BYTE(int(forceData) >> 5) & 0x7f;
  458. pPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_SETINDEX);
  459. pPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  460. return SUCCESS;
  461. }
  462. /************** DataPackeger200 class ******************/
  463. BYTE DataPackager200::EffectCommandParity(const DataPacket& packet) const
  464. {
  465. BYTE w = packet.m_pData[0] ^ (packet.m_pData[1] & 0xF0) ^ packet.m_pData[2];
  466. return (w >> 4) ^ (w & 0x0F);
  467. }
  468. BYTE DataPackager200::DeviceCommandParity(const DataPacket& packet) const
  469. {
  470. BYTE w = packet.m_pData[0] ^ (packet.m_pData[1] & 0xF0);
  471. return (w >> 4) ^ (w & 0x0F);
  472. }
  473. // Gain is parameter 0 from effect 0
  474. HRESULT DataPackager200::SetGain(DWORD gain)
  475. {
  476. if (!AllocateDataPackets(1)) {
  477. return SFERR_DRIVER_ERROR;
  478. }
  479. DataPacket* modifyPacket = GetPacket(0);
  480. if ((modifyPacket == NULL) || (!modifyPacket->AllocateBytes(6))) {
  481. ClearPackets();
  482. return SFERR_DRIVER_ERROR;
  483. }
  484. DWORD value = DWORD(double(gain)/GAIN_SCALE_200);
  485. modifyPacket->m_pData[0] = MODIFY_CMD_200;
  486. modifyPacket->m_pData[1] = 0; // Temporary for checksum calc.
  487. modifyPacket->m_pData[2] = 0;
  488. modifyPacket->m_pData[3] = 0;
  489. modifyPacket->m_pData[4] = BYTE(value & 0x7F);
  490. modifyPacket->m_pData[5] = 0; // Gain is only 0 to 127
  491. // New checksum method just to be annoying
  492. BYTE checksum = modifyPacket->m_pData[0] + modifyPacket->m_pData[4];
  493. checksum = 0 - checksum;
  494. checksum &= 0xFF;
  495. modifyPacket->m_pData[1] = BYTE(checksum & 0x7F);
  496. modifyPacket->m_pData[2] |= BYTE(checksum >> 1) & 0x40;
  497. modifyPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_MODIFYPARAM);
  498. modifyPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  499. return SUCCESS;
  500. }
  501. HRESULT DataPackager200::SendForceFeedbackCommand(DWORD state)
  502. {
  503. if (!AllocateDataPackets(1)) {
  504. return SFERR_DRIVER_ERROR;
  505. }
  506. // Packet to set requested System Command
  507. DataPacket* commandPacket = GetPacket(0);
  508. if (!commandPacket->AllocateBytes(2)) {
  509. ClearPackets();
  510. return SFERR_DRIVER_ERROR;
  511. }
  512. commandPacket->m_pData[0] = DEVICE_CMD_200;
  513. switch (state) {
  514. case DISFFC_SETACTUATORSON:
  515. commandPacket->m_pData[1] = ENABLE_OP_200; break;
  516. case DISFFC_SETACTUATORSOFF:
  517. commandPacket->m_pData[1] = DISABLE_OP_200; break;
  518. case DISFFC_PAUSE:
  519. commandPacket->m_pData[1] = PAUSE_OP_200; break;
  520. case DISFFC_CONTINUE:
  521. commandPacket->m_pData[1] = CONTINUE_OP_200; break;
  522. case DISFFC_STOPALL:
  523. commandPacket->m_pData[1] = STOPALL_OP_200; break;
  524. case DISFFC_RESET:
  525. commandPacket->m_pData[1] = SHUTDOWN_OP_200; break;
  526. default: {
  527. ClearPackets();
  528. return SFERR_INVALID_PARAM;
  529. }
  530. }
  531. commandPacket->m_pData[1] = BYTE(commandPacket->m_pData[1] << 4);
  532. commandPacket->m_pData[1] |= DeviceCommandParity(*commandPacket) & 0x0F;
  533. commandPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_SETDEVICESTATE);
  534. commandPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  535. if (NULL == g_pJoltMidi) return (SFERR_DRIVER_ERROR);
  536. commandPacket->m_AckNackDelay = g_pJoltMidi->DelayParamsPtrOf()->dwHWResetDelay;
  537. commandPacket->m_AckNackTimeout = ACKNACK_TIMEOUT;
  538. return SUCCESS;
  539. }
  540. HRESULT DataPackager200::GetForceFeedbackState(DIDEVICESTATE* pDeviceState)
  541. {
  542. return DataPackager::GetForceFeedbackState(pDeviceState);
  543. }
  544. HRESULT DataPackager200::CreateEffect(const InternalEffect& effect, DWORD diFlags)
  545. {
  546. // Figure out the number of packets nessacary
  547. UINT totPackets = effect.GetModifyOnlyNeeded() + 1;
  548. if (!AllocateDataPackets((USHORT)totPackets)) {
  549. return SFERR_DRIVER_ERROR;
  550. }
  551. DataPacket* createPacket = GetPacket(0);
  552. HRESULT hr = effect.FillCreatePacket(*createPacket);
  553. if (hr != SUCCESS) {
  554. ClearPackets();
  555. return hr;
  556. }
  557. createPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_DOWNLOADEFFECT);
  558. createPacket->m_AckNackDelay = 0;
  559. createPacket->m_AckNackTimeout = SHORT_MSG_TIMEOUT;
  560. createPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  561. hr = effect.FillModifyOnlyParms(); // Add the params that can only be modified
  562. if (hr != SUCCESS) {
  563. ClearPackets();
  564. }
  565. return hr;
  566. }
  567. HRESULT DataPackager200::DestroyEffect(DWORD downloadID)
  568. {
  569. ClearPackets();
  570. // Note: Cannot allow actually destroying the SYSTEM Effects - Control panel might call this
  571. if ((downloadID == SYSTEM_FRICTIONCANCEL_ID) || (downloadID == SYSTEM_EFFECT_ID) ||
  572. (downloadID == SYSTEM_RTCSPRING_ALIAS_ID) || (downloadID == ID_RTCSPRING_200)) {
  573. ASSUME_NOT_REACHED();
  574. return S_FALSE; // User should have no acces to these
  575. }
  576. { // Check for valid Effect and destroy it
  577. InternalEffect* pEffect = g_ForceFeedbackDevice.RemoveEffect(downloadID);
  578. if (pEffect == NULL) {
  579. ASSUME_NOT_REACHED();
  580. return SFERR_INVALID_OBJECT;
  581. }
  582. delete pEffect;
  583. }
  584. // Allocate DestroyEffect packet
  585. if (!AllocateDataPackets(1)) {
  586. return SFERR_DRIVER_ERROR;
  587. }
  588. // Packet for destroy effect
  589. DataPacket* destroyPacket = GetPacket(0);
  590. if (!destroyPacket->AllocateBytes(3)) {
  591. ClearPackets();
  592. return SFERR_DRIVER_ERROR;
  593. }
  594. if (NULL == g_pJoltMidi) return (SFERR_DRIVER_ERROR);
  595. destroyPacket->m_pData[0] = EFFECT_CMD_200;
  596. destroyPacket->m_pData[1] = BYTE(DESTROY_OP_200 << 4);
  597. destroyPacket->m_pData[2] = BYTE(downloadID);
  598. destroyPacket->m_pData[1] |= EffectCommandParity(*destroyPacket) & 0x0F;
  599. destroyPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_DESTROYEFFECT);
  600. destroyPacket->m_AckNackDelay = g_pJoltMidi->DelayParamsPtrOf()->dwDestroyEffectDelay;
  601. destroyPacket->m_AckNackTimeout = SHORT_MSG_TIMEOUT;
  602. destroyPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  603. return SUCCESS;
  604. }
  605. HRESULT DataPackager200::StartEffect(DWORD downloadID, DWORD mode, DWORD count)
  606. {
  607. if ((downloadID == SYSTEM_EFFECT_ID) || (downloadID == RAW_FORCE_ALIAS)) { // start has no meaning for raw force
  608. ClearPackets();
  609. return S_FALSE;
  610. }
  611. #ifdef _DEBUG
  612. if (downloadID != SYSTEM_RTCSPRING_ALIAS_ID) { // Remap RTC Spring ID Alias
  613. ASSUME(BYTE(downloadID) < MAX_EFFECT_IDS); // Small sanity check
  614. }
  615. #endif _DEBUG
  616. InternalEffect* pEffect = g_ForceFeedbackDevice.GetEffect(downloadID);
  617. if (pEffect == NULL) { // Check for valid Effect
  618. ClearPackets();
  619. ASSUME_NOT_REACHED();
  620. return SFERR_INVALID_OBJECT;
  621. }
  622. if (count == 0) { // I can do this easily
  623. ClearPackets();
  624. return S_OK;
  625. }
  626. BOOL truncate = FALSE;
  627. if (count == INFINITE) { // Device expects zero for infinite
  628. count = 0;
  629. } else if (count > 127) { // Device MAX
  630. count = 127;
  631. truncate = TRUE;
  632. }
  633. int allocCount = 1;
  634. if ((mode & DIES_SOLO) && count != 1) {
  635. allocCount = 2; // Need to stopall for SOLO with count
  636. }
  637. if (!AllocateDataPackets((USHORT)allocCount)) {
  638. return SFERR_DRIVER_ERROR;
  639. }
  640. if (NULL == g_pJoltMidi) return (SFERR_DRIVER_ERROR);
  641. if (count != 1) { // Special case, done via modify
  642. BYTE nextPacket = 0;
  643. if (mode & DIES_SOLO) { // need to stop all first
  644. DataPacket* stopAllPacket = GetPacket(0);
  645. if (!stopAllPacket->AllocateBytes(2)) {
  646. ClearPackets();
  647. return SFERR_DRIVER_ERROR;
  648. }
  649. stopAllPacket->m_pData[0] = DEVICE_CMD_200;
  650. stopAllPacket->m_pData[1] = STOPALL_OP_200 << 4;
  651. stopAllPacket->m_pData[1] |= DeviceCommandParity(*stopAllPacket) & 0x0F;
  652. stopAllPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_SETDEVICESTATE);
  653. stopAllPacket->m_AckNackDelay = g_pJoltMidi->DelayParamsPtrOf()->dwHWResetDelay;
  654. stopAllPacket->m_AckNackTimeout = ACKNACK_TIMEOUT;
  655. stopAllPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  656. nextPacket = 1;
  657. }
  658. HRESULT hr = pEffect->FillModifyPacket200(nextPacket, pEffect->GetRepeatIndex(), count);
  659. if ((hr == S_OK) && (truncate == TRUE)) {
  660. return DI_TRUNCATED;
  661. }
  662. return hr;
  663. }
  664. // Packet for play effect
  665. DataPacket* playPacket = GetPacket(0);
  666. if (!playPacket->AllocateBytes(3)) {
  667. ClearPackets();
  668. return SFERR_DRIVER_ERROR;
  669. }
  670. playPacket->m_pData[0] = EFFECT_CMD_200;
  671. playPacket->m_pData[2] = BYTE(pEffect->GetDeviceID());
  672. playPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_PLAYEFFECT);
  673. playPacket->m_AckNackTimeout = LONG_MSG_TIMEOUT;
  674. playPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  675. if (mode & DIES_SOLO) { // Is it PLAY_SOLO?
  676. playPacket->m_pData[1] = PLAYSOLO_OP_200;
  677. } else {
  678. playPacket->m_pData[1] = PLAYSUPER_OP_200;
  679. }
  680. playPacket->m_pData[1] = BYTE(playPacket->m_pData[1] << 4);
  681. playPacket->m_pData[1] |= EffectCommandParity(*playPacket) & 0x0F;
  682. return SUCCESS;
  683. }
  684. HRESULT DataPackager200::StopEffect(DWORD downloadID)
  685. {
  686. // Special case for putrawforce (Cannot stop - this is up for discussion)
  687. if ((downloadID == SYSTEM_EFFECT_ID) || (downloadID == RAW_FORCE_ALIAS)) {
  688. ClearPackets();
  689. return S_FALSE;
  690. }
  691. // Remap alias ID properly
  692. if (downloadID == SYSTEM_RTCSPRING_ALIAS_ID) {
  693. downloadID = ID_RTCSPRING_200; // Jolt returned ID0 for RTC Spring so return send alias ID
  694. }
  695. if (g_ForceFeedbackDevice.GetEffect(downloadID) == NULL) { // Check for valid Effect
  696. ASSUME_NOT_REACHED();
  697. ClearPackets();
  698. return SFERR_INVALID_OBJECT;
  699. }
  700. if (!AllocateDataPackets(1)) {
  701. return SFERR_DRIVER_ERROR;
  702. }
  703. // Packet for stop effect
  704. DataPacket* stopPacket = GetPacket(0);
  705. if (!stopPacket->AllocateBytes(3)) {
  706. ClearPackets();
  707. return SFERR_DRIVER_ERROR;
  708. }
  709. stopPacket->m_pData[0] = EFFECT_CMD_200;
  710. stopPacket->m_pData[1] = BYTE(STOP_OP_200 << 4);
  711. stopPacket->m_pData[2] = BYTE(downloadID);
  712. stopPacket->m_pData[1] |= EffectCommandParity(*stopPacket) & 0x0F;
  713. stopPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_STOPEFFECT);
  714. stopPacket->m_AckNackTimeout = SHORT_MSG_TIMEOUT;
  715. stopPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  716. return SUCCESS;
  717. }
  718. HRESULT DataPackager200::GetEffectStatus(DWORD downloadID)
  719. {
  720. // Special case RTC Spring ID
  721. if (downloadID == SYSTEM_RTCSPRING_ALIAS_ID) {
  722. downloadID = ID_RTCSPRING_200; // Jolt returned ID0 for RTC Spring so return send alias ID
  723. }
  724. if (!AllocateDataPackets(1)) {
  725. return SFERR_DRIVER_ERROR;
  726. }
  727. // Packet for status effect command
  728. DataPacket* packet = GetPacket(0);
  729. if (!packet->AllocateBytes(3)) {
  730. ClearPackets();
  731. return SFERR_DRIVER_ERROR;
  732. }
  733. if (NULL == g_pJoltMidi) return (SFERR_DRIVER_ERROR);
  734. packet->m_pData[0] = EFFECT_CMD_200;
  735. packet->m_pData[1] = BYTE(STATUS_OP_200 << 4);
  736. packet->m_pData[2] = BYTE(downloadID);
  737. packet->m_pData[1] |= EffectCommandParity(*packet) & 0x0F;
  738. packet->m_AckNackMethod = ACKNACK_BUTTONSTATUS;
  739. packet->m_AckNackDelay = g_pJoltMidi->DelayParamsPtrOf()->dwGetEffectStatusDelay;
  740. packet->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  741. return SUCCESS;
  742. }
  743. HRESULT DataPackager200::ForceOut(LONG forceData, ULONG axisMask)
  744. {
  745. if (!AllocateDataPackets(1)) {
  746. return SFERR_DRIVER_ERROR;
  747. }
  748. // Packet to set index15 (gain) of System Effect
  749. DataPacket* pPacket = GetPacket(0);
  750. if (!pPacket->AllocateBytes(3)) {
  751. ClearPackets();
  752. return SFERR_DRIVER_ERROR;
  753. }
  754. pPacket->m_pData[0] = EFFECT_CMD_200;
  755. switch (axisMask) {
  756. case X_AXIS: {
  757. pPacket->m_pData[1] = BYTE(FORCEX_OP_200 << 4); break;
  758. }
  759. case Y_AXIS: {
  760. pPacket->m_pData[1] = BYTE(FORCEY_OP_200 << 4); break;
  761. }
  762. default: {
  763. ClearPackets();
  764. return SFERR_INVALID_PARAM;
  765. }
  766. }
  767. BYTE calc = BYTE((PERCENT_SHIFT - forceData)/PERCENT_TO_DEVICE);
  768. pPacket->m_pData[2] = BYTE(calc & 0x7f);
  769. pPacket->m_pData[1] |= EffectCommandParity(*pPacket) & 0x0F;
  770. pPacket->m_AckNackMethod = g_ForceFeedbackDevice.GetAckNackMethod(REGBITS_SETINDEX);
  771. pPacket->m_NumberOfRetries = MAX_RETRY_COUNT; // Probably differentiate this
  772. return SUCCESS;
  773. }