mirror of https://github.com/PCSX2/pcsx2.git
recording: Rewrite of PadData class
Now a pure object representation of the controller data, no longer tightly coupled to the VirtualPad
This commit is contained in:
parent
1afc75d6d9
commit
b53d22ae7d
|
@ -1,5 +1,5 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2019 PCSX2 Dev Team
|
||||
* 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-
|
||||
|
@ -19,300 +19,179 @@
|
|||
#include "ConsoleLogger.h"
|
||||
#include "PadData.h"
|
||||
|
||||
|
||||
#ifndef DISABLE_RECORDING
|
||||
PadData::PadData()
|
||||
void PadData::UpdateControllerData(u16 bufIndex, u8 const &bufVal)
|
||||
{
|
||||
// TODO - multi-tap support eventually?
|
||||
for (int port = 0; port < 2; port++)
|
||||
BufferIndex index = static_cast<BufferIndex>(bufIndex);
|
||||
switch (index)
|
||||
{
|
||||
buf[port][0] = 255;
|
||||
buf[port][1] = 255;
|
||||
buf[port][2] = 127;
|
||||
buf[port][3] = 127;
|
||||
buf[port][4] = 127;
|
||||
buf[port][5] = 127;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void PadData::LogPadData(u8 port, u16 bufCount, u8 buf[512]) {
|
||||
// skip first two bytes because they dont seem to matter
|
||||
if (port == 0 && bufCount > 2)
|
||||
{
|
||||
if (bufCount == 3)
|
||||
{
|
||||
controlLog(wxString::Format("\nController Port %d", port));
|
||||
controlLog(wxString::Format("\nPressed Flags - "));
|
||||
}
|
||||
if (bufCount == 5) // analog sticks
|
||||
{
|
||||
controlLog(wxString::Format("\nAnalog Sticks - "));
|
||||
}
|
||||
if (bufCount == 9) // pressure sensitive bytes
|
||||
{
|
||||
controlLog(wxString::Format("\nPressure Bytes - "));
|
||||
}
|
||||
controlLog(wxString::Format("%3d ", buf[bufCount]));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> PadData::GetNormalButtons(int port) const
|
||||
u8 PadData::PollControllerData(u16 bufIndex)
|
||||
{
|
||||
std::vector<int> buttons(PadDataNormalButtonCount);
|
||||
for (int i = 0; i < PadDataNormalButtonCount; i++)
|
||||
u8 byte = 0;
|
||||
BufferIndex index = static_cast<BufferIndex>(bufIndex);
|
||||
switch (index)
|
||||
{
|
||||
buttons[i] = GetNormalButton(port, PadData_NormalButton(i));
|
||||
}
|
||||
return buttons;
|
||||
}
|
||||
|
||||
void PadData::SetNormalButtons(int port, std::vector<int> buttons)
|
||||
{
|
||||
for (int i = 0; i < PadDataNormalButtonCount; i++)
|
||||
{
|
||||
SetNormalButton(port, PadData_NormalButton(i), buttons[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void PadData::SetNormalButton(int port, PadData_NormalButton button, int fpushed)
|
||||
{
|
||||
wxByte keybit[2];
|
||||
GetKeyBit(keybit, button);
|
||||
int pressureByteIndex = GetPressureByte(button);
|
||||
|
||||
if (fpushed > 0)
|
||||
{
|
||||
// set whether or not the button is pressed
|
||||
buf[port][0] = ~(~buf[port][0] | keybit[0]);
|
||||
buf[port][1] = ~(~buf[port][1] | keybit[1]);
|
||||
|
||||
// if the button supports pressure sensitivity
|
||||
if (pressureByteIndex != -1)
|
||||
{
|
||||
buf[port][6 + pressureByteIndex] = fpushed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[port][0] = (buf[port][0] | keybit[0]);
|
||||
buf[port][1] = (buf[port][1] | keybit[1]);
|
||||
|
||||
// if the button supports pressure sensitivity
|
||||
if (pressureByteIndex != -1)
|
||||
{
|
||||
buf[port][6 + pressureByteIndex] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int PadData::GetNormalButton(int port, PadData_NormalButton button) const
|
||||
{
|
||||
wxByte keybit[2];
|
||||
GetKeyBit(keybit, button);
|
||||
int pressureByteIndex = GetPressureByte(button);
|
||||
|
||||
// If the button is pressed on either controller
|
||||
bool f1 = (~buf[port][0] & keybit[0])>0;
|
||||
bool f2 = (~buf[port][1] & keybit[1])>0;
|
||||
|
||||
if (f1 || f2)
|
||||
{
|
||||
// If the button does not support pressure sensitive inputs
|
||||
// just return 1 for pressed.
|
||||
if (pressureByteIndex == -1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
// else return the pressure information
|
||||
return buf[port][6 + pressureByteIndex];
|
||||
}
|
||||
|
||||
// else the button isnt pressed at all
|
||||
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;
|
||||
}
|
||||
|
||||
void PadData::GetKeyBit(wxByte keybit[2], PadData_NormalButton button) const
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case PadData_NormalButton_LEFT:
|
||||
keybit[0] = 0b10000000;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_DOWN:
|
||||
keybit[0] = 0b01000000;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_RIGHT:
|
||||
keybit[0] = 0b00100000;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_UP:
|
||||
keybit[0] = 0b00010000;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_START:
|
||||
keybit[0] = 0b00001000;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_R3:
|
||||
keybit[0] = 0b00000100;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_L3:
|
||||
keybit[0] = 0b00000010;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_SELECT:
|
||||
keybit[0] = 0b00000001;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_SQUARE:
|
||||
keybit[0] = 0b00000000;
|
||||
keybit[1] = 0b10000000;
|
||||
break;
|
||||
case PadData_NormalButton_CROSS:
|
||||
keybit[0] = 0b00000000;
|
||||
keybit[1] = 0b01000000;
|
||||
break;
|
||||
case PadData_NormalButton_CIRCLE:
|
||||
keybit[0] = 0b00000000;
|
||||
keybit[1] = 0b00100000;
|
||||
break;
|
||||
case PadData_NormalButton_TRIANGLE:
|
||||
keybit[0] = 0b00000000;
|
||||
keybit[1] = 0b00010000;
|
||||
break;
|
||||
case PadData_NormalButton_R1:
|
||||
keybit[0] = 0b00000000;
|
||||
keybit[1] = 0b00001000;
|
||||
break;
|
||||
case PadData_NormalButton_L1:
|
||||
keybit[0] = 0b00000000;
|
||||
keybit[1] = 0b00000100;
|
||||
break;
|
||||
case PadData_NormalButton_R2:
|
||||
keybit[0] = 0b00000000;
|
||||
keybit[1] = 0b00000010;
|
||||
break;
|
||||
case PadData_NormalButton_L2:
|
||||
keybit[0] = 0b00000000;
|
||||
keybit[1] = 0b00000001;
|
||||
break;
|
||||
default:
|
||||
keybit[0] = 0;
|
||||
keybit[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an index for the buffer to set the pressure byte
|
||||
// Returns -1 if it is a button that does not support pressure sensitivty
|
||||
int PadData::GetPressureByte(PadData_NormalButton button) const
|
||||
bool PadData::IsButtonPressed(ButtonResolver buttonResolver, u8 const &bufVal)
|
||||
{
|
||||
// Pressure Byte Order
|
||||
// R - L - U - D - Tri - Circle - Cross - Sqr - L1 - R1 - L2 - R2
|
||||
switch (button)
|
||||
{
|
||||
case PadData_NormalButton_RIGHT:
|
||||
return 0;
|
||||
break;
|
||||
case PadData_NormalButton_LEFT:
|
||||
return 1;
|
||||
break;
|
||||
case PadData_NormalButton_UP:
|
||||
return 2;
|
||||
break;
|
||||
case PadData_NormalButton_DOWN:
|
||||
return 3;
|
||||
break;
|
||||
case PadData_NormalButton_TRIANGLE:
|
||||
return 4;
|
||||
break;
|
||||
case PadData_NormalButton_CIRCLE:
|
||||
return 5;
|
||||
break;
|
||||
case PadData_NormalButton_CROSS:
|
||||
return 6;
|
||||
break;
|
||||
case PadData_NormalButton_SQUARE:
|
||||
return 7;
|
||||
break;
|
||||
case PadData_NormalButton_L1:
|
||||
return 8;
|
||||
break;
|
||||
case PadData_NormalButton_R1:
|
||||
return 9;
|
||||
break;
|
||||
case PadData_NormalButton_L2:
|
||||
return 10;
|
||||
break;
|
||||
case PadData_NormalButton_R2:
|
||||
return 11;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
std::vector<int> PadData::GetAnalogVectors(int port) const
|
||||
u8 PadData::BitmaskOrZero(bool pressed, ButtonResolver buttonInfo)
|
||||
{
|
||||
std::vector<int> vectors(PadDataAnalogVectorCount);
|
||||
for (int i = 0; i < PadDataAnalogVectorCount; i++)
|
||||
{
|
||||
vectors[i] = GetAnalogVector(port, PadData_AnalogVector(i));
|
||||
}
|
||||
return vectors;
|
||||
return pressed ? buttonInfo.buttonBitmask : 0;
|
||||
}
|
||||
|
||||
void PadData::SetAnalogVectors(int port, std::vector<int> vectors)
|
||||
wxString PadData::RawPadBytesToString(int start, int end)
|
||||
{
|
||||
for (int i = 0; i < PadDataAnalogVectorCount; i++)
|
||||
{
|
||||
SetAnalogVector(port, PadData_AnalogVector(i), vectors[i]);
|
||||
wxString str;
|
||||
for (int i = start; i < end; i++) {
|
||||
str += wxString::Format("%d", PollControllerData(i));
|
||||
if (i != end-1) {
|
||||
str += ", ";
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void PadData::SetAnalogVector(int port, PadData_AnalogVector vector, int val)
|
||||
{
|
||||
if (val < 0)
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
else if (val > 255)
|
||||
{
|
||||
val = 255;
|
||||
}
|
||||
|
||||
buf[port][GetAnalogVectorByte(vector)] = val;
|
||||
void PadData::LogPadData() {
|
||||
wxString pressedBytes = RawPadBytesToString(0, 2);
|
||||
wxString rightAnalogBytes = RawPadBytesToString(2, 4);
|
||||
wxString leftAnalogBytes = RawPadBytesToString(4, 6);
|
||||
wxString pressureBytes = RawPadBytesToString(6, 17);
|
||||
controlLog(wxString::Format("[PAD] Raw Bytes: Pressed = [%s], Right Analog = [%s], Left Analog = [%s]\n", pressedBytes, rightAnalogBytes, leftAnalogBytes));
|
||||
controlLog(wxString::Format("[PAD] Raw Bytes: Pressure = [%s]\n", pressureBytes));
|
||||
}
|
||||
|
||||
int PadData::GetAnalogVector(int port, PadData_AnalogVector vector) const
|
||||
{
|
||||
|
||||
return buf[port][GetAnalogVectorByte(vector)];
|
||||
}
|
||||
|
||||
// Returns an index for the buffer to set the analog's vector
|
||||
int PadData::GetAnalogVectorByte(PadData_AnalogVector vector) const
|
||||
{
|
||||
// Vector Byte Ordering
|
||||
// RX - RY - LX - LY
|
||||
switch (vector)
|
||||
{
|
||||
case PadData_AnalogVector_RIGHT_ANALOG_X:
|
||||
return 2;
|
||||
break;
|
||||
case PadData_AnalogVector_RIGHT_ANALOG_Y:
|
||||
return 3;
|
||||
break;
|
||||
case PadData_AnalogVector_LEFT_ANALOG_X:
|
||||
return 4;
|
||||
break;
|
||||
case PadData_AnalogVector_LEFT_ANALOG_Y:
|
||||
return 5;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2019 PCSX2 Dev Team
|
||||
* 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-
|
||||
|
@ -15,75 +15,115 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#ifndef DISABLE_RECORDING
|
||||
static const int PadDataNormalButtonCount = 16;
|
||||
enum PadData_NormalButton
|
||||
{
|
||||
PadData_NormalButton_UP,
|
||||
PadData_NormalButton_RIGHT,
|
||||
PadData_NormalButton_LEFT,
|
||||
PadData_NormalButton_DOWN,
|
||||
PadData_NormalButton_CROSS,
|
||||
PadData_NormalButton_CIRCLE,
|
||||
PadData_NormalButton_SQUARE,
|
||||
PadData_NormalButton_TRIANGLE,
|
||||
PadData_NormalButton_L1,
|
||||
PadData_NormalButton_L2,
|
||||
PadData_NormalButton_R1,
|
||||
PadData_NormalButton_R2,
|
||||
PadData_NormalButton_L3,
|
||||
PadData_NormalButton_R3,
|
||||
PadData_NormalButton_SELECT,
|
||||
PadData_NormalButton_START
|
||||
};
|
||||
|
||||
static const int PadDataAnalogVectorCount = 4;
|
||||
enum PadData_AnalogVector
|
||||
{
|
||||
PadData_AnalogVector_LEFT_ANALOG_X,
|
||||
PadData_AnalogVector_LEFT_ANALOG_Y,
|
||||
PadData_AnalogVector_RIGHT_ANALOG_X,
|
||||
PadData_AnalogVector_RIGHT_ANALOG_Y
|
||||
};
|
||||
|
||||
struct PadData
|
||||
class PadData
|
||||
{
|
||||
public:
|
||||
PadData();
|
||||
~PadData() {}
|
||||
/// Constants
|
||||
const u8 PRESSURE_BUTTON_UNPRESSED = 0;
|
||||
const bool BUTTON_PRESSED = true;
|
||||
const bool BUTTON_UNPRESSED = false;
|
||||
const u8 ANALOG_VECTOR_CENTER_POS = 127;
|
||||
|
||||
bool fExistKey = false;
|
||||
u8 buf[2][18];
|
||||
enum class BufferIndex
|
||||
{
|
||||
PressedFlagsGroupOne,
|
||||
PressedFlagsGroupTwo,
|
||||
RightAnalogXVector,
|
||||
RightAnalogYVector,
|
||||
LeftAnalogXVector,
|
||||
LeftAnalogYVector,
|
||||
RightPressure,
|
||||
LeftPressure,
|
||||
UpPressure,
|
||||
DownPressure,
|
||||
TrianglePressure,
|
||||
CirclePressure,
|
||||
CrossPressure,
|
||||
SquarePressure,
|
||||
L1Pressure,
|
||||
R1Pressure,
|
||||
L2Pressure,
|
||||
R2Pressure
|
||||
};
|
||||
|
||||
// Prints controlller data every frame to the Controller Log filter, disabled by default
|
||||
static void LogPadData(u8 port, u16 bufCount, u8 buf[512]);
|
||||
/// Pressure Buttons - 0-255
|
||||
u8 circlePressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 crossPressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 squarePressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 trianglePressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 downPressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 leftPressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 rightPressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 upPressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 l1Pressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 l2Pressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 r1Pressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
u8 r2Pressure = PRESSURE_BUTTON_UNPRESSED;
|
||||
|
||||
// Normal Buttons
|
||||
std::vector<int> GetNormalButtons(int port) const;
|
||||
void SetNormalButtons(int port, std::vector<int> buttons);
|
||||
/// Pressure Button Flags
|
||||
/// NOTE - It shouldn't be possible to depress a button
|
||||
/// while also having no pressure (PAD plugin should default to max pressure).
|
||||
/// But for the sake of completeness, it should be tracked.
|
||||
bool circlePressed = BUTTON_UNPRESSED;
|
||||
bool crossPressed = BUTTON_UNPRESSED;
|
||||
bool squarePressed = BUTTON_UNPRESSED;
|
||||
bool trianglePressed = BUTTON_UNPRESSED;
|
||||
bool downPressed = BUTTON_UNPRESSED;
|
||||
bool leftPressed = BUTTON_UNPRESSED;
|
||||
bool rightPressed = BUTTON_UNPRESSED;
|
||||
bool upPressed = BUTTON_UNPRESSED;
|
||||
bool l1Pressed = BUTTON_UNPRESSED;
|
||||
bool l2Pressed = BUTTON_UNPRESSED;
|
||||
bool r1Pressed = BUTTON_UNPRESSED;
|
||||
bool r2Pressed = BUTTON_UNPRESSED;
|
||||
|
||||
// Analog Vectors
|
||||
// max left/up : 0
|
||||
// neutral : 127
|
||||
// max right/down : 255
|
||||
std::vector<int> GetAnalogVectors(int port) const;
|
||||
// max left/up : 0
|
||||
// neutral : 127
|
||||
// max right/down : 255
|
||||
void SetAnalogVectors(int port, std::vector<int> vector);
|
||||
/// Normal (un)pressed buttons
|
||||
bool select = BUTTON_UNPRESSED;
|
||||
bool start = BUTTON_UNPRESSED;
|
||||
bool l3 = BUTTON_UNPRESSED;
|
||||
bool r3 = BUTTON_UNPRESSED;
|
||||
|
||||
/// Analog Sticks - 0-255 (127 center)
|
||||
u8 leftAnalogX = ANALOG_VECTOR_CENTER_POS;
|
||||
u8 leftAnalogY = ANALOG_VECTOR_CENTER_POS;
|
||||
u8 rightAnalogX = ANALOG_VECTOR_CENTER_POS;
|
||||
u8 rightAnalogY = ANALOG_VECTOR_CENTER_POS;
|
||||
|
||||
// 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();
|
||||
|
||||
private:
|
||||
void SetNormalButton(int port, PadData_NormalButton button, int pressure);
|
||||
int GetNormalButton(int port, PadData_NormalButton button) const;
|
||||
void GetKeyBit(wxByte keybit[2], PadData_NormalButton button) const;
|
||||
int GetPressureByte(PadData_NormalButton button) const;
|
||||
struct ButtonResolver
|
||||
{
|
||||
u8 buttonBitmask;
|
||||
};
|
||||
|
||||
void SetAnalogVector(int port, PadData_AnalogVector vector, int val);
|
||||
int GetAnalogVector(int port, PadData_AnalogVector vector) const;
|
||||
int GetAnalogVectorByte(PadData_AnalogVector vector) const;
|
||||
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);
|
||||
|
||||
wxString RawPadBytesToString(int start, int end);
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2019 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "RecordingInputManager.h"
|
||||
#include "InputRecording.h"
|
||||
|
||||
|
||||
#ifndef DISABLE_RECORDING
|
||||
RecordingInputManager g_RecordingInput;
|
||||
|
||||
RecordingInputManager::RecordingInputManager()
|
||||
{
|
||||
for (u8 i = 0; i < 2; i++)
|
||||
{
|
||||
virtualPad[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RecordingInputManager::ControllerInterrupt(u8 & data, u8 & port, u16 & BufCount, u8 buf[])
|
||||
{
|
||||
|
||||
if (virtualPad[port])
|
||||
{
|
||||
int bufIndex = BufCount - 3;
|
||||
// first two bytes have nothing of interest in the buffer
|
||||
// already handled by InputRecording.cpp
|
||||
if (BufCount < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Normal keys
|
||||
// We want to perform an OR, but, since 255 means that no button is pressed and 0 that every button is pressed (and by De Morgan's Laws), we execute an AND.
|
||||
if (BufCount <= 4)
|
||||
{
|
||||
buf[BufCount] = buf[BufCount] & pad.buf[port][bufIndex];
|
||||
}
|
||||
// Analog keys (! overrides !)
|
||||
else if ((BufCount > 4 && BufCount <= 6) && pad.buf[port][bufIndex] != 127)
|
||||
{
|
||||
buf[BufCount] = pad.buf[port][bufIndex];
|
||||
}
|
||||
// Pressure sensitivity bytes
|
||||
else if (BufCount > 6)
|
||||
{
|
||||
buf[BufCount] = pad.buf[port][bufIndex];
|
||||
}
|
||||
|
||||
// Updating movie file
|
||||
g_InputRecording.ControllerInterrupt(data, port, BufCount, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void RecordingInputManager::SetButtonState(int port, PadData_NormalButton button, int pressure)
|
||||
{
|
||||
std::vector<int> buttons = pad.GetNormalButtons(port);
|
||||
buttons[button] = pressure;
|
||||
pad.SetNormalButtons(port, buttons);
|
||||
}
|
||||
|
||||
void RecordingInputManager::UpdateAnalog(int port, PadData_AnalogVector vector, int value)
|
||||
{
|
||||
std::vector<int> vectors = pad.GetAnalogVectors(port);
|
||||
vectors[vector] = value;
|
||||
pad.SetAnalogVectors(port, vectors);
|
||||
}
|
||||
|
||||
void RecordingInputManager::SetVirtualPadReading(int port, bool read)
|
||||
{
|
||||
virtualPad[port] = read;
|
||||
}
|
||||
#endif
|
|
@ -1,402 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2019 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include "Recording/VirtualPad.h"
|
||||
#include "Recording/RecordingInputManager.h"
|
||||
|
||||
#ifndef DISABLE_RECORDING
|
||||
wxBEGIN_EVENT_TABLE(VirtualPad, wxFrame)
|
||||
EVT_CLOSE(VirtualPad::OnClose)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
// TODO - Problems / Potential improvements:
|
||||
// - The UI doesn't update to manual controller inputs and actually overrides the controller when opened (easily noticable with analog stick)
|
||||
// - This is less than ideal, but it's going to take a rather large / focused refactor, in it's current state the virtual pad does what it needs to do (precise inputs, frame by frame)
|
||||
VirtualPad::VirtualPad(wxWindow* parent, wxWindowID id, const wxString& title, int controllerPort, const wxPoint& pos, const wxSize& size, long style) :
|
||||
wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE)
|
||||
{
|
||||
// Define components
|
||||
SetSize(wxSize(1000, 700));
|
||||
l2Button = new wxToggleButton(this, wxID_ANY, wxT("L2"));
|
||||
l2ButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
l1Button = new wxToggleButton(this, wxID_ANY, wxT("L1"));
|
||||
l1ButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
r2Button = new wxToggleButton(this, wxID_ANY, wxT("R2"));
|
||||
r2ButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
r1Button = new wxToggleButton(this, wxID_ANY, wxT("R1"));
|
||||
r1ButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
upButton = new wxToggleButton(this, wxID_ANY, wxT("Up"));
|
||||
upButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
leftButton = new wxToggleButton(this, wxID_ANY, wxT("Left"));
|
||||
leftButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
rightButton = new wxToggleButton(this, wxID_ANY, wxT("Right"));
|
||||
rightButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
downButton = new wxToggleButton(this, wxID_ANY, wxT("Down"));
|
||||
downButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
selectButton = new wxToggleButton(this, wxID_ANY, wxT("Select"));
|
||||
startButton = new wxToggleButton(this, wxID_ANY, wxT("Start"));
|
||||
triangleButton = new wxToggleButton(this, wxID_ANY, wxT("Triangle"));
|
||||
triangleButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
squareButton = new wxToggleButton(this, wxID_ANY, wxT("Square"));
|
||||
squareButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
circleButton = new wxToggleButton(this, wxID_ANY, wxT("Circle"));
|
||||
circleButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
crossButton = new wxToggleButton(this, wxID_ANY, wxT("Cross"));
|
||||
crossButtonPressure = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 255);
|
||||
leftAnalogXVal = new wxSlider(this, wxID_ANY, 0, -127, 127);
|
||||
leftAnalogXValPrecise = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -127, 128);
|
||||
l3Button = new wxToggleButton(this, wxID_ANY, wxT("L3"));
|
||||
leftAnalogYVal = new wxSlider(this, wxID_ANY, 0, -127, 127, wxDefaultPosition, wxDefaultSize, wxSL_VERTICAL);
|
||||
leftAnalogYValPrecise = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -127, 128);
|
||||
rightAnalogXVal = new wxSlider(this, wxID_ANY, 0, -127, 127);
|
||||
rightAnalogXValPrecise = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -127, 128);
|
||||
r3Button = new wxToggleButton(this, wxID_ANY, wxT("R3"));
|
||||
rightAnalogYVal = new wxSlider(this, wxID_ANY, 0, -127, 127, wxDefaultPosition, wxDefaultSize, wxSL_VERTICAL);
|
||||
rightAnalogYValPrecise = new wxSpinCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -127, 128);
|
||||
|
||||
// Initialize class members
|
||||
VirtualPad::controllerPort = controllerPort;
|
||||
|
||||
// NOTE: Order MATTERS, these match enum defined in PadData.h
|
||||
wxToggleButton* tempButtons[16] = {
|
||||
// Pressure sensitive buttons
|
||||
upButton, rightButton, leftButton, downButton,
|
||||
crossButton, circleButton, squareButton, triangleButton,
|
||||
l1Button, l2Button, r1Button, r2Button,
|
||||
// Non-pressure sensitive buttons
|
||||
l3Button, r3Button,
|
||||
selectButton, startButton};
|
||||
std::copy(std::begin(tempButtons), std::end(tempButtons), std::begin(buttons));
|
||||
|
||||
// NOTE: Order MATTERS, these match enum defined in PadData.h
|
||||
wxSpinCtrl* tempPressureButtons[16] = {
|
||||
// Pressure sensitive buttons
|
||||
upButtonPressure, rightButtonPressure, leftButtonPressure, downButtonPressure,
|
||||
crossButtonPressure, circleButtonPressure, squareButtonPressure, triangleButtonPressure,
|
||||
l1ButtonPressure, l2ButtonPressure, r1ButtonPressure, r2ButtonPressure};
|
||||
std::copy(std::begin(tempPressureButtons), std::end(tempPressureButtons), std::begin(buttonsPressure));
|
||||
|
||||
// NOTE: Order MATTERS, these match enum defined in PadData.h
|
||||
wxSlider* tempAnalogSliders[4] = { leftAnalogXVal, leftAnalogYVal, rightAnalogXVal, rightAnalogYVal };
|
||||
std::copy(std::begin(tempAnalogSliders), std::end(tempAnalogSliders), std::begin(analogSliders));
|
||||
|
||||
// NOTE: Order MATTERS, these match enum defined in PadData.h
|
||||
wxSpinCtrl* tempAnalogVals[4] = { leftAnalogXValPrecise, leftAnalogYValPrecise, rightAnalogXValPrecise, rightAnalogYValPrecise };
|
||||
std::copy(std::begin(tempAnalogVals), std::end(tempAnalogVals), std::begin(analogVals));
|
||||
|
||||
// Setup event bindings
|
||||
for (int i = 0; i < buttonsLength; i++)
|
||||
{
|
||||
(*buttons[i]).Bind(wxEVT_TOGGLEBUTTON, &VirtualPad::OnButtonPress, this);
|
||||
}
|
||||
for (int i = 0; i < buttonsPressureLength; i++)
|
||||
{
|
||||
(*buttonsPressure[i]).Bind(wxEVT_SPINCTRL, &VirtualPad::OnPressureChange, this);
|
||||
}
|
||||
for (int i = 0; i < analogSlidersLength; i++)
|
||||
{
|
||||
(*analogSliders[i]).Bind(wxEVT_SLIDER, &VirtualPad::OnAnalogSliderChange, this);
|
||||
}
|
||||
for (int i = 0; i < analogValsLength; i++)
|
||||
{
|
||||
(*analogVals[i]).Bind(wxEVT_SPINCTRL, &VirtualPad::OnAnalogValChange, this);
|
||||
}
|
||||
|
||||
// Finalize layout
|
||||
SetProperties();
|
||||
DoLayout();
|
||||
}
|
||||
|
||||
|
||||
void VirtualPad::SetProperties()
|
||||
{
|
||||
if (controllerPort == 0)
|
||||
{
|
||||
SetTitle(wxT("Virtual Pad - Port 1"));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTitle(wxT("Virtual Pad - Port 2"));
|
||||
}
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
}
|
||||
|
||||
bool VirtualPad::Show(bool show)
|
||||
{
|
||||
if (!wxFrame::Show(show))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (show)
|
||||
{
|
||||
g_RecordingInput.SetVirtualPadReading(controllerPort, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void VirtualPad::OnClose(wxCloseEvent & event)
|
||||
{
|
||||
g_RecordingInput.SetVirtualPadReading(controllerPort, false);
|
||||
Hide();
|
||||
}
|
||||
|
||||
void VirtualPad::OnButtonPress(wxCommandEvent & event)
|
||||
{
|
||||
wxToggleButton* pressedButton = (wxToggleButton*) event.GetEventObject();
|
||||
int buttonId = -1;
|
||||
for (int i = 0; i < buttonsLength; i++)
|
||||
{
|
||||
if (pressedButton == buttons[i])
|
||||
{
|
||||
buttonId = i;
|
||||
}
|
||||
}
|
||||
if (buttonId != -1)
|
||||
{
|
||||
u8 pressure = 0;
|
||||
if (event.IsChecked())
|
||||
{
|
||||
if (buttonId < 12)
|
||||
{
|
||||
pressure = buttonsPressure[buttonId]->GetValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
pressure = 255;
|
||||
}
|
||||
}
|
||||
g_RecordingInput.SetButtonState(controllerPort, PadData_NormalButton(buttonId), pressure);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualPad::OnPressureChange(wxSpinEvent & event)
|
||||
{
|
||||
wxSpinCtrl* updatedSpinner = (wxSpinCtrl*) event.GetEventObject();
|
||||
int spinnerId = -1;
|
||||
for (int i = 0; i < buttonsPressureLength; i++)
|
||||
{
|
||||
if (updatedSpinner == buttonsPressure[i])
|
||||
{
|
||||
spinnerId = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (spinnerId != -1)
|
||||
{
|
||||
u8 pressure = 0;
|
||||
if (event.IsChecked())
|
||||
{
|
||||
pressure = buttonsPressure[spinnerId]->GetValue();
|
||||
}
|
||||
g_RecordingInput.SetButtonState(controllerPort, PadData_NormalButton(spinnerId), pressure);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualPad::OnAnalogSliderChange(wxCommandEvent & event)
|
||||
{
|
||||
wxSlider* movedSlider = (wxSlider*) event.GetEventObject();
|
||||
int sliderId = -1;
|
||||
for (int i = 0; i < analogSlidersLength; i++)
|
||||
{
|
||||
if (movedSlider == analogSliders[i])
|
||||
{
|
||||
sliderId = i;
|
||||
}
|
||||
}
|
||||
if (sliderId != -1)
|
||||
{
|
||||
if (sliderId % 2 == 0)
|
||||
{
|
||||
analogVals[sliderId]->SetValue(event.GetInt());
|
||||
}
|
||||
else
|
||||
{
|
||||
analogVals[sliderId]->SetValue(event.GetInt() * -1);
|
||||
}
|
||||
|
||||
g_RecordingInput.UpdateAnalog(controllerPort, PadData_AnalogVector(sliderId), event.GetInt() + 127);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualPad::OnAnalogValChange(wxSpinEvent & event)
|
||||
{
|
||||
wxSpinCtrl* updatedSpinner = (wxSpinCtrl*)event.GetEventObject();
|
||||
int spinnerId = -1;
|
||||
for (int i = 0; i < analogValsLength; i++)
|
||||
{
|
||||
if (updatedSpinner == analogVals[i])
|
||||
{
|
||||
spinnerId = i;
|
||||
}
|
||||
}
|
||||
if (spinnerId != -1)
|
||||
{
|
||||
analogVals[spinnerId]->SetValue(event.GetInt());
|
||||
g_RecordingInput.UpdateAnalog(controllerPort, PadData_AnalogVector(spinnerId), event.GetInt() + 127);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualPad::DoLayout()
|
||||
{
|
||||
wxBoxSizer* container = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* analogSticks = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* emptySpace6 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* rightAnalogContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* rightAnalog = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* rightAnalogYContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* rightAnalogY = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* rightAnalogButtonAndGUI = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* rightAnalogX = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* emptySpace5 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* leftAnalogContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* leftAnalog = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* leftAnalogYContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* leftAnalogY = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* leftAnalogButtonAndGUI = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* leftAnalogX = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* emptySpace4 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* faceButtonRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxGridSizer* faceButtons = new wxGridSizer(0, 3, 0, 0);
|
||||
wxBoxSizer* cross = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* circle = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* square = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* triangle = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* middleOfController = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* emptySpace8 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* startAndSelect = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* emptySpace9 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* emptySpace7 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxGridSizer* dPad = new wxGridSizer(0, 3, 0, 0);
|
||||
wxBoxSizer* dPadDown = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* dPadRight = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* dPadLeft = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* dPadUp = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* shoulderButtons = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* emptySpace3 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* rightShoulderButtons = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* r1ButtonRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* r2ButtonRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* emptySpace2 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* leftShoulderButtons = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* l1ButtonRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* l2ButtonRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* emptySpace1 = new wxBoxSizer(wxVERTICAL);
|
||||
emptySpace1->Add(0, 0, 0, 0, 0);
|
||||
shoulderButtons->Add(emptySpace1, 2, wxEXPAND, 0);
|
||||
l2ButtonRow->Add(l2Button, 0, wxEXPAND, 0);
|
||||
l2ButtonRow->Add(l2ButtonPressure, 0, wxEXPAND, 0);
|
||||
leftShoulderButtons->Add(l2ButtonRow, 1, wxEXPAND, 0);
|
||||
l1ButtonRow->Add(l1Button, 0, wxEXPAND, 0);
|
||||
l1ButtonRow->Add(l1ButtonPressure, 0, wxEXPAND, 0);
|
||||
leftShoulderButtons->Add(l1ButtonRow, 1, wxEXPAND, 0);
|
||||
shoulderButtons->Add(leftShoulderButtons, 5, wxEXPAND, 0);
|
||||
emptySpace2->Add(0, 0, 0, 0, 0);
|
||||
shoulderButtons->Add(emptySpace2, 13, wxEXPAND, 0);
|
||||
r2ButtonRow->Add(r2Button, 0, wxEXPAND, 0);
|
||||
r2ButtonRow->Add(r2ButtonPressure, 0, wxEXPAND, 0);
|
||||
rightShoulderButtons->Add(r2ButtonRow, 1, wxEXPAND, 0);
|
||||
r1ButtonRow->Add(r1Button, 0, wxEXPAND, 0);
|
||||
r1ButtonRow->Add(r1ButtonPressure, 0, wxEXPAND, 0);
|
||||
rightShoulderButtons->Add(r1ButtonRow, 1, wxEXPAND, 0);
|
||||
shoulderButtons->Add(rightShoulderButtons, 5, wxEXPAND, 0);
|
||||
emptySpace3->Add(0, 0, 0, 0, 0);
|
||||
shoulderButtons->Add(emptySpace3, 2, wxEXPAND, 0);
|
||||
container->Add(shoulderButtons, 1, wxBOTTOM | wxEXPAND | wxTOP, 3);
|
||||
dPad->Add(0, 0, 0, 0, 0);
|
||||
dPadUp->Add(upButton, 0, wxEXPAND, 0);
|
||||
dPadUp->Add(upButtonPressure, 0, wxEXPAND, 0);
|
||||
dPad->Add(dPadUp, 1, wxEXPAND, 0);
|
||||
dPad->Add(0, 0, 0, 0, 0);
|
||||
dPadLeft->Add(leftButton, 0, wxEXPAND, 0);
|
||||
dPadLeft->Add(leftButtonPressure, 0, wxEXPAND, 0);
|
||||
dPad->Add(dPadLeft, 1, wxEXPAND, 0);
|
||||
dPad->Add(0, 0, 0, 0, 0);
|
||||
dPadRight->Add(rightButton, 0, wxEXPAND, 0);
|
||||
dPadRight->Add(rightButtonPressure, 0, wxEXPAND, 0);
|
||||
dPad->Add(dPadRight, 1, wxEXPAND, 0);
|
||||
dPad->Add(0, 0, 0, 0, 0);
|
||||
dPadDown->Add(downButton, 0, wxEXPAND, 0);
|
||||
dPadDown->Add(downButtonPressure, 0, wxEXPAND, 0);
|
||||
dPad->Add(dPadDown, 1, wxEXPAND, 0);
|
||||
dPad->Add(0, 0, 0, 0, 0);
|
||||
faceButtonRow->Add(dPad, 9, wxEXPAND | wxLEFT | wxRIGHT, 3);
|
||||
emptySpace7->Add(0, 0, 0, 0, 0);
|
||||
middleOfController->Add(emptySpace7, 1, wxEXPAND, 0);
|
||||
startAndSelect->Add(selectButton, 0, 0, 0);
|
||||
emptySpace9->Add(0, 0, 0, 0, 0);
|
||||
startAndSelect->Add(emptySpace9, 1, wxEXPAND, 0);
|
||||
startAndSelect->Add(startButton, 0, 0, 0);
|
||||
middleOfController->Add(startAndSelect, 1, wxEXPAND, 0);
|
||||
emptySpace8->Add(0, 0, 0, 0, 0);
|
||||
middleOfController->Add(emptySpace8, 1, wxEXPAND, 0);
|
||||
faceButtonRow->Add(middleOfController, 8, wxEXPAND | wxLEFT | wxRIGHT, 3);
|
||||
faceButtons->Add(0, 0, 0, 0, 0);
|
||||
triangle->Add(triangleButton, 0, wxEXPAND, 0);
|
||||
triangle->Add(triangleButtonPressure, 0, wxEXPAND, 0);
|
||||
faceButtons->Add(triangle, 1, wxEXPAND, 0);
|
||||
faceButtons->Add(0, 0, 0, 0, 0);
|
||||
square->Add(squareButton, 0, wxEXPAND, 0);
|
||||
square->Add(squareButtonPressure, 0, wxEXPAND, 0);
|
||||
faceButtons->Add(square, 1, wxEXPAND, 0);
|
||||
faceButtons->Add(0, 0, 0, 0, 0);
|
||||
circle->Add(circleButton, 0, wxEXPAND, 0);
|
||||
circle->Add(circleButtonPressure, 0, wxEXPAND, 0);
|
||||
faceButtons->Add(circle, 1, wxEXPAND, 0);
|
||||
faceButtons->Add(0, 0, 0, 0, 0);
|
||||
cross->Add(crossButton, 0, wxEXPAND, 0);
|
||||
cross->Add(crossButtonPressure, 0, wxEXPAND, 0);
|
||||
faceButtons->Add(cross, 1, wxEXPAND, 0);
|
||||
faceButtons->Add(0, 0, 0, 0, 0);
|
||||
faceButtonRow->Add(faceButtons, 9, wxEXPAND | wxLEFT | wxRIGHT, 3);
|
||||
container->Add(faceButtonRow, 4, wxBOTTOM | wxEXPAND | wxTOP, 3);
|
||||
emptySpace4->Add(0, 0, 0, 0, 0);
|
||||
analogSticks->Add(emptySpace4, 6, wxEXPAND, 0);
|
||||
leftAnalogX->Add(leftAnalogXVal, 1, wxALL | wxEXPAND, 0);
|
||||
leftAnalogX->Add(leftAnalogXValPrecise, 0, wxEXPAND, 0);
|
||||
leftAnalog->Add(leftAnalogX, 1, wxEXPAND, 0);
|
||||
leftAnalogButtonAndGUI->Add(0, 0, 0, 0, 0);
|
||||
leftAnalogButtonAndGUI->Add(l3Button, 0, wxALIGN_CENTER, 0);
|
||||
leftAnalogYContainer->Add(leftAnalogButtonAndGUI, 1, wxEXPAND, 0);
|
||||
leftAnalogY->Add(leftAnalogYVal, 1, wxALIGN_RIGHT, 0);
|
||||
leftAnalogY->Add(leftAnalogYValPrecise, 0, wxALIGN_RIGHT, 0);
|
||||
leftAnalogYContainer->Add(leftAnalogY, 1, wxEXPAND, 0);
|
||||
leftAnalog->Add(leftAnalogYContainer, 5, wxEXPAND, 0);
|
||||
leftAnalogContainer->Add(leftAnalog, 1, wxEXPAND, 0);
|
||||
analogSticks->Add(leftAnalogContainer, 6, wxEXPAND, 0);
|
||||
emptySpace5->Add(0, 0, 0, 0, 0);
|
||||
analogSticks->Add(emptySpace5, 3, wxEXPAND, 0);
|
||||
rightAnalogX->Add(rightAnalogXVal, 1, wxEXPAND, 0);
|
||||
rightAnalogX->Add(rightAnalogXValPrecise, 0, wxEXPAND, 0);
|
||||
rightAnalog->Add(rightAnalogX, 1, wxEXPAND, 0);
|
||||
rightAnalogButtonAndGUI->Add(0, 0, 0, 0, 0);
|
||||
rightAnalogButtonAndGUI->Add(r3Button, 0, wxALIGN_CENTER, 0);
|
||||
rightAnalogYContainer->Add(rightAnalogButtonAndGUI, 1, wxEXPAND, 0);
|
||||
rightAnalogY->Add(rightAnalogYVal, 1, wxALIGN_RIGHT, 0);
|
||||
rightAnalogY->Add(rightAnalogYValPrecise, 0, wxALIGN_RIGHT | wxEXPAND, 0);
|
||||
rightAnalogYContainer->Add(rightAnalogY, 1, wxEXPAND, 0);
|
||||
rightAnalog->Add(rightAnalogYContainer, 5, wxEXPAND, 0);
|
||||
rightAnalogContainer->Add(rightAnalog, 1, wxEXPAND, 0);
|
||||
analogSticks->Add(rightAnalogContainer, 6, wxEXPAND, 0);
|
||||
emptySpace6->Add(0, 0, 0, 0, 0);
|
||||
analogSticks->Add(emptySpace6, 6, wxEXPAND, 0);
|
||||
container->Add(analogSticks, 3, wxBOTTOM | wxEXPAND | wxTOP, 3);
|
||||
SetSizer(container);
|
||||
Layout();
|
||||
}
|
||||
#endif
|
|
@ -1,94 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2019 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/tglbtn.h>
|
||||
#include <wx/spinctrl.h>
|
||||
|
||||
#include "Recording/PadData.h"
|
||||
|
||||
#ifndef DISABLE_RECORDING
|
||||
class VirtualPad : public wxFrame
|
||||
{
|
||||
public:
|
||||
VirtualPad(wxWindow* parent, wxWindowID id, const wxString& title, int controllerPort, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE);
|
||||
|
||||
bool Show(bool show = true) override;
|
||||
|
||||
private:
|
||||
void SetProperties();
|
||||
void DoLayout();
|
||||
|
||||
int controllerPort;
|
||||
|
||||
wxToggleButton* l2Button;
|
||||
wxSpinCtrl* l2ButtonPressure;
|
||||
wxToggleButton* l1Button;
|
||||
wxSpinCtrl* l1ButtonPressure;
|
||||
wxToggleButton* r2Button;
|
||||
wxSpinCtrl* r2ButtonPressure;
|
||||
wxToggleButton* r1Button;
|
||||
wxSpinCtrl* r1ButtonPressure;
|
||||
wxToggleButton* upButton;
|
||||
wxSpinCtrl* upButtonPressure;
|
||||
wxToggleButton* leftButton;
|
||||
wxSpinCtrl* leftButtonPressure;
|
||||
wxToggleButton* rightButton;
|
||||
wxSpinCtrl* rightButtonPressure;
|
||||
wxToggleButton* downButton;
|
||||
wxSpinCtrl* downButtonPressure;
|
||||
wxToggleButton* startButton;
|
||||
wxToggleButton* selectButton;
|
||||
wxToggleButton* triangleButton;
|
||||
wxSpinCtrl* triangleButtonPressure;
|
||||
wxToggleButton* squareButton;
|
||||
wxSpinCtrl* squareButtonPressure;
|
||||
wxToggleButton* circleButton;
|
||||
wxSpinCtrl* circleButtonPressure;
|
||||
wxToggleButton* crossButton;
|
||||
wxSpinCtrl* crossButtonPressure;
|
||||
wxSlider* leftAnalogXVal;
|
||||
wxSpinCtrl* leftAnalogXValPrecise;
|
||||
wxToggleButton* l3Button;
|
||||
wxSlider* leftAnalogYVal;
|
||||
wxSpinCtrl* leftAnalogYValPrecise;
|
||||
wxSlider* rightAnalogXVal;
|
||||
wxSpinCtrl* rightAnalogXValPrecise;
|
||||
wxToggleButton* r3Button;
|
||||
wxSlider* rightAnalogYVal;
|
||||
wxSpinCtrl* rightAnalogYValPrecise;
|
||||
|
||||
wxToggleButton* buttons[16];
|
||||
int buttonsLength = 16;
|
||||
wxSpinCtrl* buttonsPressure[12];
|
||||
int buttonsPressureLength = 12;
|
||||
wxSlider* analogSliders[4];
|
||||
int analogSlidersLength = 4;
|
||||
wxSpinCtrl* analogVals[4];
|
||||
int analogValsLength = 4;
|
||||
|
||||
void OnClose(wxCloseEvent &event);
|
||||
void OnButtonPress(wxCommandEvent &event);
|
||||
void OnPressureChange(wxSpinEvent &event);
|
||||
void OnAnalogValChange(wxSpinEvent &event);
|
||||
void OnAnalogSliderChange(wxCommandEvent &event);
|
||||
// TODO - reset button
|
||||
|
||||
protected:
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
#endif
|
Loading…
Reference in New Issue