diff --git a/impls/Windows_Libs/Input/inc/INP_Main.h b/impls/Windows_Libs/Input/inc/INP_Main.h index 63d24b9..4394ac9 100644 --- a/impls/Windows_Libs/Input/inc/INP_Main.h +++ b/impls/Windows_Libs/Input/inc/INP_Main.h @@ -158,8 +158,23 @@ public: unsigned char m_ucMenuActionC; unsigned int **m_JoypadMap; - bool m_bJoypadMapArrayIsSetup; + + static const int MAX_SWAP_SLOTS = 2; + static const int MAX_SWAP_ENTRIES = 4; + struct SwapEntry + { + unsigned int btnFrom; + unsigned int btnTo; + }; + bool m_bSwapEnabled[MAX_JOYPADS][MAX_SWAP_SLOTS]; + int m_iSwapEntryCount[MAX_JOYPADS][MAX_SWAP_SLOTS]; + SwapEntry m_SwapTable[MAX_JOYPADS][MAX_SWAP_SLOTS][MAX_SWAP_ENTRIES]; + + void SetButtonSwapEnabled(int iPad, int iSlot, bool bEnabled); + void AddMapButtonSwap(int iPad, int iSlot, int iEntry, unsigned int uiBtnFrom, unsigned int uiBtnTo); + unsigned int ApplyButtonSwap(int iPad, unsigned int uiInput); + unsigned int m_uiSigninJoypadMask; bool m_bIsMenuDisplayed[MAX_JOYPADS]; @@ -180,4 +195,4 @@ public: }; // Singleton -extern CInput InternalInputManager; \ No newline at end of file +extern CInput InternalInputManager; diff --git a/impls/Windows_Libs/Input/src/4J_Input.cpp b/impls/Windows_Libs/Input/src/4J_Input.cpp index 8fec45d..bfb262d 100644 --- a/impls/Windows_Libs/Input/src/4J_Input.cpp +++ b/impls/Windows_Libs/Input/src/4J_Input.cpp @@ -174,4 +174,14 @@ void C_4JInput::CancelQueuedVerifyStrings(int (*Func)(LPVOID, STRING_VERIFY_RESP void C_4JInput::CancelAllVerifyInProgress(void) {} -// bool C_4JInput::InputDetected(DWORD dwUserIndex,WCHAR *pwchInput) {} \ No newline at end of file +void C_4JInput::SetButtonSwapEnabled(int iPad, int iSlot, bool bEnabled) +{ + InternalInputManager.SetButtonSwapEnabled(iPad, iSlot, bEnabled); +} + +void C_4JInput::AddMapButtonSwap(int iPad, int iSlot, int iEntry, unsigned int uiBtnFrom, unsigned int uiBtnTo) +{ + InternalInputManager.AddMapButtonSwap(iPad, iSlot, iEntry, uiBtnFrom, uiBtnTo); +} + +// bool C_4JInput::InputDetected(DWORD dwUserIndex,WCHAR *pwchInput) {} diff --git a/impls/Windows_Libs/Input/src/INP_Main.cpp b/impls/Windows_Libs/Input/src/INP_Main.cpp index 9953243..ae2d3a7 100644 --- a/impls/Windows_Libs/Input/src/INP_Main.cpp +++ b/impls/Windows_Libs/Input/src/INP_Main.cpp @@ -42,6 +42,10 @@ CInput::CInput() m_sDebugSequenceName = 0; m_uiDebugSequenceIndex = 0; m_pDebugSequenceFn = 0; + + ZeroMemory(m_bSwapEnabled, sizeof(m_bSwapEnabled)); + ZeroMemory(m_iSwapEntryCount, sizeof(m_iSwapEntryCount)); + ZeroMemory(m_SwapTable, sizeof(m_SwapTable)); } void CInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC) @@ -290,7 +294,8 @@ unsigned int CInput::GetGameJoypadMaps(unsigned char ucMap, unsigned char ucActi assert(ucMap < m_ucJoypadMapC); assert(ucAction < m_ucJoypadMapActionC); - return m_JoypadMap[ucMap][ucAction]; + unsigned int uiVal = m_JoypadMap[ucMap][ucAction]; + return ApplyButtonSwap(0, uiVal); } void CInput::SetJoypadMapVal(int iPad, unsigned char ucMap) @@ -384,7 +389,12 @@ unsigned int CInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat) } unsigned char ucMap = this->m_Joypads[iPad].m_ucMappingValue; - unsigned int uiVal = this->m_JoypadMap[ucMap][ucAction] & this->m_Joypads[iPad].m_uiButtons; + unsigned int uiMapping = this->m_JoypadMap[ucMap][ucAction]; + + if (ucAction > m_ucMenuActionC) + uiMapping = ApplyButtonSwap(iPad, uiMapping); + + unsigned int uiVal = uiMapping & this->m_Joypads[iPad].m_uiButtons; if (!uiVal || !bRepeat) { return uiVal; @@ -426,8 +436,12 @@ unsigned int CInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat) bool CInput::IsSet(int iPad, unsigned char ucAction) { - return (!m_bIsMenuDisplayed[iPad] || ucAction <= m_ucMenuActionC) && - (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtons) != 0; + if (m_bIsMenuDisplayed[iPad] && ucAction > m_ucMenuActionC) + return false; + + unsigned int uiRaw = m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction]; + unsigned int uiSwapped = (ucAction > m_ucMenuActionC) ? ApplyButtonSwap(iPad, uiRaw) : uiRaw; + return (uiSwapped & m_Joypads[iPad].m_uiButtons) != 0; } bool CInput::ButtonPressed(int iPad, unsigned char ucAction) @@ -442,13 +456,19 @@ bool CInput::ButtonPressed(int iPad, unsigned char ucAction) return 0; } - return (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtonsPressed) != 0; + unsigned int uiRaw = m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction]; + unsigned int uiSwapped = (ucAction > m_ucMenuActionC) ? ApplyButtonSwap(iPad, uiRaw) : uiRaw; + return (uiSwapped & m_Joypads[iPad].m_uiButtonsPressed) != 0; } bool CInput::ButtonReleased(int iPad, unsigned char ucAction) { - return (!m_bIsMenuDisplayed[iPad] || ucAction <= m_ucMenuActionC) && - (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtonsReleased) != 0; + if (m_bIsMenuDisplayed[iPad] && ucAction > m_ucMenuActionC) + return false; + + unsigned int uiRaw = m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction]; + unsigned int uiSwapped = (ucAction > m_ucMenuActionC) ? ApplyButtonSwap(iPad, uiRaw) : uiRaw; + return (uiSwapped & m_Joypads[iPad].m_uiButtonsReleased) != 0; } bool CInput::ButtonDown(int iPad, unsigned char ucAction) @@ -463,7 +483,9 @@ bool CInput::ButtonDown(int iPad, unsigned char ucAction) return 0; } - return (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtons) != 0; + unsigned int uiRaw = m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction]; + unsigned int uiSwapped = (ucAction > m_ucMenuActionC) ? ApplyButtonSwap(iPad, uiRaw) : uiRaw; + return (uiSwapped & m_Joypads[iPad].m_uiButtons) != 0; } float CInput::GetJoypadStick_Menu_LX(unsigned char ucPad) @@ -747,6 +769,50 @@ void CInput::GetStartTime(int iPad, int iKey) m_LastActivityTime[iPad].QuadPart = m_Timers[iPad][iKey].m_qwStartTime.QuadPart; } +void CInput::SetButtonSwapEnabled(int iPad, int iSlot, bool bEnabled) +{ + if (iPad < 0 || iPad >= MAX_JOYPADS) return; + if (iSlot < 0 || iSlot >= MAX_SWAP_SLOTS) return; + m_bSwapEnabled[iPad][iSlot] = bEnabled; +} + +void CInput::AddMapButtonSwap(int iPad, int iSlot, int iEntry, unsigned int uiBtnFrom, unsigned int uiBtnTo) +{ + if (iPad < 0 || iPad >= MAX_JOYPADS) return; + if (iSlot < 0 || iSlot >= MAX_SWAP_SLOTS) return; + if (iEntry < 0 || iEntry >= MAX_SWAP_ENTRIES) return; + m_SwapTable[iPad][iSlot][iEntry].btnFrom = uiBtnFrom; + m_SwapTable[iPad][iSlot][iEntry].btnTo = uiBtnTo; + if (iEntry >= m_iSwapEntryCount[iPad][iSlot]) + m_iSwapEntryCount[iPad][iSlot] = iEntry + 1; +} + +unsigned int CInput::ApplyButtonSwap(int iPad, unsigned int uiInput) +{ + if (iPad < 0 || iPad >= MAX_JOYPADS) return uiInput; + + for (int iSlot = 0; iSlot < MAX_SWAP_SLOTS; iSlot++) + { + if (!m_bSwapEnabled[iPad][iSlot]) continue; + + for (int iEntry = 0; iEntry < m_iSwapEntryCount[iPad][iSlot]; iEntry++) + { + unsigned int btnFrom = m_SwapTable[iPad][iSlot][iEntry].btnFrom; + unsigned int btnTo = m_SwapTable[iPad][iSlot][iEntry].btnTo; + + if (uiInput & btnFrom) + { + uiInput = (uiInput & ~btnFrom) | btnTo; + } + else if (uiInput & btnTo) + { + uiInput = (uiInput & ~btnTo) | btnFrom; + } + } + } + return uiInput; +} + void CInput::UpdateTime(int iPad, int iKey) { LARGE_INTEGER qwDeltaTime; @@ -759,4 +825,4 @@ void CInput::UpdateTime(int iPad, int iKey) m_Timers[iPad][iKey].m_fTotalHoldTime = m_Timers[iPad][iKey].m_fTotalHoldTime + (m_fTickToSeconds * qwNewTime); m_LastActivityTime[iPad].QuadPart = m_Timers[iPad][iKey].m_qwStartTime.QuadPart; -} \ No newline at end of file +} diff --git a/inc/4J_Input.h b/inc/4J_Input.h index 3083e99..1307a6f 100644 --- a/inc/4J_Input.h +++ b/inc/4J_Input.h @@ -130,6 +130,9 @@ public: void CancelQueuedVerifyStrings(int(*Func)(LPVOID, STRING_VERIFY_RESPONSE*), LPVOID lpParam); void CancelAllVerifyInProgress(void); + void SetButtonSwapEnabled(int iPad, int iSlot, bool bEnabled); + void AddMapButtonSwap(int iPad, int iSlot, int iEntry, unsigned int uiBtnFrom, unsigned int uiBtnTo); + //bool InputDetected(DWORD dwUserIndex,WCHAR *pwchInput); };