XInput_Scp/XInput_SCP.cpp (308 lines of code) (raw):

#include "stdafx.h" static CSCPController* l_Pad[XUSER_MAX_COUNT]; static BOOL l_bPassThrough = false, l_bStarted = false, l_bUnloaded = false; static DWORD l_nPads = 0, l_nAttached = 0, l_nBtPads = 0; BOOL LoadApi(BOOL bEnable) { if (bEnable) l_nAttached++; else l_nAttached--; if (bEnable && !l_bStarted && !l_bUnloaded) { load_lib_usb(); WRAP_LoadXInput(true); // Load Bluetooth DS3s CBTConnection* BtPad = new CBTConnection(); if (BtPad->Open()) { l_nBtPads = BtPad->CollectionSize; for(DWORD Index = 0; Index < BtPad->CollectionSize; Index++) { l_Pad[l_nPads++] = BtPad; } } else delete BtPad; CSCPController* Pad; // Load DS3s if (l_nBtPads == 0) // Only if not using BTH Server { for (DWORD Index = 0; Index < XUSER_MAX_COUNT * CDS3Controller::CollectionSize && l_nPads < XUSER_MAX_COUNT; Index++) { Pad = new CDS3Controller(Index); if (Pad->Open()) l_Pad[l_nPads++] = Pad; else { delete Pad; break; } } } // Load SL3s for (DWORD Index = 0; Index < XUSER_MAX_COUNT * CSL3Controller::CollectionSize && l_nPads < XUSER_MAX_COUNT; Index++) { Pad = new CSL3Controller(Index); if (Pad->Open()) l_Pad[l_nPads++] = Pad; else { delete Pad; break; } } // Load DS2s for (DWORD Index = 0; Index < XUSER_MAX_COUNT * CDS2Controller::CollectionSize && l_nPads < XUSER_MAX_COUNT; Index++) { Pad = new CDS2Controller(Index); if (Pad->Open()) l_Pad[l_nPads++] = Pad; else delete Pad; } // Load X360s if (l_nBtPads == 0) // Only if not using BTH Server { for (DWORD Index = 0; Index < XUSER_MAX_COUNT * CX360Controller::CollectionSize && l_nPads < XUSER_MAX_COUNT; Index++) { Pad = new CX360Controller(Index); if (Pad->Open()) l_Pad[l_nPads++] = Pad; else delete Pad; } } l_bStarted = true; if (l_nPads == 0) { // No Devices found, PassThrough only l_bPassThrough = true; } } else if (!bEnable && l_bStarted && !l_bUnloaded && l_nAttached == 0) { l_bStarted = false; l_bUnloaded = true; if (l_nBtPads > 0) { l_Pad[0]->Close(); delete l_Pad[0]; } for (DWORD Index = l_nBtPads; Index < l_nPads; Index++) { l_Pad[Index]->Close(); delete l_Pad[Index]; } return WRAP_LoadXInput(bEnable); } return true; } DWORD WINAPI XInputGetState ( __in DWORD dwUserIndex, // Index of the gamer associated with the device __out XINPUT_STATE* pState // Receives the current state ) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->GetState(dwUserIndex, pState); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputGetState(dwUserIndex, pState); } DWORD WINAPI XInputSetState ( __in DWORD dwUserIndex, // Index of the gamer associated with the device __in XINPUT_VIBRATION* pVibration // The vibration information to send to the controller ) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->SetState(dwUserIndex, pVibration); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputSetState(dwUserIndex, pVibration); } DWORD WINAPI XInputGetCapabilities ( __in DWORD dwUserIndex, // Index of the gamer associated with the device __in DWORD dwFlags, // Input flags that identify the device type __out XINPUT_CAPABILITIES* pCapabilities // Receives the capabilities ) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->GetCapabilities(dwUserIndex, dwFlags, pCapabilities); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputGetCapabilities(dwUserIndex, dwFlags, pCapabilities); } void WINAPI XInputEnable ( __in BOOL enable // [in] Indicates whether xinput is enabled or disabled. ) { if (l_bUnloaded) return; if (!l_bStarted) LoadApi(true); if (!enable) { XINPUT_VIBRATION Vibration = { 0, 0 }; for (DWORD nPad = 0; nPad < l_nPads; nPad++) { XInputSetState(nPad, &Vibration); } } WRAP_XInputEnable(enable); } DWORD WINAPI XInputGetDSoundAudioDeviceGuids ( __in DWORD dwUserIndex, // Index of the gamer associated with the device __out GUID* pDSoundRenderGuid, // DSound device ID for render __out GUID* pDSoundCaptureGuid // DSound device ID for capture ) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->GetDSoundAudioDeviceGuids(dwUserIndex, pDSoundRenderGuid, pDSoundCaptureGuid); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputGetDSoundAudioDeviceGuids(dwUserIndex, pDSoundRenderGuid, pDSoundCaptureGuid); } DWORD WINAPI XInputGetBatteryInformation ( __in DWORD dwUserIndex, // Index of the gamer associated with the device __in BYTE devType, // Which device on this user index __out XINPUT_BATTERY_INFORMATION* pBatteryInformation // Contains the level and types of batteries ) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->GetBatteryInformation(dwUserIndex, devType, pBatteryInformation); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputGetBatteryInformation(dwUserIndex, devType, pBatteryInformation); } DWORD WINAPI XInputGetKeystroke ( __in DWORD dwUserIndex, // Index of the gamer associated with the device __reserved DWORD dwReserved, // Reserved for future use __out PXINPUT_KEYSTROKE pKeystroke // Pointer to an XINPUT_KEYSTROKE structure that receives an input event. ) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->GetKeystroke(dwUserIndex, dwReserved, pKeystroke); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputGetKeystroke(dwUserIndex, dwReserved, pKeystroke); } DWORD WINAPI XInputGetExtended(DWORD dwUserIndex, SCP_EXTN* pPressure) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->GetExtended(dwUserIndex, pPressure); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return ERROR_NOT_SUPPORTED; } // UNDOCUMENTED DWORD WINAPI XInputGetStateEx(DWORD dwUserIndex, XINPUT_STATE* pState) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->GetStateEx(dwUserIndex, pState); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputGetStateEx(dwUserIndex, pState); } DWORD WINAPI XInputWaitForGuideButton(DWORD dwUserIndex, DWORD dwFlag, LPVOID pVoid) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->WaitForGuideButton(dwUserIndex, dwFlag, pVoid); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputWaitForGuideButton(dwUserIndex, dwFlag, pVoid); } DWORD WINAPI XInputCancelGuideButtonWait(DWORD dwUserIndex) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->CancelGuideButtonWait(dwUserIndex); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputCancelGuideButtonWait(dwUserIndex); } DWORD WINAPI XInputPowerOffController(DWORD dwUserIndex) { if (l_bUnloaded) return ERROR_DEVICE_NOT_CONNECTED; if (!l_bStarted) LoadApi(true); if (!l_bPassThrough) { if (dwUserIndex < l_nPads) { return l_Pad[dwUserIndex]->PowerOffController(dwUserIndex); } else { return ERROR_DEVICE_NOT_CONNECTED; } } return WRAP_XInputPowerOffController(dwUserIndex); }