diff --git a/Source/Core/Core/HW/GCPad.cpp b/Source/Core/Core/HW/GCPad.cpp index 55d5c3a62d..1c61e3dd7f 100644 --- a/Source/Core/Core/HW/GCPad.cpp +++ b/Source/Core/Core/HW/GCPad.cpp @@ -64,68 +64,18 @@ void GetStatus(u8 _numPAD, GCPadStatus* _pPADStatus) return; } - // if we are on the next input cycle, update output and input - // if we can get a lock - static int _last_numPAD = 4; - if (_numPAD <= _last_numPAD) - { - g_controller_interface.UpdateOutput(); - g_controller_interface.UpdateInput(); - } - _last_numPAD = _numPAD; - // get input ((GCPad*)s_config.controllers[_numPAD])->GetInput(_pPADStatus); } -// __________________________________________________________________________________________________ -// Function: Rumble -// Purpose: Pad rumble! -// input: _numPad - Which pad to rumble. -// _uType - Command type (Stop=0, Rumble=1, Stop Hard=2). -// _uStrength - Strength of the Rumble -// output: none -// -void Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) +void Rumble(u8 _numPAD, const ControlState strength) { std::unique_lock lk(s_config.controls_lock, std::try_to_lock); - if (lk.owns_lock()) - { - // TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time - // set rumble - if (1 == _uType && _uStrength > 2) - { - ((GCPad*)s_config.controllers[ _numPAD ])->SetOutput(255); - } - else - { - ((GCPad*)s_config.controllers[ _numPAD ])->SetOutput(0); - } - } -} + if (!lk.owns_lock()) + return; -// __________________________________________________________________________________________________ -// Function: Motor -// Purpose: For devices with constant Force feedback -// input: _numPAD - The pad to operate on -// _uType - 06 = Motor On, 04 = Motor Off -// _uStrength - 00 = Left Strong, 127 = Left Weak, 128 = Right Weak, 255 = Right Strong -// output: none -// -void Motor(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) -{ - std::unique_lock lk(s_config.controls_lock, std::try_to_lock); - - if (lk.owns_lock()) - { - // TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time - // set rumble - if (_uType == 6) - { - ((GCPad*)s_config.controllers[ _numPAD ])->SetMotor(_uStrength); - } - } + ((GCPad*)s_config.controllers[ _numPAD ])->SetOutput(strength); } bool GetMicButton(u8 pad) diff --git a/Source/Core/Core/HW/GCPad.h b/Source/Core/Core/HW/GCPad.h index 6146891942..d9da72e9fc 100644 --- a/Source/Core/Core/HW/GCPad.h +++ b/Source/Core/Core/HW/GCPad.h @@ -17,8 +17,7 @@ void Initialize(void* const hwnd); InputConfig* GetConfig(); void GetStatus(u8 _numPAD, GCPadStatus* _pPADStatus); -void Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength); -void Motor(u8 _numPAD, unsigned int _uType, unsigned int _uStrength); +void Rumble(u8 _numPAD, const ControlState strength); bool GetMicButton(u8 pad); } diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp index da58c44af3..57af144311 100644 --- a/Source/Core/Core/HW/GCPadEmu.cpp +++ b/Source/Core/Core/HW/GCPadEmu.cpp @@ -120,16 +120,9 @@ void GCPad::GetInput(GCPadStatus* const pad) pad->triggerRight = static_cast(triggers[1] * 0xFF); } -void GCPad::SetMotor(const u8 on) +void GCPad::SetOutput(const ControlState strength) { - // map 0..255 to -1.0..1.0 - ControlState force = on / 127.5 - 1; - m_rumble->controls[0]->control_ref->State(force); -} - -void GCPad::SetOutput(const u8 on) -{ - m_rumble->controls[0]->control_ref->State(on); + m_rumble->controls[0]->control_ref->State(strength); } void GCPad::LoadDefaults(const ControllerInterface& ciface) diff --git a/Source/Core/Core/HW/GCPadEmu.h b/Source/Core/Core/HW/GCPadEmu.h index dc8bd835fd..9007cd5829 100644 --- a/Source/Core/Core/HW/GCPadEmu.h +++ b/Source/Core/Core/HW/GCPadEmu.h @@ -14,8 +14,7 @@ public: GCPad(const unsigned int index); void GetInput(GCPadStatus* const pad); - void SetOutput(const u8 on); - void SetMotor(const u8 on); + void SetOutput(const ControlState strength); bool GetMicButton() const; diff --git a/Source/Core/Core/HW/SI_DeviceDanceMat.cpp b/Source/Core/Core/HW/SI_DeviceDanceMat.cpp index 8f64fc962c..ca12a9e343 100644 --- a/Source/Core/Core/HW/SI_DeviceDanceMat.cpp +++ b/Source/Core/Core/HW/SI_DeviceDanceMat.cpp @@ -2,250 +2,40 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include "Core/Core.h" -#include "Core/CoreTiming.h" -#include "Core/Movie.h" -#include "Core/HW/EXI_Device.h" -#include "Core/HW/EXI_DeviceMic.h" -#include "Core/HW/GCPad.h" -#include "Core/HW/ProcessorInterface.h" -#include "Core/HW/SI.h" -#include "Core/HW/SI_Device.h" #include "Core/HW/SI_DeviceDanceMat.h" -#include "Core/HW/SystemTimers.h" -// --- Dance mat GameCube controller --- CSIDevice_DanceMat::CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber) - : ISIDevice(device, _iDeviceNumber) - , m_TButtonComboStart(0) - , m_TButtonCombo(0) - , m_LastButtonCombo(COMBO_NONE) + : CSIDevice_GCController(device, _iDeviceNumber) {} + +u32 CSIDevice_DanceMat::MapPadStatus(const GCPadStatus& pad_status) { - memset(&m_Origin, 0, sizeof(SOrigin)); - m_Origin.uCommand = CMD_ORIGIN; - m_Origin.uOriginStickX = 0x80; // center - m_Origin.uOriginStickY = 0x80; - m_Origin.uSubStickStickX = 0x80; - m_Origin.uSubStickStickY = 0x80; - m_Origin.uTrigger_L = 0x00; - m_Origin.uTrigger_R = 0x00; - - // Dunno if we need to do this, game/lib should set it? - m_Mode = 0x03; -} - -int CSIDevice_DanceMat::RunBuffer(u8* _pBuffer, int _iLength) -{ - // For debug logging only - ISIDevice::RunBuffer(_pBuffer, _iLength); - - // Read the command - EBufferCommands command = static_cast(_pBuffer[3]); - - // Handle it - switch (command) - { - case CMD_RESET: - *(u32*)&_pBuffer[0] = SI_DANCEMAT; - break; - - case CMD_DIRECT: - { - INFO_LOG(SERIALINTERFACE, "PAD - Direct (Length: %d)", _iLength); - u32 high, low; - GetData(high, low); - for (int i = 0; i < (_iLength - 1) / 2; i++) - { - _pBuffer[i + 0] = (high >> (i * 8)) & 0xff; - _pBuffer[i + 4] = (low >> (i * 8)) & 0xff; - } - } - break; - - case CMD_ORIGIN: - { - INFO_LOG(SERIALINTERFACE, "PAD - Get Origin"); - u8* pCalibration = reinterpret_cast(&m_Origin); - for (int i = 0; i < (int)sizeof(SOrigin); i++) - { - _pBuffer[i ^ 3] = *pCalibration++; - } - } - break; - - // Recalibrate (FiRES: i am not 100 percent sure about this) - case CMD_RECALIBRATE: - { - INFO_LOG(SERIALINTERFACE, "PAD - Recalibrate"); - u8* pCalibration = reinterpret_cast(&m_Origin); - for (int i = 0; i < (int)sizeof(SOrigin); i++) - { - _pBuffer[i ^ 3] = *pCalibration++; - } - } - break; - - // DEFAULT - default: - { - ERROR_LOG(SERIALINTERFACE, "Unknown SI command (0x%x)", command); - PanicAlert("SI: Unknown command (0x%x)", command); - } - break; - } - - return _iLength; -} - - -// GetData - -// Return true on new data (max 7 Bytes and 6 bits ;) -// [00?SYXBA] [1LRZUDRL] [x] [y] [cx] [cy] [l] [r] -// |\_ ERR_LATCH (error latched - check SISR) -// |_ ERR_STATUS (error on last GetData or SendCmd?) -bool CSIDevice_DanceMat::GetData(u32& _Hi, u32& _Low) -{ - GCPadStatus PadStatus; - memset(&PadStatus, 0, sizeof(PadStatus)); - - Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); - Movie::CallGCInputManip(&PadStatus, ISIDevice::m_iDeviceNumber); - - Movie::SetPolledDevice(); - if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, &PadStatus)) - { - } - else if (Movie::IsPlayingInput()) - { - Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber); - Movie::InputUpdate(); - } - else if (Movie::IsRecordingInput()) - { - Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); - Movie::InputUpdate(); - } - else - { - Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); - } - // Map the dpad to the blue arrows, the buttons to the orange arrows // Z = + button, Start = - button u16 map = 0; - if (PadStatus.button & PAD_BUTTON_UP) + if (pad_status.button & PAD_BUTTON_UP) map |= 0x1000; - if (PadStatus.button & PAD_BUTTON_DOWN) + if (pad_status.button & PAD_BUTTON_DOWN) map |= 0x2; - if (PadStatus.button & PAD_BUTTON_LEFT) + if (pad_status.button & PAD_BUTTON_LEFT) map |= 0x8; - if (PadStatus.button & PAD_BUTTON_RIGHT) + if (pad_status.button & PAD_BUTTON_RIGHT) map |= 0x4; - if (PadStatus.button & PAD_BUTTON_Y) + if (pad_status.button & PAD_BUTTON_Y) map |= 0x200; - if (PadStatus.button & PAD_BUTTON_A) + if (pad_status.button & PAD_BUTTON_A) map |= 0x10; - if (PadStatus.button & PAD_BUTTON_B) + if (pad_status.button & PAD_BUTTON_B) map |= 0x100; - if (PadStatus.button & PAD_BUTTON_X) + if (pad_status.button & PAD_BUTTON_X) map |= 0x800; - if (PadStatus.button & PAD_TRIGGER_Z) + if (pad_status.button & PAD_TRIGGER_Z) map |= 0x400; - if (PadStatus.button & PAD_BUTTON_START) + if (pad_status.button & PAD_BUTTON_START) map |= 0x1; - _Hi = (u32)(map << 16) | 0x8080; - - // Low bits are packed differently per mode - if (m_Mode == 0 || m_Mode == 5 || m_Mode == 6 || m_Mode == 7) - { - _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.substickY) << 16); // All 8 bits - _Low |= (u32)((u8)(PadStatus.substickX) << 24); // All 8 bits - } - else if (m_Mode == 1) - { - _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits - _Low |= (u32)((u8)PadStatus.triggerRight << 8); // All 8 bits - _Low |= (u32)((u8)PadStatus.triggerLeft << 16); // All 8 bits - _Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits - _Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits - } - else if (m_Mode == 2) - { - // Identifies the dance mat - _Low = 0x8080ffff; - } - else if (m_Mode == 3) - { - // Analog A/B are always 0 - _Low = (u8)PadStatus.triggerRight; // All 8 bits - _Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits - _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits - _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits - } - else if (m_Mode == 4) - { - _Low = (u8)(PadStatus.analogB); // All 8 bits - _Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits - // triggerLeft/Right are always 0 - _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits - _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits - } - return true; + return (u32)(map << 16) | 0x8080; } - -// SendCommand -void CSIDevice_DanceMat::SendCommand(u32 _Cmd, u8 _Poll) +void CSIDevice_DanceMat::HandleButtonCombos(const GCPadStatus& pad_status) { - UCommand command(_Cmd); - - switch (command.Command) - { - // Costis sent it in some demos :) - case 0x00: - break; - - case CMD_WRITE: - { - unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard - unsigned int uStrength = command.Parameter2; - - // get the correct pad number that should rumble locally when using netplay - const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); - - if (numPAD < 4) - Pad::Rumble(numPAD, uType, uStrength); - - if (!_Poll) - { - m_Mode = command.Parameter2; - INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode); - } - } - break; - - default: - { - ERROR_LOG(SERIALINTERFACE, "Unknown direct command (0x%x)", _Cmd); - PanicAlert("SI: Unknown direct command"); - } - break; - } -} - -// Savestate support -void CSIDevice_DanceMat::DoState(PointerWrap& p) -{ - p.Do(m_Origin); - p.Do(m_Mode); - p.Do(m_TButtonComboStart); - p.Do(m_TButtonCombo); - p.Do(m_LastButtonCombo); } diff --git a/Source/Core/Core/HW/SI_DeviceDanceMat.h b/Source/Core/Core/HW/SI_DeviceDanceMat.h index 3eaf5c4be8..16711d254f 100644 --- a/Source/Core/Core/HW/SI_DeviceDanceMat.h +++ b/Source/Core/Core/HW/SI_DeviceDanceMat.h @@ -4,98 +4,12 @@ #pragma once -#include "Core/HW/SI_Device.h" -#include "InputCommon/GCPadStatus.h" +#include "Core/HW/SI_DeviceGCController.h" -// standard GameCube controller -class CSIDevice_DanceMat : public ISIDevice +class CSIDevice_DanceMat : public CSIDevice_GCController { -private: - - // Commands - enum EBufferCommands - { - CMD_RESET = 0x00, - CMD_DIRECT = 0x40, - CMD_ORIGIN = 0x41, - CMD_RECALIBRATE = 0x42, - }; - - struct SOrigin - { - u8 uCommand;// Maybe should be button bits? - u8 unk_1; // ..and this would be the other half - u8 uOriginStickX; - u8 uOriginStickY; - u8 uSubStickStickX; - u8 uSubStickStickY; - u8 uTrigger_L; - u8 uTrigger_R; - u8 unk_4; - u8 unk_5; - u8 unk_6; - u8 unk_7; - }; - - enum EDirectCommands - { - CMD_WRITE = 0x40 - }; - - union UCommand - { - u32 Hex; - struct - { - u32 Parameter1 : 8; - u32 Parameter2 : 8; - u32 Command : 8; - u32 : 8; - }; - UCommand() {Hex = 0;} - UCommand(u32 _iValue) {Hex = _iValue;} - }; - - enum EButtonCombo - { - COMBO_NONE = 0, - COMBO_ORIGIN, - COMBO_RESET - }; - - // struct to compare input against - // Set on connection and (standard pad only) on button combo - SOrigin m_Origin; - - // PADAnalogMode - u8 m_Mode; - - // Timer to track special button combos: - // y, X, start for 3 seconds updates origin with current status - // Technically, the above is only on standard pad, wavebird does not support it for example - // b, x, start for 3 seconds triggers reset (PI reset button interrupt) - u64 m_TButtonComboStart, m_TButtonCombo; - // Type of button combo from the last/current poll - EButtonCombo m_LastButtonCombo; - public: - - // Constructor CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber); - - // Run the SI Buffer - virtual int RunBuffer(u8* _pBuffer, int _iLength) override; - - // Send and Receive pad input from network - static bool NetPlay_GetInput(u8 numPAD, GCPadStatus* status); - static u8 NetPlay_InGamePadToLocalPad(u8 numPAD); - - // Return true on new data - virtual bool GetData(u32& _Hi, u32& _Low) override; - - // Send a command directly - virtual void SendCommand(u32 _Cmd, u8 _Poll) override; - - // Savestate support - virtual void DoState(PointerWrap& p) override; + virtual u32 MapPadStatus(const GCPadStatus& pad_status) override; + virtual void HandleButtonCombos(const GCPadStatus& pad_status) override; }; diff --git a/Source/Core/Core/HW/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI_DeviceGCController.cpp index f3c6efcbb0..667df524ae 100644 --- a/Source/Core/Core/HW/SI_DeviceGCController.cpp +++ b/Source/Core/Core/HW/SI_DeviceGCController.cpp @@ -131,10 +131,7 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); } - // Thankfully changing mode does not change the high bits ;) - _Hi = (u32)((u8)PadStatus.stickY); - _Hi |= (u32)((u8)PadStatus.stickX << 8); - _Hi |= (u32)((u16)(PadStatus.button | PAD_USE_ORIGIN) << 16); + _Hi = MapPadStatus(PadStatus); // Low bits are packed differently per mode if (m_Mode == 0 || m_Mode == 5 || m_Mode == 6 || m_Mode == 7) @@ -181,11 +178,27 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits } + HandleButtonCombos(PadStatus); + return true; +} + +u32 CSIDevice_GCController::MapPadStatus(const GCPadStatus& pad_status) +{ + // Thankfully changing mode does not change the high bits ;) + u32 _Hi = 0; + _Hi = (u32)((u8)pad_status.stickY); + _Hi |= (u32)((u8)pad_status.stickX << 8); + _Hi |= (u32)((u16)(pad_status.button | PAD_USE_ORIGIN) << 16); + return _Hi; +} + +void CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status) +{ // Keep track of the special button combos (embedded in controller hardware... :( ) EButtonCombo tempCombo; - if ((PadStatus.button & 0xff00) == (PAD_BUTTON_Y|PAD_BUTTON_X|PAD_BUTTON_START)) + if ((pad_status.button & 0xff00) == (PAD_BUTTON_Y|PAD_BUTTON_X|PAD_BUTTON_START)) tempCombo = COMBO_ORIGIN; - else if ((PadStatus.button & 0xff00) == (PAD_BUTTON_B|PAD_BUTTON_X|PAD_BUTTON_START)) + else if ((pad_status.button & 0xff00) == (PAD_BUTTON_B|PAD_BUTTON_X|PAD_BUTTON_START)) tempCombo = COMBO_RESET; else tempCombo = COMBO_NONE; @@ -204,21 +217,18 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) ProcessorInterface::ResetButton_Tap(); else if (m_LastButtonCombo == COMBO_ORIGIN) { - m_Origin.uOriginStickX = PadStatus.stickX; - m_Origin.uOriginStickY = PadStatus.stickY; - m_Origin.uSubStickStickX = PadStatus.substickX; - m_Origin.uSubStickStickY = PadStatus.substickY; - m_Origin.uTrigger_L = PadStatus.triggerLeft; - m_Origin.uTrigger_R = PadStatus.triggerRight; + m_Origin.uOriginStickX = pad_status.stickX; + m_Origin.uOriginStickY = pad_status.stickY; + m_Origin.uSubStickStickX = pad_status.substickX; + m_Origin.uSubStickStickY = pad_status.substickY; + m_Origin.uTrigger_L = pad_status.triggerLeft; + m_Origin.uTrigger_R = pad_status.triggerRight; } m_LastButtonCombo = COMBO_NONE; } } - - return true; } - // SendCommand void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll) { @@ -239,7 +249,12 @@ void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll) const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); if (numPAD < 4) - Pad::Rumble(numPAD, uType, uStrength); + { + if (uType == 1 && uStrength > 2) + Pad::Rumble(numPAD, 1.0); + else + Pad::Rumble(numPAD, 0.0); + } if (!_Poll) { diff --git a/Source/Core/Core/HW/SI_DeviceGCController.h b/Source/Core/Core/HW/SI_DeviceGCController.h index 254df8d233..403b5a6dad 100644 --- a/Source/Core/Core/HW/SI_DeviceGCController.h +++ b/Source/Core/Core/HW/SI_DeviceGCController.h @@ -7,11 +7,9 @@ #include "Core/HW/SI_Device.h" #include "InputCommon/GCPadStatus.h" - -// standard GameCube controller class CSIDevice_GCController : public ISIDevice { -private: +protected: // Commands enum EBufferCommands @@ -24,8 +22,8 @@ private: struct SOrigin { - u8 uCommand;// Maybe should be button bits? - u8 unk_1; // ..and this would be the other half + u8 uCommand; // Maybe should be button bits? + u8 unk_1; // ..and this would be the other half u8 uOriginStickX; u8 uOriginStickY; u8 uSubStickStickX; @@ -94,6 +92,9 @@ public: // Return true on new data virtual bool GetData(u32& _Hi, u32& _Low) override; + virtual u32 MapPadStatus(const GCPadStatus& pad_status); + virtual void HandleButtonCombos(const GCPadStatus& pad_status); + // Send a command directly virtual void SendCommand(u32 _Cmd, u8 _Poll) override; diff --git a/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp b/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp index bf803c5ce0..cd13c3fd55 100644 --- a/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp +++ b/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp @@ -2,292 +2,47 @@ // Licensed under GPLv2 // Refer to the license.txt file included. - -#include "Core/Core.h" -#include "Core/CoreTiming.h" -#include "Core/Movie.h" -#include "Core/HW/EXI_Device.h" -#include "Core/HW/EXI_DeviceMic.h" #include "Core/HW/GCPad.h" -#include "Core/HW/ProcessorInterface.h" -#include "Core/HW/SI.h" -#include "Core/HW/SI_Device.h" #include "Core/HW/SI_DeviceGCSteeringWheel.h" -#include "Core/HW/SystemTimers.h" -// --- standard GameCube controller --- CSIDevice_GCSteeringWheel::CSIDevice_GCSteeringWheel(SIDevices device, int _iDeviceNumber) - : ISIDevice(device, _iDeviceNumber) - , m_TButtonComboStart(0) - , m_TButtonCombo(0) - , m_LastButtonCombo(COMBO_NONE) -{ - memset(&m_Origin, 0, sizeof(SOrigin)); - m_Origin.uCommand = CMD_ORIGIN; - m_Origin.uOriginStickX = 0x80; // center - m_Origin.uOriginStickY = 0x80; - m_Origin.uSubStickStickX = 0x80; - m_Origin.uSubStickStickY = 0x80; - m_Origin.uTrigger_L = 0x1F; // 0-30 is the lower deadzone - m_Origin.uTrigger_R = 0x1F; + : CSIDevice_GCController(device, _iDeviceNumber) +{} - // Dunno if we need to do this, game/lib should set it? - m_Mode = 0x03; -} - -int CSIDevice_GCSteeringWheel::RunBuffer(u8* _pBuffer, int _iLength) -{ - // For debug logging only - ISIDevice::RunBuffer(_pBuffer, _iLength); - - // Read the command - EBufferCommands command = static_cast(_pBuffer[3]); - - // Handle it - switch (command) - { - case CMD_RESET: - *(u32*)&_pBuffer[0] = SI_GC_STEERING; - break; - - case CMD_ORIGIN: - { - INFO_LOG(SERIALINTERFACE, "PAD - Get Origin"); - u8* pCalibration = reinterpret_cast(&m_Origin); - for (int i = 0; i < (int)sizeof(SOrigin); i++) - { - _pBuffer[i ^ 3] = *pCalibration++; - } - } - break; - - // Recalibrate (FiRES: i am not 100 percent sure about this) - case CMD_RECALIBRATE: - { - INFO_LOG(SERIALINTERFACE, "PAD - Recalibrate"); - u8* pCalibration = reinterpret_cast(&m_Origin); - for (int i = 0; i < (int)sizeof(SOrigin); i++) - { - _pBuffer[i ^ 3] = *pCalibration++; - } - } - break; - - // Seen in F-Zero GX - case CMD_MOTOR_OFF: - break; - - // DEFAULT - default: - { - ERROR_LOG(SERIALINTERFACE, "Unknown SI command (0x%x)", command); - } - break; - } - - return _iLength; -} - - -// GetData - -// Return true on new data (max 7 Bytes and 6 bits ;) -// [00?SYXBA] [1LRZUDRL] [x] [y] [cx] [cy] [l] [r] -// |\_ ERR_LATCH (error latched - check SISR) -// |_ ERR_STATUS (error on last GetData or SendCmd?) -bool CSIDevice_GCSteeringWheel::GetData(u32& _Hi, u32& _Low) -{ - GCPadStatus PadStatus; - memset(&PadStatus, 0, sizeof(PadStatus)); - - Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); - Movie::CallGCInputManip(&PadStatus, ISIDevice::m_iDeviceNumber); - - Movie::SetPolledDevice(); - if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, &PadStatus)) - { - } - else if (Movie::IsPlayingInput()) - { - Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber); - Movie::InputUpdate(); - } - else if (Movie::IsRecordingInput()) - { - Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); - Movie::InputUpdate(); - } - else - { - Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); - } - - // Thankfully changing mode does not change the high bits ;) - _Hi = (u32)((u8)PadStatus.stickX); // Steering - _Hi |= 0x800; // Pedal connected flag - _Hi |= (u32)((u16)(PadStatus.button | PAD_USE_ORIGIN) << 16); - - // Low bits are packed differently per mode - if (m_Mode == 0 || m_Mode == 5 || m_Mode == 7) - { - _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.substickY) << 16); // All 8 bits - _Low |= (u32)((u8)(PadStatus.substickX) << 24); // All 8 bits - } - else if (m_Mode == 1) - { - _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits - _Low |= (u32)((u8)PadStatus.triggerRight << 8); // All 8 bits - _Low |= (u32)((u8)PadStatus.triggerLeft << 16); // All 8 bits - _Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits - _Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits - } - else if (m_Mode == 2) - { - _Low = (u8)(PadStatus.analogB); // All 8 bits - _Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits - _Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 16); // Top 4 bits - _Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 20); // Top 4 bits - _Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits - _Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits - } - else if (m_Mode == 3) - { - // Analog A/B are always 0 - _Low = (u8)PadStatus.triggerRight; // All 8 bits - _Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits - _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits - _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits - } - else if (m_Mode == 4) - { - _Low = (u8)(PadStatus.analogB); // All 8 bits - _Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits - // triggerLeft/Right are always 0 - _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits - _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits - } - else if (m_Mode == 6) - { - _Low = (u8)PadStatus.triggerRight; // All 8 bits - _Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits - - // The GC Steering Wheel appears to have combined pedals - // (both the Accelerate and Brake pedals are mapped to a single axis) - // We use the stickY axis for the pedals. - if (PadStatus.stickY < 128) - _Low |= (u32)((u8)(255 - ((PadStatus.stickY & 0x7f) * 2)) << 16); // All 8 bits (Brake) - if (PadStatus.stickY >= 128) - _Low |= (u32)((u8)((PadStatus.stickY & 0x7f) * 2) << 24); // All 8 bits (Accelerate) - } - - // Keep track of the special button combos (embedded in controller hardware... :( ) - EButtonCombo tempCombo; - if ((PadStatus.button & 0xff00) == (PAD_BUTTON_Y|PAD_BUTTON_X|PAD_BUTTON_START)) - tempCombo = COMBO_ORIGIN; - else if ((PadStatus.button & 0xff00) == (PAD_BUTTON_B|PAD_BUTTON_X|PAD_BUTTON_START)) - tempCombo = COMBO_RESET; - else - tempCombo = COMBO_NONE; - if (tempCombo != m_LastButtonCombo) - { - m_LastButtonCombo = tempCombo; - if (m_LastButtonCombo != COMBO_NONE) - m_TButtonComboStart = CoreTiming::GetTicks(); - } - if (m_LastButtonCombo != COMBO_NONE) - { - m_TButtonCombo = CoreTiming::GetTicks(); - if ((m_TButtonCombo - m_TButtonComboStart) > SystemTimers::GetTicksPerSecond() * 3) - { - if (m_LastButtonCombo == COMBO_RESET) - { - ProcessorInterface::ResetButton_Tap(); - } - else if (m_LastButtonCombo == COMBO_ORIGIN) - { - m_Origin.uOriginStickX = PadStatus.stickX; - m_Origin.uOriginStickY = PadStatus.stickY; - m_Origin.uSubStickStickX = PadStatus.substickX; - m_Origin.uSubStickStickY = PadStatus.substickY; - m_Origin.uTrigger_L = PadStatus.triggerLeft; - m_Origin.uTrigger_R = PadStatus.triggerRight; - } - m_LastButtonCombo = COMBO_NONE; - } - } - - return true; -} - - -// SendCommand void CSIDevice_GCSteeringWheel::SendCommand(u32 _Cmd, u8 _Poll) { UCommand command(_Cmd); - switch (command.Command) + if (command.Command == CMD_FORCE) { - // Costis sent it in some demos :) - case 0x00: - break; + unsigned int uStrength = command.Parameter1; // 0 = left strong, 127 = left weak, 128 = right weak, 255 = right strong + unsigned int uType = command.Parameter2; // 06 = motor on, 04 = motor off - case CMD_FORCE: + // get the correct pad number that should rumble locally when using netplay + const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); + + if (numPAD < 4) { - unsigned int uStrength = command.Parameter1; // 0 = left strong, 127 = left weak, 128 = right weak, 255 = right strong - unsigned int uType = command.Parameter2; // 06 = motor on, 04 = motor off - - // get the correct pad number that should rumble locally when using netplay - const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); - - if (numPAD < 4) - Pad::Motor(numPAD, uType, uStrength); - - if (!_Poll) + if (uType == 0x06) { - m_Mode = command.Parameter2; - INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode); + // map 0..255 to -1.0..1.0 + ControlState strength = uStrength / 127.5 - 1; + Pad::Rumble(numPAD, strength); + } + else + { + Pad::Rumble(numPAD, 0); } } - break; - case CMD_WRITE: + if (!_Poll) { - unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard - unsigned int uStrength = command.Parameter2; - - // get the correct pad number that should rumble locally when using netplay - const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); - - if (numPAD < 4) - Pad::Rumble(numPAD, uType, uStrength); - - if (!_Poll) - { - m_Mode = command.Parameter2; - INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode); - } + m_Mode = command.Parameter2; + INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode); } - break; - - default: - { - ERROR_LOG(SERIALINTERFACE, "Unknown direct command (0x%x)", _Cmd); - } - break; + } + else + { + return CSIDevice_GCController::SendCommand(_Cmd, _Poll); } } - -// Savestate support -void CSIDevice_GCSteeringWheel::DoState(PointerWrap& p) -{ - p.Do(m_Origin); - p.Do(m_Mode); - p.Do(m_TButtonComboStart); - p.Do(m_TButtonCombo); - p.Do(m_LastButtonCombo); -} diff --git a/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.h b/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.h index 6e231436f8..b5853713fa 100644 --- a/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.h +++ b/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.h @@ -4,14 +4,11 @@ #pragma once -#include "Core/HW/SI_Device.h" -#include "InputCommon/GCPadStatus.h" +#include "Core/HW/SI_DeviceGCController.h" -// standard GameCube controller -class CSIDevice_GCSteeringWheel : public ISIDevice +class CSIDevice_GCSteeringWheel : public CSIDevice_GCController { private: - // Commands enum EBufferCommands { @@ -21,82 +18,13 @@ private: CMD_MOTOR_OFF = 0xff, }; - struct SOrigin - { - u8 uCommand;// Maybe should be button bits? - u8 unk_1; // ..and this would be the other half - u8 uOriginStickX; - u8 uOriginStickY; - u8 uSubStickStickX; - u8 uSubStickStickY; - u8 uTrigger_L; - u8 uTrigger_R; - u8 unk_4; - u8 unk_5; - u8 unk_6; - u8 unk_7; - }; - enum EDirectCommands { CMD_FORCE = 0x30, CMD_WRITE = 0x40 }; - union UCommand - { - u32 Hex; - struct - { - u32 Parameter1 : 8; - u32 Parameter2 : 8; - u32 Command : 8; - u32 : 8; - }; - UCommand() {Hex = 0;} - UCommand(u32 _iValue) {Hex = _iValue;} - }; - - enum EButtonCombo - { - COMBO_NONE = 0, - COMBO_ORIGIN, - COMBO_RESET - }; - - // struct to compare input against - // Set on connection and (standard pad only) on button combo - SOrigin m_Origin; - - // PADAnalogMode - u8 m_Mode; - - // Timer to track special button combos: - // y, X, start for 3 seconds updates origin with current status - // Technically, the above is only on standard pad, wavebird does not support it for example - // b, x, start for 3 seconds triggers reset (PI reset button interrupt) - u64 m_TButtonComboStart, m_TButtonCombo; - // Type of button combo from the last/current poll - EButtonCombo m_LastButtonCombo; - public: - - // Constructor CSIDevice_GCSteeringWheel(SIDevices device, int _iDeviceNumber); - - // Run the SI Buffer - virtual int RunBuffer(u8* _pBuffer, int _iLength) override; - - // Send and Receive pad input from network - static bool NetPlay_GetInput(u8 numPAD, GCPadStatus* status); - static u8 NetPlay_InGamePadToLocalPad(u8 numPAD); - - // Return true on new data - virtual bool GetData(u32& _Hi, u32& _Low) override; - - // Send a command directly - virtual void SendCommand(u32 _Cmd, u8 _Poll) override; - - // Savestate support - virtual void DoState(PointerWrap& p) override; + virtual void SendCommand(u32 _Cmd, u8 _Poll); }; diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index 3f79f2e39a..c907d3f1a1 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -61,6 +61,8 @@ IPC_HLE_PERIOD: For the Wiimote this is the call schedule: #include "Core/IPC_HLE/WII_IPC_HLE.h" #include "Core/PowerPC/PowerPC.h" +#include "InputCommon/ControllerInterface/ControllerInterface.h" + #include "VideoCommon/CommandProcessor.h" #include "VideoCommon/VideoBackendBase.h" @@ -79,6 +81,7 @@ static int et_DSP; static int et_IPC_HLE; static int et_PatchEngine; // PatchEngine updates every 1/60th of a second by default static int et_Throttle; +static int et_UpdateInput; // These are badly educated guesses // Feel free to experiment. Set these in Init below. @@ -132,6 +135,14 @@ static void VICallback(u64 userdata, int cyclesLate) CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine() - cyclesLate, et_VI); } +static void UpdateInputCallback(u64 userdata, int cyclesLate) +{ + g_controller_interface.UpdateInput(); + + // Poll system input every 1/60th of a second. + CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond() / 60 - cyclesLate, et_UpdateInput); +} + static void SICallback(u64 userdata, int cyclesLate) { SerialInterface::UpdateDevices(); @@ -258,6 +269,7 @@ void Init() et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback); et_PatchEngine = CoreTiming::RegisterEvent("PatchEngine", PatchEngineCallback); et_Throttle = CoreTiming::RegisterEvent("Throttle", ThrottleCallback); + et_UpdateInput = CoreTiming::RegisterEvent("UpdateInput", UpdateInputCallback); CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine(), et_VI); CoreTiming::ScheduleEvent(0, et_DSP); @@ -271,6 +283,8 @@ void Init() if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) CoreTiming::ScheduleEvent(IPC_HLE_PERIOD, et_IPC_HLE); + + CoreTiming::ScheduleEvent(0, et_UpdateInput); } void Shutdown() diff --git a/Source/Core/Core/HW/Wiimote.cpp b/Source/Core/Core/HW/Wiimote.cpp index 0f1870aad9..14ab7dfeb1 100644 --- a/Source/Core/Core/HW/Wiimote.cpp +++ b/Source/Core/Core/HW/Wiimote.cpp @@ -17,7 +17,6 @@ namespace Wiimote { static InputConfig s_config(WIIMOTE_INI_NAME, _trans("Wiimote"), "Wiimote"); -static int s_last_number = 4; InputConfig* GetConfig() { @@ -115,13 +114,6 @@ void Update(int _number) // TODO: change this to a try_to_lock, and make it give empty input on failure std::lock_guard lk(s_config.controls_lock); - if (_number <= s_last_number) - { - g_controller_interface.UpdateOutput(); - g_controller_interface.UpdateInput(); - } - s_last_number = _number; - if (WIIMOTE_SRC_EMU & g_wiimote_sources[_number]) ((WiimoteEmu::Wiimote*)s_config.controllers[_number])->Update(); else @@ -154,7 +146,6 @@ void DoState(u8 **ptr, PointerWrap::Mode mode) // TODO: PointerWrap p(ptr, mode); - p.Do(s_last_number); for (unsigned int i=0; iDoState(p); } diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index 1f664f0ccd..bcabce5742 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -835,16 +835,6 @@ bool WiimoteEmu::Wiimote::NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size) return false; } -bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, GCPadStatus* PadStatus) -{ - return false; -} - -bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, GCPadStatus* PadStatus) -{ - return false; -} - // called from ---CPU--- thread // so all players' games get the same time u32 CEXIIPL::NetPlay_GetGCTime() @@ -869,16 +859,6 @@ u8 CSIDevice_GCController::NetPlay_InGamePadToLocalPad(u8 numPAD) return numPAD; } -u8 CSIDevice_GCSteeringWheel::NetPlay_InGamePadToLocalPad(u8 numPAD) -{ - return CSIDevice_GCController::NetPlay_InGamePadToLocalPad(numPAD); -} - -u8 CSIDevice_DanceMat::NetPlay_InGamePadToLocalPad(u8 numPAD) -{ - return CSIDevice_GCController::NetPlay_InGamePadToLocalPad(numPAD); -} - bool NetPlay::IsNetPlayRunning() { return netplay_client != nullptr; diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.h b/Source/Core/InputCommon/ControllerInterface/Android/Android.h index 309f42e604..5d6767aa03 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.h +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.h @@ -39,9 +39,6 @@ private: }; public: - bool UpdateInput() { return true; } - bool UpdateOutput() { return true; } - Touchscreen(int padID); ~Touchscreen() {} diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index e75df76a36..3eb1b95ff2 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -98,9 +98,6 @@ void ControllerInterface::Shutdown() for (ciface::Core::Device::Output* o : d->Outputs()) o->SetState(0); - // Update output - d->UpdateOutput(); - // Delete device delete d; } @@ -135,52 +132,15 @@ void ControllerInterface::Shutdown() // // Update input for all devices, return true if all devices returned successful // -bool ControllerInterface::UpdateInput(const bool force) +void ControllerInterface::UpdateInput() { std::unique_lock lk(update_lock, std::defer_lock); - if (force) - lk.lock(); - else if (!lk.try_lock()) - return false; - - size_t ok_count = 0; + if (!lk.try_lock()) + return; for (ciface::Core::Device* d : m_devices) - { - if (d->UpdateInput()) - ++ok_count; - //else - // disabled. it might be causing problems - //(*d)->ClearInputState(); - } - - return (m_devices.size() == ok_count); -} - -// -// UpdateOutput -// -// Update output for all devices, return true if all devices returned successful -// -bool ControllerInterface::UpdateOutput(const bool force) -{ - std::unique_lock lk(update_lock, std::defer_lock); - - if (force) - lk.lock(); - else if (!lk.try_lock()) - return false; - - size_t ok_count = 0; - - for (ciface::Core::Device* d : m_devices) - { - if (d->UpdateOutput()) - ++ok_count; - } - - return (m_devices.size() == ok_count); + d->UpdateInput(); } // @@ -299,14 +259,9 @@ ciface::Core::Device::Control* ControllerInterface::OutputReference::Detect(cons // this loop is to make stuff like flashing keyboard LEDs work while (ms > (slept += 10)) - { - // TODO: improve this to update more than just the default device's output - device->UpdateOutput(); Common::SleepCurrentThread(10); - } State(0); - device->UpdateOutput(); } return nullptr; } diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h index 2420b65ed7..9ab8427ad2 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h @@ -120,8 +120,7 @@ public: bool IsInit() const { return m_is_init; } void UpdateReference(ControlReference* control, const ciface::Core::DeviceQualifier& default_device) const; - bool UpdateInput(const bool force = false); - bool UpdateOutput(const bool force = false); + void UpdateInput(); std::recursive_mutex update_lock; diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp index ecd5db838c..bc8638293e 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp @@ -149,7 +149,9 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI InitForceFeedback(m_device, (int)objects.size()); } - ClearInputState(); + ZeroMemory(&m_state_in, sizeof(m_state_in)); + // set hats to center + memset(m_state_in.rgdwPOV, 0xFF, sizeof(m_state_in.rgdwPOV)); } Joystick::~Joystick() @@ -158,13 +160,6 @@ Joystick::~Joystick() m_device->Release(); } -void Joystick::ClearInputState() -{ - ZeroMemory(&m_state_in, sizeof(m_state_in)); - // set hats to center - memset(m_state_in.rgdwPOV, 0xFF, sizeof(m_state_in.rgdwPOV)); -} - std::string Joystick::GetName() const { return GetDeviceName(m_device); @@ -182,7 +177,7 @@ std::string Joystick::GetSource() const // update IO -bool Joystick::UpdateInput() +void Joystick::UpdateInput() { HRESULT hr = 0; @@ -220,9 +215,7 @@ bool Joystick::UpdateInput() // try reacquire if input lost if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr) - hr = m_device->Acquire(); - - return SUCCEEDED(hr); + m_device->Acquire(); } // get name diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h index 0ac535cdfe..f1af8102cd 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h @@ -52,9 +52,7 @@ private: }; public: - bool UpdateInput(); - - void ClearInputState(); + void UpdateInput() override; Joystick(const LPDIRECTINPUTDEVICE8 device, const unsigned int index); ~Joystick(); diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index 05f28c79ae..c96e51a830 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -30,17 +30,6 @@ static const struct #include "InputCommon/ControllerInterface/DInput/NamedKeys.h" // NOLINT }; -static const struct -{ - const BYTE code; - const char* const name; -} named_lights[] = -{ - { VK_NUMLOCK, "NUM LOCK" }, - { VK_CAPITAL, "CAPS LOCK" }, - { VK_SCROLL, "SCROLL LOCK" } -}; - // lil silly static HWND hwnd; @@ -102,16 +91,11 @@ KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, const LPDIREC m_last_update = GetTickCount(); ZeroMemory(&m_state_in, sizeof(m_state_in)); - ZeroMemory(m_state_out, sizeof(m_state_out)); - ZeroMemory(&m_current_state_out, sizeof(m_current_state_out)); // KEYBOARD // add keys for (u8 i = 0; i < sizeof(named_keys)/sizeof(*named_keys); ++i) AddInput(new Key(i, m_state_in.keyboard[named_keys[i].code])); - // add lights - for (u8 i = 0; i < sizeof(named_lights)/sizeof(*named_lights); ++i) - AddOutput(new Light(i)); // MOUSE // get caps @@ -155,7 +139,7 @@ void GetMousePos(ControlState* const x, ControlState* const y) *y = (ControlState)point.y / (ControlState)win_height * 2 - 1; } -bool KeyboardMouse::UpdateInput() +void KeyboardMouse::UpdateInput() { DIMOUSESTATE2 tmp_mouse; @@ -191,50 +175,7 @@ bool KeyboardMouse::UpdateInput() // update mouse cursor GetMousePos(&m_state_in.cursor.x, &m_state_in.cursor.y); - - return true; } - - return false; -} - -bool KeyboardMouse::UpdateOutput() -{ - class KInput : public INPUT - { - public: - KInput( const unsigned char key, const bool up = false ) - { - memset( this, 0, sizeof(*this) ); - type = INPUT_KEYBOARD; - ki.wVk = key; - - if (up) - ki.dwFlags = KEYEVENTF_KEYUP; - } - }; - - std::vector< KInput > kbinputs; - for (unsigned int i = 0; i < sizeof(m_state_out)/sizeof(*m_state_out); ++i) - { - bool want_on = false; - if (m_state_out[i]) - want_on = m_state_out[i] > GetTickCount() % 255 ; // light should flash when output is 0.5 - - // lights are set to their original state when output is zero - if (want_on ^ m_current_state_out[i]) - { - kbinputs.push_back(KInput(named_lights[i].code)); // press - kbinputs.push_back(KInput(named_lights[i].code, true)); // release - - m_current_state_out[i] ^= 1; - } - } - - if (kbinputs.size()) - return ( kbinputs.size() == SendInput( (UINT)kbinputs.size(), &kbinputs[0], sizeof( kbinputs[0] ) ) ); - else - return true; } std::string KeyboardMouse::GetName() const @@ -280,11 +221,6 @@ std::string KeyboardMouse::Cursor::GetName() const return tmpstr; } -std::string KeyboardMouse::Light::GetName() const -{ - return named_lights[m_index].name; -} - // get/set state ControlState KeyboardMouse::Key::GetState() const { @@ -306,10 +242,5 @@ ControlState KeyboardMouse::Cursor::GetState() const return std::max(0.0, ControlState(m_axis) / (m_positive ? 1.0 : -1.0)); } -void KeyboardMouse::Light::SetState(const ControlState state) -{ - //state_out[m_index] = (unsigned char)(state * 255); -} - } } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h index f4ad99db2d..704635057e 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h @@ -76,19 +76,8 @@ private: const bool m_positive; }; - class Light : public Output - { - public: - std::string GetName() const; - Light(u8 index) : m_index(index) {} - void SetState(ControlState state); - private: - const u8 m_index; - }; - public: - bool UpdateInput(); - bool UpdateOutput(); + void UpdateInput() override; KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRECTINPUTDEVICE8 mo_device); ~KeyboardMouse(); @@ -103,8 +92,6 @@ private: DWORD m_last_update; State m_state_in; - unsigned char m_state_out[3]; // NUM CAPS SCROLL - bool m_current_state_out[3]; // NUM CAPS SCROLL }; } diff --git a/Source/Core/InputCommon/ControllerInterface/Device.cpp b/Source/Core/InputCommon/ControllerInterface/Device.cpp index 84af8649a8..f96c637426 100644 --- a/Source/Core/InputCommon/ControllerInterface/Device.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Device.cpp @@ -66,20 +66,6 @@ Device::Output* Device::FindOutput(const std::string &name) const return nullptr; } -// -// Device :: ClearInputState -// -// Device classes should override this function -// ControllerInterface will call this when the device returns failure during UpdateInput -// used to try to set all buttons and axes to their default state when user unplugs a gamepad during play -// buttons/axes that were held down at the time of unplugging should be seen as not pressed after unplugging -// -void Device::ClearInputState() -{ - // this is going to be called for every UpdateInput call that fails - // kinda slow but, w/e, should only happen when user unplugs a device while playing -} - bool Device::Control::InputGateOn() { if (SConfig::GetInstance().m_BackgroundInput) diff --git a/Source/Core/InputCommon/ControllerInterface/Device.h b/Source/Core/InputCommon/ControllerInterface/Device.h index c23c0d29bf..fa536e4116 100644 --- a/Source/Core/InputCommon/ControllerInterface/Device.h +++ b/Source/Core/InputCommon/ControllerInterface/Device.h @@ -100,10 +100,7 @@ public: virtual std::string GetName() const = 0; virtual int GetId() const = 0; virtual std::string GetSource() const = 0; - virtual bool UpdateInput() = 0; - virtual bool UpdateOutput() = 0; - - virtual void ClearInputState(); + virtual void UpdateInput() {} const std::vector& Inputs() const { return m_inputs; } const std::vector& Outputs() const { return m_outputs; } diff --git a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp index 4350444492..c6b1974a89 100644 --- a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp @@ -38,17 +38,6 @@ static const ForceType force_type_names[] = //{GUID_Friction, "Friction"}, }; -ForceFeedbackDevice::~ForceFeedbackDevice() -{ - // release the ff effect iface's - for (EffectState& state : m_state_out) - { - state.iface->Stop(); - state.iface->Unload(); - state.iface->Release(); - } -} - bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, int cAxes) { if (cAxes == 0) @@ -107,14 +96,12 @@ bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, i LPDIRECTINPUTEFFECT pEffect; if (SUCCEEDED(device->CreateEffect(f.guid, &eff, &pEffect, nullptr))) { - m_state_out.push_back(EffectState(pEffect)); - if (f.guid == GUID_ConstantForce) - AddOutput(new ForceConstant(f.name, m_state_out.back())); + AddOutput(new ForceConstant(f.name, pEffect)); else if (f.guid == GUID_RampForce) - AddOutput(new ForceRamp(f.name, m_state_out.back())); + AddOutput(new ForceRamp(f.name, pEffect)); else - AddOutput(new ForcePeriodic(f.name, m_state_out.back())); + AddOutput(new ForcePeriodic(f.name, pEffect)); } } @@ -133,40 +120,32 @@ bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, i return true; } -bool ForceFeedbackDevice::UpdateOutput() +template +ForceFeedbackDevice::Force

::~Force() { - size_t ok_count = 0; + m_iface->Stop(); + m_iface->Unload(); + m_iface->Release(); +} - DIEFFECT eff; - memset(&eff, 0, sizeof(eff)); +template +void ForceFeedbackDevice::Force

::Update() +{ + DIEFFECT eff = {}; eff.dwSize = sizeof(DIEFFECT); eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; - for (EffectState& state : m_state_out) - { - if (state.params) - { - if (state.size) - { - eff.cbTypeSpecificParams = state.size; - eff.lpvTypeSpecificParams = state.params; - // set params and start effect - ok_count += SUCCEEDED(state.iface->SetParameters(&eff, DIEP_TYPESPECIFICPARAMS | DIEP_START)); - } - else - { - ok_count += SUCCEEDED(state.iface->Stop()); - } + eff.cbTypeSpecificParams = sizeof(P); + eff.lpvTypeSpecificParams = ¶ms; - state.params = nullptr; - } - else - { - ++ok_count; - } - } + // set params and start effect + m_iface->SetParameters(&eff, DIEP_TYPESPECIFICPARAMS | DIEP_START); +} - return (m_state_out.size() == ok_count); +template +void ForceFeedbackDevice::Force

::Stop() +{ + m_iface->Stop(); } template<> @@ -174,15 +153,14 @@ void ForceFeedbackDevice::ForceConstant::SetState(const ControlState state) { const LONG new_val = LONG(10000 * state); - LONG &val = params.lMagnitude; - if (val != new_val) - { - val = new_val; - m_state.params = ¶ms; // tells UpdateOutput the state has changed + if (params.lMagnitude == new_val) + return; - // tells UpdateOutput to either start or stop the force - m_state.size = new_val ? sizeof(params) : 0; - } + params.lMagnitude = new_val; + if (new_val) + Update(); + else + Stop(); } template<> @@ -190,14 +168,14 @@ void ForceFeedbackDevice::ForceRamp::SetState(const ControlState state) { const LONG new_val = LONG(10000 * state); - if (params.lStart != new_val) - { - params.lStart = params.lEnd = new_val; - m_state.params = ¶ms; // tells UpdateOutput the state has changed + if (params.lStart == new_val) + return; - // tells UpdateOutput to either start or stop the force - m_state.size = new_val ? sizeof(params) : 0; - } + params.lStart = params.lEnd = new_val; + if (new_val) + Update(); + else + Stop(); } template<> @@ -205,22 +183,19 @@ void ForceFeedbackDevice::ForcePeriodic::SetState(const ControlState state) { const DWORD new_val = DWORD(10000 * state); - DWORD &val = params.dwMagnitude; - if (val != new_val) - { - val = new_val; - //params.dwPeriod = 0;//DWORD(0.05 * DI_SECONDS); // zero is working fine for me + if (params.dwMagnitude == new_val) + return; - m_state.params = ¶ms; // tells UpdateOutput the state has changed - - // tells UpdateOutput to either start or stop the force - m_state.size = new_val ? sizeof(params) : 0; - } + params.dwMagnitude = new_val; + if (new_val) + Update(); + else + Stop(); } template -ForceFeedbackDevice::Force

::Force(const std::string& name, EffectState& state) -: m_name(name), m_state(state) +ForceFeedbackDevice::Force

::Force(const std::string& name, LPDIRECTINPUTEFFECT iface) +: m_name(name), m_iface(iface) { memset(¶ms, 0, sizeof(params)); } diff --git a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h index 31a1884aae..c42f0d41f7 100644 --- a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h +++ b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h @@ -25,25 +25,19 @@ namespace ForceFeedback class ForceFeedbackDevice : public Core::Device { private: - struct EffectState - { - EffectState(LPDIRECTINPUTEFFECT eff) : iface(eff), params(nullptr), size(0) {} - - LPDIRECTINPUTEFFECT iface; - void* params; // null when force hasn't changed - u8 size; // zero when force should stop - }; - template class Force : public Output { public: std::string GetName() const; - Force(const std::string& name, EffectState& state); + Force(const std::string& name, LPDIRECTINPUTEFFECT iface); + ~Force(); void SetState(ControlState state); + void Update(); + void Stop(); private: const std::string m_name; - EffectState& m_state; + LPDIRECTINPUTEFFECT m_iface; P params; }; typedef Force ForceConstant; @@ -52,11 +46,6 @@ private: public: bool InitForceFeedback(const LPDIRECTINPUTDEVICE8, int cAxes); - bool UpdateOutput(); - - virtual ~ForceFeedbackDevice(); -private: - std::list m_state_out; }; diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h index ffbe475840..728d55dde8 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h @@ -72,8 +72,6 @@ private: }; public: - bool UpdateInput(); - Joystick(IOHIDDeviceRef device, std::string name, int index); ~Joystick(); diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm index 93dea13c28..bdba40c410 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm @@ -90,11 +90,6 @@ Joystick::~Joystick() m_ff_device->Release(); } -bool Joystick::UpdateInput() -{ - return true; -} - std::string Joystick::GetName() const { return m_device_name; diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h index 36705075ee..06e686fc6a 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h @@ -53,8 +53,7 @@ private: }; public: - bool UpdateInput(); - bool UpdateOutput(); + void UpdateInput() override; Keyboard(IOHIDDeviceRef device, std::string name, int index, void *window); diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm index 1294346e1b..0e876f4173 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm @@ -54,7 +54,7 @@ Keyboard::Keyboard(IOHIDDeviceRef device, std::string name, int index, void *win AddInput(new Button(i, m_mousebuttons[i])); } -bool Keyboard::UpdateInput() +void Keyboard::UpdateInput() { CGRect bounds = CGRectZero; uint32_t windowid[1] = { m_windowid }; @@ -85,13 +85,6 @@ bool Keyboard::UpdateInput() m_mousebuttons[0] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonLeft); m_mousebuttons[1] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonRight); m_mousebuttons[2] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonCenter); - - return true; -} - -bool Keyboard::UpdateOutput() -{ - return true; } std::string Keyboard::GetName() const diff --git a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp index b745f7b2d4..a46a08100d 100644 --- a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp +++ b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp @@ -121,40 +121,26 @@ Joystick::Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsi // constant effect if (supported_effects & SDL_HAPTIC_CONSTANT) - { - m_state_out.push_back(EffectIDState()); - AddOutput(new ConstantEffect(m_state_out.back())); - } + AddOutput(new ConstantEffect(m_haptic)); // ramp effect if (supported_effects & SDL_HAPTIC_RAMP) - { - m_state_out.push_back(EffectIDState()); - AddOutput(new RampEffect(m_state_out.back())); - } + AddOutput(new RampEffect(m_haptic)); // sine effect if (supported_effects & SDL_HAPTIC_SINE) - { - m_state_out.push_back(EffectIDState()); - AddOutput(new SineEffect(m_state_out.back())); - } + AddOutput(new SineEffect(m_haptic)); #ifdef SDL_HAPTIC_SQUARE // square effect if (supported_effects & SDL_HAPTIC_SQUARE) - { - m_state_out.push_back(EffectIDState()); - AddOutput(new SquareEffect(m_state_out.back())); - } + AddOutput(new SquareEffect(m_haptic)); + #endif // defined(SDL_HAPTIC_SQUARE) // triangle effect if (supported_effects & SDL_HAPTIC_TRIANGLE) - { - m_state_out.push_back(EffectIDState()); - AddOutput(new TriangleEffect(m_state_out.back())); - } + AddOutput(new TriangleEffect(m_haptic)); } #endif @@ -167,13 +153,6 @@ Joystick::~Joystick() { // stop/destroy all effects SDL_HapticStopAll(m_haptic); - for (auto &i : m_state_out) - { - if (i.id != -1) - { - SDL_HapticDestroyEffect(m_haptic, i.id); - } - } // close haptic first SDL_HapticClose(m_haptic); } @@ -184,6 +163,26 @@ Joystick::~Joystick() } #ifdef USE_SDL_HAPTIC +void Joystick::HapticEffect::Update() +{ + if (m_id == -1 && m_effect.type > 0) + { + m_id = SDL_HapticNewEffect(m_haptic, &m_effect); + if (m_id > -1) + SDL_HapticRunEffect(m_haptic, m_id, 1); + } + else if (m_id > -1 && m_effect.type == 0) + { + SDL_HapticStopEffect(m_haptic, m_id); + SDL_HapticDestroyEffect(m_haptic, m_id); + m_id = -1; + } + else if (m_id > -1) + { + SDL_HapticUpdateEffect(m_haptic, m_id, &m_effect); + } +} + std::string Joystick::ConstantEffect::GetName() const { return "Constant"; @@ -215,58 +214,51 @@ void Joystick::ConstantEffect::SetState(ControlState state) { if (state) { - m_effect.effect.type = SDL_HAPTIC_CONSTANT; - m_effect.effect.constant.length = SDL_HAPTIC_INFINITY; + m_effect.type = SDL_HAPTIC_CONSTANT; + m_effect.constant.length = SDL_HAPTIC_INFINITY; } else { - m_effect.effect.type = 0; + m_effect.type = 0; } - const Sint16 old = m_effect.effect.constant.level; - m_effect.effect.constant.level = (Sint16)(state * 0x7FFF); - if (old != m_effect.effect.constant.level) - m_effect.changed = true; + m_effect.constant.level = (Sint16)(state * 0x7FFF); + Update(); } void Joystick::RampEffect::SetState(ControlState state) { if (state) { - m_effect.effect.type = SDL_HAPTIC_RAMP; - m_effect.effect.ramp.length = SDL_HAPTIC_INFINITY; + m_effect.type = SDL_HAPTIC_RAMP; + m_effect.ramp.length = SDL_HAPTIC_INFINITY; } else { - m_effect.effect.type = 0; + m_effect.type = 0; } - const Sint16 old = m_effect.effect.ramp.start; - m_effect.effect.ramp.start = (Sint16)(state * 0x7FFF); - if (old != m_effect.effect.ramp.start) - m_effect.changed = true; + m_effect.ramp.start = (Sint16)(state * 0x7FFF); + Update(); } void Joystick::SineEffect::SetState(ControlState state) { if (state) { - m_effect.effect.type = SDL_HAPTIC_SINE; - m_effect.effect.periodic.length = 250; + m_effect.type = SDL_HAPTIC_SINE; + m_effect.periodic.length = 250; } else { - m_effect.effect.type = 0; + m_effect.type = 0; } - const Sint16 old = m_effect.effect.periodic.magnitude; - m_effect.effect.periodic.period = 5; - m_effect.effect.periodic.magnitude = (Sint16)(state * 0x5000); - m_effect.effect.periodic.attack_length = 0; - m_effect.effect.periodic.fade_length = 500; - - if (old != m_effect.effect.periodic.magnitude) - m_effect.changed = true; + m_effect.periodic.period = 5; + m_effect.periodic.magnitude = (Sint16)(state * 0x5000); + m_effect.periodic.attack_length = 0; + m_effect.periodic.fade_length = 500; + Update(); } #ifdef SDL_HAPTIC_SQUARE @@ -274,22 +266,19 @@ void Joystick::SquareEffect::SetState(ControlState state) { if (state) { - m_effect.effect.type = SDL_HAPTIC_SQUARE; - m_effect.effect.periodic.length = 250; + m_effect.type = SDL_HAPTIC_SQUARE; + m_effect.periodic.length = 250; } else { - m_effect.effect.type = 0; + m_effect.type = 0; } - const Sint16 old = m_effect.effect.periodic.magnitude; - m_effect.effect.periodic.period = 5; - m_effect.effect.periodic.magnitude = state * 0x5000; - m_effect.effect.periodic.attack_length = 0; - m_effect.effect.periodic.fade_length = 100; - - if (old != m_effect.effect.periodic.magnitude) - m_effect.changed = true; + m_effect.periodic.period = 5; + m_effect.periodic.magnitude = state * 0x5000; + m_effect.periodic.attack_length = 0; + m_effect.periodic.fade_length = 100; + Update(); } #endif // defined(SDL_HAPTIC_SQUARE) @@ -297,69 +286,26 @@ void Joystick::TriangleEffect::SetState(ControlState state) { if (state) { - m_effect.effect.type = SDL_HAPTIC_TRIANGLE; - m_effect.effect.periodic.length = 250; + m_effect.type = SDL_HAPTIC_TRIANGLE; + m_effect.periodic.length = 250; } else { - m_effect.effect.type = 0; + m_effect.type = 0; } - const Sint16 old = m_effect.effect.periodic.magnitude; - m_effect.effect.periodic.period = 5; - m_effect.effect.periodic.magnitude = (Sint16)(state * 0x5000); - m_effect.effect.periodic.attack_length = 0; - m_effect.effect.periodic.fade_length = 100; - - if (old != m_effect.effect.periodic.magnitude) - m_effect.changed = true; + m_effect.periodic.period = 5; + m_effect.periodic.magnitude = (Sint16)(state * 0x5000); + m_effect.periodic.attack_length = 0; + m_effect.periodic.fade_length = 100; + Update(); } #endif -bool Joystick::UpdateInput() +void Joystick::UpdateInput() { // each joystick is doin this, o well SDL_JoystickUpdate(); - - return true; -} - -bool Joystick::UpdateOutput() -{ -#ifdef USE_SDL_HAPTIC - for (auto &i : m_state_out) - { - if (i.changed) // if SetState was called on this output - { - if (-1 == i.id) // effect isn't currently uploaded - { - if (i.effect.type) // if outputstate is >0 this would be true - { - if ((i.id = SDL_HapticNewEffect(m_haptic, &i.effect)) > -1) // upload the effect - { - SDL_HapticRunEffect(m_haptic, i.id, 1); // run the effect - } - } - } - else // effect is already uploaded - { - if (i.effect.type) // if ouputstate >0 - { - SDL_HapticUpdateEffect(m_haptic, i.id, &i.effect); // update the effect - } - else - { - SDL_HapticStopEffect(m_haptic, i.id); // else, stop and remove the effect - SDL_HapticDestroyEffect(m_haptic, i.id); - i.id = -1; // mark it as not uploaded - } - } - - i.changed = false; - } - } -#endif - return true; } std::string Joystick::GetName() const diff --git a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h index 76fc028ec9..dc4c52063f 100644 --- a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h +++ b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h @@ -33,17 +33,6 @@ class Joystick : public Core::Device { private: -#ifdef USE_SDL_HAPTIC - struct EffectIDState - { - EffectIDState() : effect(SDL_HapticEffect()), id(-1), changed(false) {} - - SDL_HapticEffect effect; - int id; - bool changed; - }; -#endif - class Button : public Core::Device::Input { public: @@ -80,62 +69,65 @@ private: }; #ifdef USE_SDL_HAPTIC - class ConstantEffect : public Output + class HapticEffect : public Output { public: - std::string GetName() const override; - ConstantEffect(EffectIDState& effect) : m_effect(effect) {} - void SetState(ControlState state) override; - private: - EffectIDState& m_effect; + HapticEffect(SDL_Haptic* haptic) : m_haptic(haptic), m_id(-1) {} + ~HapticEffect() { m_effect.type = 0; Update(); } + + protected: + void Update(); + + SDL_HapticEffect m_effect; + SDL_Haptic* m_haptic; + int m_id; }; - class RampEffect : public Output + class ConstantEffect : public HapticEffect { public: + ConstantEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} std::string GetName() const override; - RampEffect(EffectIDState& effect) : m_effect(effect) {} void SetState(ControlState state) override; - private: - EffectIDState& m_effect; }; - class SineEffect : public Output + class RampEffect : public HapticEffect { public: + RampEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} + std::string GetName() const override; + void SetState(ControlState state) override; + }; + + class SineEffect : public HapticEffect + { + public: + SineEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} std::string GetName() const override; - SineEffect(EffectIDState& effect) : m_effect(effect) {} void SetState(ControlState state) override; - private: - EffectIDState& m_effect; }; #ifdef SDL_HAPTIC_SQUARE - class SquareEffect : public Output + class SquareEffect : public HapticEffect { public: + SquareEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} std::string GetName() const; - SquareEffect(EffectIDState& effect) : m_effect(effect) {} void SetState(ControlState state); - private: - EffectIDState& m_effect; }; #endif // defined(SDL_HAPTIC_SQUARE) - class TriangleEffect : public Output + class TriangleEffect : public HapticEffect { public: + TriangleEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} std::string GetName() const override; - TriangleEffect(EffectIDState& effect) : m_effect(effect) {} void SetState(ControlState state) override; - private: - EffectIDState& m_effect; }; #endif public: - bool UpdateInput() override; - bool UpdateOutput() override; + void UpdateInput() override; Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsigned int index); ~Joystick(); @@ -150,7 +142,6 @@ private: const unsigned int m_index; #ifdef USE_SDL_HAPTIC - std::list m_state_out; SDL_Haptic* m_haptic; #endif }; diff --git a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp index 37949e03ac..2bf98bb0b3 100644 --- a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp +++ b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp @@ -121,7 +121,6 @@ Device::Device(const XINPUT_CAPABILITIES& caps, u8 index) : m_index(index), m_subtype(caps.SubType) { ZeroMemory(&m_state_out, sizeof(m_state_out)); - ZeroMemory(&m_current_state_out, sizeof(m_current_state_out)); // XInputGetCaps seems to always claim all capabilities are supported // but I will leave all this stuff in, incase m$ fixes xinput up a bit @@ -162,14 +161,9 @@ Device::Device(const XINPUT_CAPABILITIES& caps, u8 index) { //WORD val = (&caps.Vibration.wLeftMotorSpeed)[i]; // should be max value / nope, more lies if ((&caps.Vibration.wLeftMotorSpeed)[i]) - AddOutput(new Motor(i, (&m_state_out.wLeftMotorSpeed)[i], 65535)); + AddOutput(new Motor(i, this, (&m_state_out.wLeftMotorSpeed)[i], 65535)); } - ClearInputState(); -} - -void Device::ClearInputState() -{ ZeroMemory(&m_state_in, sizeof(m_state_in)); } @@ -208,24 +202,14 @@ std::string Device::GetSource() const // Update I/O -bool Device::UpdateInput() +void Device::UpdateInput() { - return (ERROR_SUCCESS == PXInputGetState(m_index, &m_state_in)); + PXInputGetState(m_index, &m_state_in); } -bool Device::UpdateOutput() +void Device::UpdateMotors() { - // this if statement is to make rumble work better when multiple ControllerInterfaces are using the device - // only calls XInputSetState if the state changed - if (memcmp(&m_state_out, &m_current_state_out, sizeof(m_state_out))) - { - m_current_state_out = m_state_out; - return (ERROR_SUCCESS == PXInputSetState(m_index, &m_state_out)); - } - else - { - return true; - } + PXInputSetState(m_index, &m_state_out); } // GET name/source/id @@ -270,6 +254,7 @@ ControlState Device::Axis::GetState() const void Device::Motor::SetState(ControlState state) { m_motor = (WORD)(state * m_range); + m_parent->UpdateMotors(); } } diff --git a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h index 3c9eadc395..94c1549a53 100644 --- a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h +++ b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h @@ -64,19 +64,17 @@ private: { public: std::string GetName() const; - Motor(u8 index, WORD& motor, WORD range) : m_index(index), m_motor(motor), m_range(range) {} + Motor(u8 index, Device* parent, WORD &motor, WORD range) : m_index(index), m_parent(parent), m_motor(motor), m_range(range) {} void SetState(ControlState state); private: WORD& m_motor; const WORD m_range; const u8 m_index; + Device* m_parent; }; public: - bool UpdateInput(); - bool UpdateOutput(); - - void ClearInputState(); + void UpdateInput() override; Device(const XINPUT_CAPABILITIES& capabilities, u8 index); @@ -84,9 +82,11 @@ public: int GetId() const; std::string GetSource() const; + void UpdateMotors(); + private: XINPUT_STATE m_state_in; - XINPUT_VIBRATION m_state_out, m_current_state_out; + XINPUT_VIBRATION m_state_out; const BYTE m_subtype; const u8 m_index; }; diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index 13ace15997..1d7d080d7e 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -208,7 +208,7 @@ void KeyboardMouse::UpdateCursor() m_state.cursor.y = win_y / (float)win_attribs.height * 2 - 1; } -bool KeyboardMouse::UpdateInput() +void KeyboardMouse::UpdateInput() { XFlush(m_display); @@ -282,13 +282,6 @@ bool KeyboardMouse::UpdateInput() m_state.axis.y *= MOUSE_AXIS_SMOOTHING; m_state.axis.y += delta_y; m_state.axis.y /= MOUSE_AXIS_SMOOTHING+1.0f; - - return true; -} - -bool KeyboardMouse::UpdateOutput() -{ - return true; } std::string KeyboardMouse::GetName() const diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h index a75c74bba5..3f31aa50f2 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h @@ -98,8 +98,7 @@ private: void UpdateCursor(); public: - bool UpdateInput() override; - bool UpdateOutput() override; + void UpdateInput() override; KeyboardMouse(Window window, int opcode, int pointer_deviceid, int keyboard_deviceid); ~KeyboardMouse(); diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp index 973368a78e..9a700a9c99 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp @@ -49,7 +49,7 @@ KeyboardMouse::~KeyboardMouse() XCloseDisplay(m_display); } -bool KeyboardMouse::UpdateInput() +void KeyboardMouse::UpdateInput() { XQueryKeymap(m_display, m_state.keyboard); @@ -64,16 +64,8 @@ bool KeyboardMouse::UpdateInput() // the mouse position as a range from -1 to 1 m_state.cursor.x = (float)win_x / (float)win_attribs.width * 2 - 1; m_state.cursor.y = (float)win_y / (float)win_attribs.height * 2 - 1; - - return true; } -bool KeyboardMouse::UpdateOutput() -{ - return true; -} - - std::string KeyboardMouse::GetName() const { return "Keyboard Mouse"; diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.h b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.h index 237b3a484e..0c2f79c8b3 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.h +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.h @@ -70,8 +70,7 @@ private: }; public: - bool UpdateInput() override; - bool UpdateOutput() override; + void UpdateInput() override; KeyboardMouse(Window window); ~KeyboardMouse();