diff --git a/pcsx2/Recording/PadData.cpp b/pcsx2/Recording/PadData.cpp index edc97b61fb..01d2ea38f3 100644 --- a/pcsx2/Recording/PadData.cpp +++ b/pcsx2/Recording/PadData.cpp @@ -14,9 +14,198 @@ */ #include "PrecompiledHeader.h" + #include "DebugTools/Debug.h" #include "Recording/PadData.h" +#ifndef PCSX2_CORE + +void PadData::UpdateControllerData(u16 bufIndex, u8 const& bufVal) +{ + const BufferIndex index = static_cast(bufIndex); + switch (index) + { + case BufferIndex::PressedFlagsGroupOne: + leftPressed = IsButtonPressed(LEFT, bufVal); + downPressed = IsButtonPressed(DOWN, bufVal); + rightPressed = IsButtonPressed(RIGHT, bufVal); + upPressed = IsButtonPressed(UP, bufVal); + start = IsButtonPressed(START, bufVal); + r3 = IsButtonPressed(R3, bufVal); + l3 = IsButtonPressed(L3, bufVal); + select = IsButtonPressed(SELECT, bufVal); + break; + case BufferIndex::PressedFlagsGroupTwo: + squarePressed = IsButtonPressed(SQUARE, bufVal); + crossPressed = IsButtonPressed(CROSS, bufVal); + circlePressed = IsButtonPressed(CIRCLE, bufVal); + trianglePressed = IsButtonPressed(TRIANGLE, bufVal); + r1Pressed = IsButtonPressed(R1, bufVal); + l1Pressed = IsButtonPressed(L1, bufVal); + r2Pressed = IsButtonPressed(R2, bufVal); + l2Pressed = IsButtonPressed(L2, bufVal); + break; + case BufferIndex::RightAnalogXVector: + rightAnalogX = bufVal; + break; + case BufferIndex::RightAnalogYVector: + rightAnalogY = bufVal; + break; + case BufferIndex::LeftAnalogXVector: + leftAnalogX = bufVal; + break; + case BufferIndex::LeftAnalogYVector: + leftAnalogY = bufVal; + break; + case BufferIndex::RightPressure: + rightPressure = bufVal; + break; + case BufferIndex::LeftPressure: + leftPressure = bufVal; + break; + case BufferIndex::UpPressure: + upPressure = bufVal; + break; + case BufferIndex::DownPressure: + downPressure = bufVal; + break; + case BufferIndex::TrianglePressure: + trianglePressure = bufVal; + break; + case BufferIndex::CirclePressure: + circlePressure = bufVal; + break; + case BufferIndex::CrossPressure: + crossPressure = bufVal; + break; + case BufferIndex::SquarePressure: + squarePressure = bufVal; + break; + case BufferIndex::L1Pressure: + l1Pressure = bufVal; + break; + case BufferIndex::R1Pressure: + r1Pressure = bufVal; + break; + case BufferIndex::L2Pressure: + l2Pressure = bufVal; + break; + case BufferIndex::R2Pressure: + r2Pressure = bufVal; + break; + } +} + +u8 PadData::PollControllerData(u16 bufIndex) +{ + u8 byte = 0; + const BufferIndex index = static_cast(bufIndex); + switch (index) + { + case BufferIndex::PressedFlagsGroupOne: + // Construct byte by combining flags if the buttons are pressed + byte |= BitmaskOrZero(leftPressed, LEFT); + byte |= BitmaskOrZero(downPressed, DOWN); + byte |= BitmaskOrZero(rightPressed, RIGHT); + byte |= BitmaskOrZero(upPressed, UP); + byte |= BitmaskOrZero(start, START); + byte |= BitmaskOrZero(r3, R3); + byte |= BitmaskOrZero(l3, L3); + byte |= BitmaskOrZero(select, 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(squarePressed, SQUARE); + byte |= BitmaskOrZero(crossPressed, CROSS); + byte |= BitmaskOrZero(circlePressed, CIRCLE); + byte |= BitmaskOrZero(trianglePressed, TRIANGLE); + byte |= BitmaskOrZero(r1Pressed, R1); + byte |= BitmaskOrZero(l1Pressed, L1); + byte |= BitmaskOrZero(r2Pressed, R2); + byte |= BitmaskOrZero(l2Pressed, L2); + // We flip the bits because as mentioned below, 0 = pressed + return ~byte; + case BufferIndex::RightAnalogXVector: + return rightAnalogX; + case BufferIndex::RightAnalogYVector: + return rightAnalogY; + case BufferIndex::LeftAnalogXVector: + return leftAnalogX; + case BufferIndex::LeftAnalogYVector: + return leftAnalogY; + case BufferIndex::RightPressure: + return rightPressure; + case BufferIndex::LeftPressure: + return leftPressure; + case BufferIndex::UpPressure: + return upPressure; + case BufferIndex::DownPressure: + return downPressure; + case BufferIndex::TrianglePressure: + return trianglePressure; + case BufferIndex::CirclePressure: + return circlePressure; + case BufferIndex::CrossPressure: + return crossPressure; + case BufferIndex::SquarePressure: + return squarePressure; + case BufferIndex::L1Pressure: + return l1Pressure; + case BufferIndex::R1Pressure: + return r1Pressure; + case BufferIndex::L2Pressure: + return l2Pressure; + case BufferIndex::R2Pressure: + return r2Pressure; + default: + return 0; + } +} + +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; +} + +// TODO - Vaser - kill with wxWidgets +// TODO - Vaser - replace with this something better in Qt +wxString PadData::RawPadBytesToString(int start, int end) +{ + wxString str; + for (int i = start; i < end; i++) + { + str += wxString::Format("%d", PollControllerData(i)); + if (i != end - 1) + str += ", "; + } + return str; +} + +void PadData::LogPadData(u8 const& port) +{ + wxString pressedBytes = RawPadBytesToString(0, 2); + wxString rightAnalogBytes = RawPadBytesToString(2, 4); + wxString leftAnalogBytes = RawPadBytesToString(4, 6); + wxString pressureBytes = RawPadBytesToString(6, 17); + wxString fullLog = + wxString::Format("[PAD %d] Raw Bytes: Pressed = [%s]\n", port + 1, pressedBytes) + + wxString::Format("[PAD %d] Raw Bytes: Right Analog = [%s]\n", port + 1, rightAnalogBytes) + + wxString::Format("[PAD %d] Raw Bytes: Left Analog = [%s]\n", port + 1, leftAnalogBytes) + + wxString::Format("[PAD %d] Raw Bytes: Pressure = [%s]\n", port + 1, pressureBytes); + controlLog(fullLog.ToUTF8()); +} + +#else + #include void PadData::UpdateControllerData(u16 bufIndex, u8 const bufVal) noexcept @@ -92,37 +281,6 @@ u8 PadData::PollControllerData(u16 bufIndex) const noexcept return byte; } -#ifndef PCSX2_CORE -// TODO - Vaser - kill with wxWidgets -// TODO - Vaser - replace with this something better in Qt -wxString PadData::RawPadBytesToString(int start, int end) -{ - wxString str; - for (int i = start; i < end; i++) - { - str += wxString::Format("%d", PollControllerData(i)); - if (i != end - 1) - str += ", "; - } - return str; -} - -void PadData::LogPadData(u8 const& port) -{ - wxString pressedBytes = RawPadBytesToString(0, 2); - wxString rightAnalogBytes = RawPadBytesToString(2, 4); - wxString leftAnalogBytes = RawPadBytesToString(4, 6); - wxString pressureBytes = RawPadBytesToString(6, 17); - wxString fullLog = - wxString::Format("[PAD %d] Raw Bytes: Pressed = [%s]\n", port + 1, pressedBytes) + - wxString::Format("[PAD %d] Raw Bytes: Right Analog = [%s]\n", port + 1, rightAnalogBytes) + - wxString::Format("[PAD %d] Raw Bytes: Left Analog = [%s]\n", port + 1, leftAnalogBytes) + - wxString::Format("[PAD %d] Raw Bytes: Pressure = [%s]\n", port + 1, pressureBytes); - controlLog(fullLog.ToUTF8()); -} - -#else - std::string PadData::RawPadBytesToString(int start, int end) { std::string str; diff --git a/pcsx2/Recording/PadData.h b/pcsx2/Recording/PadData.h index 8597f35777..3061d5afd4 100644 --- a/pcsx2/Recording/PadData.h +++ b/pcsx2/Recording/PadData.h @@ -15,6 +15,122 @@ #pragma once +#ifndef PCSX2_CORE + +class PadData +{ +public: + /// Constants + static const u8 ANALOG_VECTOR_NEUTRAL = 127; + + enum class BufferIndex + { + PressedFlagsGroupOne, + PressedFlagsGroupTwo, + RightAnalogXVector, + RightAnalogYVector, + LeftAnalogXVector, + LeftAnalogYVector, + RightPressure, + LeftPressure, + UpPressure, + DownPressure, + TrianglePressure, + CirclePressure, + CrossPressure, + SquarePressure, + L1Pressure, + R1Pressure, + L2Pressure, + R2Pressure + }; + + /// Pressure Buttons - 0-255 + u8 circlePressure = 0; + u8 crossPressure = 0; + u8 squarePressure = 0; + u8 trianglePressure = 0; + u8 downPressure = 0; + u8 leftPressure = 0; + u8 rightPressure = 0; + u8 upPressure = 0; + u8 l1Pressure = 0; + u8 l2Pressure = 0; + u8 r1Pressure = 0; + u8 r2Pressure = 0; + + /// Pressure Button Flags + /// 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 circlePressed = false; + bool crossPressed = false; + bool squarePressed = false; + bool trianglePressed = false; + bool downPressed = false; + bool leftPressed = false; + bool rightPressed = false; + bool upPressed = false; + bool l1Pressed = false; + bool l2Pressed = false; + bool r1Pressed = false; + bool r2Pressed = false; + + /// Normal (un)pressed buttons + bool select = false; + bool start = false; + bool l3 = false; + bool r3 = false; + + /// Analog Sticks - 0-255 (127 center) + u8 leftAnalogX = ANALOG_VECTOR_NEUTRAL; + u8 leftAnalogY = ANALOG_VECTOR_NEUTRAL; + u8 rightAnalogX = ANALOG_VECTOR_NEUTRAL; + u8 rightAnalogY = ANALOG_VECTOR_NEUTRAL; + + // Given the input buffer and the current index, updates the correct field(s) + void UpdateControllerData(u16 bufIndex, u8 const& bufVal); + u8 PollControllerData(u16 bufIndex); + + // Prints current PadData to the Controller Log filter which disabled by default + void LogPadData(u8 const& port); + +private: + struct ButtonResolver + { + u8 buttonBitmask; + }; + + const ButtonResolver LEFT = ButtonResolver{0b10000000}; + const ButtonResolver DOWN = ButtonResolver{0b01000000}; + const ButtonResolver RIGHT = ButtonResolver{0b00100000}; + const ButtonResolver UP = ButtonResolver{0b00010000}; + const ButtonResolver START = ButtonResolver{0b00001000}; + const ButtonResolver R3 = ButtonResolver{0b00000100}; + const ButtonResolver L3 = ButtonResolver{0b00000010}; + const ButtonResolver SELECT = ButtonResolver{0b00000001}; + + const ButtonResolver SQUARE = ButtonResolver{0b10000000}; + const ButtonResolver CROSS = ButtonResolver{0b01000000}; + const ButtonResolver CIRCLE = ButtonResolver{0b00100000}; + const ButtonResolver TRIANGLE = ButtonResolver{0b00010000}; + const ButtonResolver R1 = ButtonResolver{0b00001000}; + const ButtonResolver L1 = ButtonResolver{0b00000100}; + const ButtonResolver R2 = ButtonResolver{0b00000010}; + const ButtonResolver L2 = ButtonResolver{0b00000001}; + + // 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); +#else + std::string RawPadBytesToString(int start, int end); +#endif +}; + +#else + class PadData { public: @@ -104,24 +220,24 @@ public: }; /// 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. - 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}; + 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 - ButtonFlag m_select {0b00000001}; - ButtonFlag m_start {0b00001000}; - ButtonFlag m_l3 {0b00000010}; - ButtonFlag m_r3 {0b00000100}; + 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) noexcept; @@ -138,3 +254,5 @@ private: std::string RawPadBytesToString(int start, int end); #endif }; + +#endif