Skip to content

Commit

Permalink
Master of Puppets - SDL Dualshock 4
Browse files Browse the repository at this point in the history
  • Loading branch information
FlavioFS committed Sep 27, 2021
1 parent 6cddb90 commit a52efeb
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 26 deletions.
51 changes: 44 additions & 7 deletions ParsecSoda/SDLGamepad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ GamepadState SDLGamepad::getGamepadState()
else if (pad.sThumbRY == SDL_JOYSTICK_AXIS_MAX) pad.sThumbRY = SDL_JOYSTICK_AXIS_MIN;
else pad.sThumbRY = -pad.sThumbRY;

Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_UP, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_UP) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_DOWN, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_DOWN) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_LEFT, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_LEFT) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_RIGHT, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_RIGHT) != 0);


// =====================================================
// XInput
// =====================================================
if (isXInput)
if (type == Type::XBox)
{
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_UP, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_UP) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_DOWN, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_DOWN) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_LEFT, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_LEFT) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_RIGHT, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_RIGHT) != 0);

Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_A, SDL_JoystickGetButton(joystick, (Uint8)XInput::A) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_B, SDL_JoystickGetButton(joystick, (Uint8)XInput::B) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_X, SDL_JoystickGetButton(joystick, (Uint8)XInput::X) != 0);
Expand All @@ -59,8 +59,13 @@ GamepadState SDLGamepad::getGamepadState()
// =====================================================
// DInput
// =====================================================
else
else if (type == Type::DS)
{
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_UP, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_UP) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_DOWN, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_DOWN) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_LEFT, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_LEFT) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_RIGHT, (SDL_JoystickGetHat(joystick, 0) & SDL_HAT_RIGHT) != 0);

Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_A, SDL_JoystickGetButton(joystick, (Uint8)DInput::X) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_B, SDL_JoystickGetButton(joystick, (Uint8)DInput::Circle) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_X, SDL_JoystickGetButton(joystick, (Uint8)DInput::Square) != 0);
Expand All @@ -76,12 +81,44 @@ GamepadState SDLGamepad::getGamepadState()
pad.bLeftTrigger = (SDL_JoystickGetButton(joystick, (Uint8)DInput::L2) != 0) ? 255 : 0;
pad.bRightTrigger = (SDL_JoystickGetButton(joystick, (Uint8)DInput::R2) != 0) ? 255 : 0;
}

// =====================================================
// DS4
// =====================================================
else
{
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_UP, SDL_JoystickGetButton(joystick, (int)DS4::DUp) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_DOWN, SDL_JoystickGetButton(joystick, (int)DS4::DDown) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_LEFT, SDL_JoystickGetButton(joystick, (int)DS4::DLeft) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_DPAD_RIGHT, SDL_JoystickGetButton(joystick, (int)DS4::DRight) != 0);

Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_A, SDL_JoystickGetButton(joystick, (int)DS4::X) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_B, SDL_JoystickGetButton(joystick, (int)DS4::Circle) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_X, SDL_JoystickGetButton(joystick, (int)DS4::Square) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_Y, SDL_JoystickGetButton(joystick, (int)DS4::Triangle) != 0);

Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_LEFT_SHOULDER, SDL_JoystickGetButton(joystick, (int)DS4::L1) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_RIGHT_SHOULDER, SDL_JoystickGetButton(joystick, (int)DS4::R1) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_BACK, SDL_JoystickGetButton(joystick, (int)DS4::SELECT) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_START, SDL_JoystickGetButton(joystick, (int)DS4::START) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_LEFT_THUMB, SDL_JoystickGetButton(joystick, (int)DS4::L3) != 0);
Bitwise::setValue(&pad.wButtons, XUSB_GAMEPAD_RIGHT_THUMB, SDL_JoystickGetButton(joystick, (int)DS4::R3) != 0);

pad.bLeftTrigger = axisToByte(SDL_JoystickGetAxis(joystick, 4));
pad.bRightTrigger = axisToByte(SDL_JoystickGetAxis(joystick, 5));
}


GamepadState result;
result.state.Gamepad = pad;
return result;
}

void SDLGamepad::cycleType()
{
type = (Type)(((int)type + 1) % (int)Type::COUNT);
}


BYTE SDLGamepad::axisToByte(Sint16 axis)
{
Expand Down
33 changes: 30 additions & 3 deletions ParsecSoda/SDLGamepad.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@

#define SDL_AXIS_RANGE (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN)

enum class DS4
{
X = 0,
Circle = 1,
Square = 2,
Triangle = 3,
SELECT = 4,
START = 6,
L3 = 7,
R3 = 8,
L1 = 9,
R1 = 10,
DUp = 11,
DDown = 12,
DLeft = 13,
DRight = 14
};

enum class DInput
{
Triangle = 0,
Expand Down Expand Up @@ -41,13 +59,22 @@ enum class XInput
class SDLGamepad
{
public:
SDLGamepad(SDL_Joystick* joystick, bool isXInput = true)
: joystick(joystick), isXInput(isXInput) {}
enum class Type
{
XBox,
DS,
DS4,
COUNT
};

SDLGamepad(SDL_Joystick* joystick, Type type = Type::XBox)
: joystick(joystick), type(type) {}

GamepadState getGamepadState();
void cycleType();

SDL_Joystick* joystick;
bool isXInput;
Type type;

private:
BYTE axisToByte(Sint16 axis);
Expand Down
32 changes: 23 additions & 9 deletions ParsecSoda/Widgets/MasterOfPuppetsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,17 +167,31 @@ void MasterOfPuppetsWidget::renderMasterSDL()
ImGui::SetCursorPosX(shift1);

ImGui::PushID(i);
if (IconButton::render(
sdlGamepads[i].isXInput ? AppIcons::xinput : AppIcons::dinput,
AppColors::primary)
)

static bool isMappingBtnPressed = false;
switch (sdlGamepads[i].type)
{
sdlGamepads[i].isXInput = !sdlGamepads[i].isXInput;
case SDLGamepad::Type::XBox:
isMappingBtnPressed = IconButton::render(AppIcons::xinput, AppColors::primary);
TitleTooltipWidget::render("Button Mapping", _sdlXInputMapTooltip.c_str());
break;
case SDLGamepad::Type::DS:
isMappingBtnPressed = IconButton::render(AppIcons::dinput, AppColors::primary);
TitleTooltipWidget::render("Button Mapping", _sdlDualshockMapTooltip.c_str());
break;
case SDLGamepad::Type::DS4:
isMappingBtnPressed = IconButton::render(AppIcons::ds4, AppColors::primary);
TitleTooltipWidget::render("Button Mapping", _sdlDS4MapTooltip.c_str());
break;
default:
isMappingBtnPressed = false;
break;
}

if (isMappingBtnPressed)
{
sdlGamepads[i].cycleType();
}
TitleTooltipWidget::render(
"Button Mapping",
sdlGamepads[i].isXInput ? _sdlXInputMapTooltip.c_str() : _sdlDualshockMapTooltip.c_str()
);

ImGui::SetCursorPos(cursor);
ImGui::SetCursorPosX(shift1 + shift2);
Expand Down
23 changes: 16 additions & 7 deletions ParsecSoda/Widgets/MasterOfPuppetsWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,30 @@ class MasterOfPuppetsWidget
const string _masterTooltipOn = "Master of Puppets is pulling the strings.\n" + _masterTooltipBase;
const string _masterTooltipOff = "Click to set this gamepad as Master.\n" + _masterTooltipBase;

const string _sdlXInputMapTooltip = string() +
"Mapping type: XInput\n" +
"\n" +
"Cons:\n"
" - Only fully supports 4 slots (including Puppets).\n" +
" - XBox-like controlers above slot 4 cannot press both triggers at same time.\n" +
"\n" +
"* Click to switch to Dualshock type."
;
const string _sdlDualshockMapTooltip = string() +
"Mapping type: Dualshock\n" +
"\n" +
"Cons:\n"
" - DInput mapping treats triggers as buttons instead of axis (empty or full, no in-between).\n" +
"\n" +
"* Click to switch to XInput type."
"* Click to switch to Dualshock 4 type."
;
const string _sdlXInputMapTooltip = string() +
"Mapping type: XInput\n" +
const string _sdlDS4MapTooltip = string() +
"Mapping type: Dualshock 4\n" +
"\n" +
"Cons:\n"
" - Only fully supports 4 slots (including Puppets).\n" +
" - XBox-like controlers above slot 4 cannot press both triggers at same time.\n" +
"This is 100%% experimental, I have no idea what is going to happen.\n" +
"Hopefully, it will map correctly official DS4 gamepads connected to PC.\n" +
"Use it at your own risk.\n" +
"\n" +
"* Click to switch to Dualshock type."
"* Click to switch to XInput type."
;
};
4 changes: 4 additions & 0 deletions ParsecSoda/globals/AppIcons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ ID3D11ShaderResourceView* AppIcons::logo;
ID3D11ShaderResourceView* AppIcons::puppet;
ID3D11ShaderResourceView* AppIcons::xinput;
ID3D11ShaderResourceView* AppIcons::dinput;
ID3D11ShaderResourceView* AppIcons::ds4;
ID3D11ShaderResourceView* AppIcons::windows;
ID3D11ShaderResourceView* AppIcons::sdl;

Expand Down Expand Up @@ -114,6 +115,7 @@ Texture AppIcons::_logo;
Texture AppIcons::_puppet;
Texture AppIcons::_xinput;
Texture AppIcons::_dinput;
Texture AppIcons::_ds4;
Texture AppIcons::_windows;
Texture AppIcons::_sdl;

Expand Down Expand Up @@ -181,6 +183,7 @@ void AppIcons::init(ID3D11Device* pd3dDevice)
_puppet.loadFromFile(pd3dDevice, "./icons/puppet.png");
_xinput.loadFromFile(pd3dDevice, "./icons/xinput.png");
_dinput.loadFromFile(pd3dDevice, "./icons/dinput.png");
_ds4.loadFromFile(pd3dDevice, "./icons/ds4.png");
_windows.loadFromFile(pd3dDevice, "./icons/windows.png");
_sdl.loadFromFile(pd3dDevice, "./icons/sdl.png");

Expand Down Expand Up @@ -245,6 +248,7 @@ void AppIcons::init(ID3D11Device* pd3dDevice)
puppet = _puppet.texture;
xinput = _xinput.texture;
dinput = _dinput.texture;
ds4 = _ds4.texture;
windows = _windows.texture;
sdl = _sdl.texture;

Expand Down
2 changes: 2 additions & 0 deletions ParsecSoda/globals/AppIcons.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class AppIcons
static ID3D11ShaderResourceView* puppet;
static ID3D11ShaderResourceView* xinput;
static ID3D11ShaderResourceView* dinput;
static ID3D11ShaderResourceView* ds4;
static ID3D11ShaderResourceView* windows;
static ID3D11ShaderResourceView* sdl;

Expand Down Expand Up @@ -123,6 +124,7 @@ class AppIcons
static Texture _puppet;
static Texture _xinput;
static Texture _dinput;
static Texture _ds4;
static Texture _windows;
static Texture _sdl;

Expand Down
Binary file added ParsecSoda/icons/ds4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a52efeb

Please sign in to comment.