feat: button swapping

thank you rockefeler
This commit is contained in:
Fireblade
2026-06-29 23:49:29 -04:00
parent 8fb036f6d6
commit 9b25ddf575
4 changed files with 106 additions and 12 deletions

View File

@@ -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;
extern CInput InternalInputManager;

View File

@@ -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) {}
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) {}

View File

@@ -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;
}
}

View File

@@ -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);
};