input-rec: refactor PadData button state control

This commit is contained in:
sonicfind 2022-09-22 10:19:56 -05:00 committed by refractionpcsx2
parent 1356171af5
commit 6288f945cd
3 changed files with 146 additions and 235 deletions

View File

@ -50,24 +50,24 @@ void InputRecordingViewer::loadTable()
for (const auto& frame : data)
{
// TODO - disgusting, clean it up
m_ui.tableWidget->setItem(frameNum, 0, new QTableWidgetItem(tr("%1 %2").arg(frame.m_leftAnalogX).arg(frame.m_leftAnalogY)));
m_ui.tableWidget->setItem(frameNum, 1, new QTableWidgetItem(tr("%1 %2").arg(frame.m_rightAnalogX).arg(frame.m_rightAnalogY)));
m_ui.tableWidget->setItem(frameNum, 2, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_crossPressed).arg(frame.m_crossPressure)));
m_ui.tableWidget->setItem(frameNum, 3, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_squarePressed).arg(frame.m_squarePressure)));
m_ui.tableWidget->setItem(frameNum, 4, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_trianglePressed).arg(frame.m_trianglePressure)));
m_ui.tableWidget->setItem(frameNum, 5, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_circlePressed).arg(frame.m_circlePressure)));
m_ui.tableWidget->setItem(frameNum, 6, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_l1Pressed).arg(frame.m_l1Pressure)));
m_ui.tableWidget->setItem(frameNum, 7, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_l2Pressed).arg(frame.m_l2Pressure)));
m_ui.tableWidget->setItem(frameNum, 8, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_r1Pressed).arg(frame.m_r1Pressure)));
m_ui.tableWidget->setItem(frameNum, 9, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_r1Pressed).arg(frame.m_r2Pressure)));
m_ui.tableWidget->setItem(frameNum, 10, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_downPressed).arg(frame.m_downPressure)));
m_ui.tableWidget->setItem(frameNum, 11, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_rightPressed).arg(frame.m_rightPressure)));
m_ui.tableWidget->setItem(frameNum, 12, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_upPressed).arg(frame.m_upPressure)));
m_ui.tableWidget->setItem(frameNum, 13, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_leftPressed).arg(frame.m_leftPressure)));
m_ui.tableWidget->setItem(frameNum, 14, new QTableWidgetItem(tr("%1").arg(frame.m_l3)));
m_ui.tableWidget->setItem(frameNum, 15, new QTableWidgetItem(tr("%1").arg(frame.m_r3)));
m_ui.tableWidget->setItem(frameNum, 16, new QTableWidgetItem(tr("%1").arg(frame.m_select)));
m_ui.tableWidget->setItem(frameNum, 17, new QTableWidgetItem(tr("%1").arg(frame.m_start)));
m_ui.tableWidget->setItem(frameNum, 0, new QTableWidgetItem(tr("%1 %2") .arg(frame.m_leftAnalogX) .arg(frame.m_leftAnalogY)));
m_ui.tableWidget->setItem(frameNum, 1, new QTableWidgetItem(tr("%1 %2") .arg(frame.m_rightAnalogX) .arg(frame.m_rightAnalogY)));
m_ui.tableWidget->setItem(frameNum, 2, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_crossPressed.m_pressed) .arg(frame.m_crossPressure)));
m_ui.tableWidget->setItem(frameNum, 3, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_squarePressed.m_pressed) .arg(frame.m_squarePressure)));
m_ui.tableWidget->setItem(frameNum, 4, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_trianglePressed.m_pressed).arg(frame.m_trianglePressure)));
m_ui.tableWidget->setItem(frameNum, 5, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_circlePressed.m_pressed) .arg(frame.m_circlePressure)));
m_ui.tableWidget->setItem(frameNum, 6, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_l1Pressed.m_pressed) .arg(frame.m_l1Pressure)));
m_ui.tableWidget->setItem(frameNum, 7, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_l2Pressed.m_pressed) .arg(frame.m_l2Pressure)));
m_ui.tableWidget->setItem(frameNum, 8, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_r1Pressed.m_pressed) .arg(frame.m_r1Pressure)));
m_ui.tableWidget->setItem(frameNum, 9, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_r1Pressed.m_pressed) .arg(frame.m_r2Pressure)));
m_ui.tableWidget->setItem(frameNum, 10, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_downPressed.m_pressed) .arg(frame.m_downPressure)));
m_ui.tableWidget->setItem(frameNum, 11, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_rightPressed.m_pressed) .arg(frame.m_rightPressure)));
m_ui.tableWidget->setItem(frameNum, 12, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_upPressed.m_pressed) .arg(frame.m_upPressure)));
m_ui.tableWidget->setItem(frameNum, 13, new QTableWidgetItem(tr("%1 [%2]").arg(frame.m_leftPressed.m_pressed) .arg(frame.m_leftPressure)));
m_ui.tableWidget->setItem(frameNum, 14, new QTableWidgetItem(tr("%1") .arg(frame.m_l3.m_pressed)));
m_ui.tableWidget->setItem(frameNum, 15, new QTableWidgetItem(tr("%1") .arg(frame.m_r3.m_pressed)));
m_ui.tableWidget->setItem(frameNum, 16, new QTableWidgetItem(tr("%1") .arg(frame.m_select.m_pressed)));
m_ui.tableWidget->setItem(frameNum, 17, new QTableWidgetItem(tr("%1") .arg(frame.m_start.m_pressed)));
frameNum++;
}
}

View File

@ -19,178 +19,77 @@
#include <fmt/core.h>
const PadData::ButtonResolver PadData::s_LEFT {0b10000000};
const PadData::ButtonResolver PadData::s_DOWN {0b01000000};
const PadData::ButtonResolver PadData::s_RIGHT {0b00100000};
const PadData::ButtonResolver PadData::s_UP {0b00010000};
const PadData::ButtonResolver PadData::s_START {0b00001000};
const PadData::ButtonResolver PadData::s_R3 {0b00000100};
const PadData::ButtonResolver PadData::s_L3 {0b00000010};
const PadData::ButtonResolver PadData::s_SELECT {0b00000001};
const PadData::ButtonResolver PadData::s_SQUARE {0b10000000};
const PadData::ButtonResolver PadData::s_CROSS {0b01000000};
const PadData::ButtonResolver PadData::s_CIRCLE {0b00100000};
const PadData::ButtonResolver PadData::s_TRIANGLE{0b00010000};
const PadData::ButtonResolver PadData::s_R1 {0b00001000};
const PadData::ButtonResolver PadData::s_L1 {0b00000100};
const PadData::ButtonResolver PadData::s_R2 {0b00000010};
const PadData::ButtonResolver PadData::s_L2 {0b00000001};
void PadData::UpdateControllerData(u16 bufIndex, u8 const& bufVal)
void PadData::UpdateControllerData(u16 bufIndex, u8 const bufVal) noexcept
{
const BufferIndex index = static_cast<BufferIndex>(bufIndex);
switch (index)
if (bufIndex == static_cast<u8>(BufferIndex::PressedFlagsGroupOne))
{
case BufferIndex::PressedFlagsGroupOne:
m_leftPressed = IsButtonPressed(s_LEFT, bufVal);
m_downPressed = IsButtonPressed(s_DOWN, bufVal);
m_rightPressed = IsButtonPressed(s_RIGHT, bufVal);
m_upPressed = IsButtonPressed(s_UP, bufVal);
m_start = IsButtonPressed(s_START, bufVal);
m_r3 = IsButtonPressed(s_R3, bufVal);
m_l3 = IsButtonPressed(s_L3, bufVal);
m_select = IsButtonPressed(s_SELECT, bufVal);
break;
case BufferIndex::PressedFlagsGroupTwo:
m_squarePressed = IsButtonPressed(s_SQUARE, bufVal);
m_crossPressed = IsButtonPressed(s_CROSS, bufVal);
m_circlePressed = IsButtonPressed(s_CIRCLE, bufVal);
m_trianglePressed = IsButtonPressed(s_TRIANGLE, bufVal);
m_r1Pressed = IsButtonPressed(s_R1, bufVal);
m_l1Pressed = IsButtonPressed(s_L1, bufVal);
m_r2Pressed = IsButtonPressed(s_R2, bufVal);
m_l2Pressed = IsButtonPressed(s_L2, bufVal);
break;
case BufferIndex::RightAnalogXVector:
m_rightAnalogX = bufVal;
break;
case BufferIndex::RightAnalogYVector:
m_rightAnalogY = bufVal;
break;
case BufferIndex::LeftAnalogXVector:
m_leftAnalogX = bufVal;
break;
case BufferIndex::LeftAnalogYVector:
m_leftAnalogY = bufVal;
break;
case BufferIndex::RightPressure:
m_rightPressure = bufVal;
break;
case BufferIndex::LeftPressure:
m_leftPressure = bufVal;
break;
case BufferIndex::UpPressure:
m_upPressure = bufVal;
break;
case BufferIndex::DownPressure:
m_downPressure = bufVal;
break;
case BufferIndex::TrianglePressure:
m_trianglePressure = bufVal;
break;
case BufferIndex::CirclePressure:
m_circlePressure = bufVal;
break;
case BufferIndex::CrossPressure:
m_crossPressure = bufVal;
break;
case BufferIndex::SquarePressure:
m_squarePressure = bufVal;
break;
case BufferIndex::L1Pressure:
m_l1Pressure = bufVal;
break;
case BufferIndex::R1Pressure:
m_r1Pressure = bufVal;
break;
case BufferIndex::L2Pressure:
m_l2Pressure = bufVal;
break;
case BufferIndex::R2Pressure:
m_r2Pressure = bufVal;
break;
m_leftPressed.setPressedState(bufVal);
m_downPressed.setPressedState(bufVal);
m_rightPressed.setPressedState(bufVal);
m_upPressed.setPressedState(bufVal);
m_start.setPressedState(bufVal);
m_r3.setPressedState(bufVal);
m_l3.setPressedState(bufVal);
m_select.setPressedState(bufVal);
}
else if (bufIndex == static_cast<u8>(BufferIndex::PressedFlagsGroupTwo))
{
m_squarePressed.setPressedState(bufVal);
m_crossPressed.setPressedState(bufVal);
m_circlePressed.setPressedState(bufVal);
m_trianglePressed.setPressedState(bufVal);
m_r1Pressed.setPressedState(bufVal);
m_l1Pressed.setPressedState(bufVal);
m_r2Pressed.setPressedState(bufVal);
m_l2Pressed.setPressedState(bufVal);
}
else
{
bufIndex -= 2;
if (bufIndex < sizeof(m_allIntensities) / sizeof(u8*))
*m_allIntensities[bufIndex] = bufVal;
}
}
u8 PadData::PollControllerData(u16 bufIndex)
u8 PadData::PollControllerData(u16 bufIndex) const noexcept
{
u8 byte = 0;
const BufferIndex index = static_cast<BufferIndex>(bufIndex);
switch (index)
if (bufIndex == static_cast<u8>(BufferIndex::PressedFlagsGroupOne))
{
case BufferIndex::PressedFlagsGroupOne:
// Construct byte by combining flags if the buttons are pressed
byte |= BitmaskOrZero(m_leftPressed, s_LEFT);
byte |= BitmaskOrZero(m_downPressed, s_DOWN);
byte |= BitmaskOrZero(m_rightPressed, s_RIGHT);
byte |= BitmaskOrZero(m_upPressed, s_UP);
byte |= BitmaskOrZero(m_start, s_START);
byte |= BitmaskOrZero(m_r3, s_R3);
byte |= BitmaskOrZero(m_l3, s_L3);
byte |= BitmaskOrZero(m_select, s_SELECT);
// We flip the bits because as mentioned below, 0 = pressed
return ~byte;
case BufferIndex::PressedFlagsGroupTwo:
// Construct byte by combining flags if the buttons are pressed
byte |= BitmaskOrZero(m_squarePressed, s_SQUARE);
byte |= BitmaskOrZero(m_crossPressed, s_CROSS);
byte |= BitmaskOrZero(m_circlePressed, s_CIRCLE);
byte |= BitmaskOrZero(m_trianglePressed, s_TRIANGLE);
byte |= BitmaskOrZero(m_r1Pressed, s_R1);
byte |= BitmaskOrZero(m_l1Pressed, s_L1);
byte |= BitmaskOrZero(m_r2Pressed, s_R2);
byte |= BitmaskOrZero(m_l2Pressed, s_L2);
// We flip the bits because as mentioned below, 0 = pressed
return ~byte;
case BufferIndex::RightAnalogXVector:
return m_rightAnalogX;
case BufferIndex::RightAnalogYVector:
return m_rightAnalogY;
case BufferIndex::LeftAnalogXVector:
return m_leftAnalogX;
case BufferIndex::LeftAnalogYVector:
return m_leftAnalogY;
case BufferIndex::RightPressure:
return m_rightPressure;
case BufferIndex::LeftPressure:
return m_leftPressure;
case BufferIndex::UpPressure:
return m_upPressure;
case BufferIndex::DownPressure:
return m_downPressure;
case BufferIndex::TrianglePressure:
return m_trianglePressure;
case BufferIndex::CirclePressure:
return m_circlePressure;
case BufferIndex::CrossPressure:
return m_crossPressure;
case BufferIndex::SquarePressure:
return m_squarePressure;
case BufferIndex::L1Pressure:
return m_l1Pressure;
case BufferIndex::R1Pressure:
return m_r1Pressure;
case BufferIndex::L2Pressure:
return m_l2Pressure;
case BufferIndex::R2Pressure:
return m_r2Pressure;
default:
return 0;
// Construct byte by combining flags if the buttons are pressed
byte |= m_leftPressed.getMaskIfPressed();
byte |= m_downPressed.getMaskIfPressed();
byte |= m_rightPressed.getMaskIfPressed();
byte |= m_upPressed.getMaskIfPressed();
byte |= m_start.getMaskIfPressed();
byte |= m_r3.getMaskIfPressed();
byte |= m_l3.getMaskIfPressed();
byte |= m_select.getMaskIfPressed();
// We flip the bits because as mentioned below, 0 = pressed
byte = ~byte;
}
else if (bufIndex == static_cast<u8>(BufferIndex::PressedFlagsGroupTwo))
{
// Construct byte by combining flags if the buttons are pressed
byte |= m_squarePressed.getMaskIfPressed();
byte |= m_crossPressed.getMaskIfPressed();
byte |= m_circlePressed.getMaskIfPressed();
byte |= m_trianglePressed.getMaskIfPressed();
byte |= m_r1Pressed.getMaskIfPressed();
byte |= m_l1Pressed.getMaskIfPressed();
byte |= m_r2Pressed.getMaskIfPressed();
byte |= m_l2Pressed.getMaskIfPressed();
// We flip the bits because as mentioned below, 0 = pressed
byte = ~byte;
}
else
{
bufIndex -= 2;
if (bufIndex < sizeof(m_allIntensities) / sizeof(u8*))
byte = *m_allIntensities[bufIndex - 2];
}
}
bool PadData::IsButtonPressed(ButtonResolver buttonResolver, u8 const& bufVal)
{
// Rather than the flags being SET if the button is pressed, it is the opposite
// For example: 0111 1111 with `left` being the first bit indicates `left` is pressed.
// So, we are forced to flip the pressed bits with a NOT first
return (~bufVal & buttonResolver.buttonBitmask) > 0;
}
u8 PadData::BitmaskOrZero(bool pressed, ButtonResolver buttonInfo)
{
return pressed ? buttonInfo.buttonBitmask : 0;
return byte;
}
#ifndef PCSX2_CORE
@ -239,11 +138,11 @@ std::string PadData::RawPadBytesToString(int start, int end)
void PadData::LogPadData(u8 const& port)
{
std::string pressedBytes = RawPadBytesToString(0, 2);
std::string rightAnalogBytes = RawPadBytesToString(2, 4);
std::string leftAnalogBytes = RawPadBytesToString(4, 6);
std::string pressureBytes = RawPadBytesToString(6, 17);
std::string fullLog =
const std::string pressedBytes = RawPadBytesToString(0, 2);
const std::string rightAnalogBytes = RawPadBytesToString(2, 4);
const std::string leftAnalogBytes = RawPadBytesToString(4, 6);
const std::string pressureBytes = RawPadBytesToString(6, 17);
const std::string fullLog =
fmt::format("[PAD {}] Raw Bytes: Pressed = [{}]\n", port + 1, pressedBytes) +
fmt::format("[PAD {}] Raw Bytes: Right Analog = [{}]\n", port + 1, rightAnalogBytes) +
fmt::format("[PAD {}] Raw Bytes: Left Analog = [{}]\n", port + 1, leftAnalogBytes) +

View File

@ -43,6 +43,12 @@ public:
R2Pressure
};
/// Analog Sticks - 0-255 (127 center)
u8 m_leftAnalogX = ANALOG_VECTOR_NEUTRAL;
u8 m_leftAnalogY = ANALOG_VECTOR_NEUTRAL;
u8 m_rightAnalogX = ANALOG_VECTOR_NEUTRAL;
u8 m_rightAnalogY = ANALOG_VECTOR_NEUTRAL;
/// Pressure Buttons - 0-255
u8 m_circlePressure = 0;
u8 m_crossPressure = 0;
@ -57,68 +63,74 @@ public:
u8 m_r1Pressure = 0;
u8 m_r2Pressure = 0;
u8* const m_allIntensities[16]{
&m_rightAnalogX,
&m_rightAnalogY,
&m_leftAnalogX,
&m_leftAnalogY,
&m_rightPressure,
&m_leftPressure,
&m_upPressure,
&m_downPressure,
&m_trianglePressure,
&m_circlePressure,
&m_crossPressure,
&m_squarePressure,
&m_l1Pressure,
&m_r1Pressure,
&m_l2Pressure,
&m_r2Pressure,
};
/// Pressure Button Flags
struct ButtonFlag
{
bool m_pressed = false;
const u8 m_BITMASK;
constexpr ButtonFlag(u8 maskValue)
: m_BITMASK(maskValue)
{
}
void setPressedState(u8 bufVal) noexcept
{
m_pressed = (~bufVal & m_BITMASK) > 0;
}
u8 getMaskIfPressed() const noexcept
{
return m_pressed ? m_BITMASK : 0;
}
};
/// NOTE - It shouldn't be possible to depress a button while also having no pressure
/// But for the sake of completeness, it should be tracked.
bool m_circlePressed = false;
bool m_crossPressed = false;
bool m_squarePressed = false;
bool m_trianglePressed = false;
bool m_downPressed = false;
bool m_leftPressed = false;
bool m_rightPressed = false;
bool m_upPressed = false;
bool m_l1Pressed = false;
bool m_l2Pressed = false;
bool m_r1Pressed = false;
bool m_r2Pressed = false;
ButtonFlag m_circlePressed {0b00100000};
ButtonFlag m_crossPressed {0b01000000};
ButtonFlag m_squarePressed {0b10000000};
ButtonFlag m_trianglePressed {0b00010000};
ButtonFlag m_downPressed {0b01000000};
ButtonFlag m_leftPressed {0b10000000};
ButtonFlag m_rightPressed {0b00100000};
ButtonFlag m_upPressed {0b00010000};
ButtonFlag m_l1Pressed {0b00000100};
ButtonFlag m_l2Pressed {0b00000001};
ButtonFlag m_r1Pressed {0b00001000};
ButtonFlag m_r2Pressed {0b00000010};
/// Normal (un)pressed buttons
bool m_select = false;
bool m_start = false;
bool m_l3 = false;
bool m_r3 = false;
/// Analog Sticks - 0-255 (127 center)
u8 m_leftAnalogX = ANALOG_VECTOR_NEUTRAL;
u8 m_leftAnalogY = ANALOG_VECTOR_NEUTRAL;
u8 m_rightAnalogX = ANALOG_VECTOR_NEUTRAL;
u8 m_rightAnalogY = ANALOG_VECTOR_NEUTRAL;
ButtonFlag m_select {0b00000001};
ButtonFlag m_start {0b00001000};
ButtonFlag m_l3 {0b00000010};
ButtonFlag m_r3 {0b00000100};
// Given the input buffer and the current index, updates the correct field(s)
void UpdateControllerData(u16 bufIndex, u8 const& bufVal);
u8 PollControllerData(u16 bufIndex);
void UpdateControllerData(u16 bufIndex, u8 const bufVal) noexcept;
u8 PollControllerData(u16 bufIndex) const noexcept;
// Prints current PadData to the Controller Log filter which disabled by default
void LogPadData(u8 const& port);
private:
struct ButtonResolver
{
u8 buttonBitmask;
};
static const ButtonResolver s_LEFT;
static const ButtonResolver s_DOWN;
static const ButtonResolver s_RIGHT;
static const ButtonResolver s_UP;
static const ButtonResolver s_START;
static const ButtonResolver s_R3;
static const ButtonResolver s_L3;
static const ButtonResolver s_SELECT;
static const ButtonResolver s_SQUARE;
static const ButtonResolver s_CROSS;
static const ButtonResolver s_CIRCLE;
static const ButtonResolver s_TRIANGLE;
static const ButtonResolver s_R1;
static const ButtonResolver s_L1;
static const ButtonResolver s_R2;
static const ButtonResolver s_L2;
// Checks and returns if button a is pressed or not
bool IsButtonPressed(ButtonResolver buttonResolver, u8 const& bufVal);
u8 BitmaskOrZero(bool pressed, ButtonResolver buttonInfo);
#ifndef PCSX2_CORE
wxString RawPadBytesToString(int start, int end);