/* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2020 PCSX2 Dev Team * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with PCSX2. * If not, see . */ #include "PrecompiledHeader.h" #ifndef DISABLE_RECORDING #include "DebugTools/Debug.h" #include "Recording/PadData.h" 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; 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; } 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); } #endif