diff --git a/pcsx2-qt/Tools/InputRecording/InputRecordingViewer.cpp b/pcsx2-qt/Tools/InputRecording/InputRecordingViewer.cpp index 334a75ebda..7fcb0c2f0c 100644 --- a/pcsx2-qt/Tools/InputRecording/InputRecordingViewer.cpp +++ b/pcsx2-qt/Tools/InputRecording/InputRecordingViewer.cpp @@ -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++; } } diff --git a/pcsx2/Recording/PadData.cpp b/pcsx2/Recording/PadData.cpp index de9e787a41..edc97b61fb 100644 --- a/pcsx2/Recording/PadData.cpp +++ b/pcsx2/Recording/PadData.cpp @@ -19,178 +19,77 @@ #include -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(bufIndex); - switch (index) + if (bufIndex == static_cast(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(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(bufIndex); - switch (index) + if (bufIndex == static_cast(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(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) + diff --git a/pcsx2/Recording/PadData.h b/pcsx2/Recording/PadData.h index 15d1489a10..8597f35777 100644 --- a/pcsx2/Recording/PadData.h +++ b/pcsx2/Recording/PadData.h @@ -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);