Skip to content

Commit

Permalink
Separate custom analog from sceCtrl
Browse files Browse the repository at this point in the history
  • Loading branch information
iota97 committed Jan 30, 2020
1 parent bd2511b commit a266ca3
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 46 deletions.
5 changes: 1 addition & 4 deletions Core/HLE/sceCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct CtrlData {
// The PSP has only one stick, but has space for more info.
// The second stick is populated for HD remasters and possibly in the PSP emulator on PS3/Vita.
u8 analog[2][2];
u8 unused[4]; // First 2 byte are used from custom right analog
u8 unused[4];
};

struct CtrlLatch {
Expand Down Expand Up @@ -321,9 +321,6 @@ void __CtrlInit()

memset(&ctrlCurrent, 0, sizeof(ctrlCurrent));
memset(ctrlCurrent.analog, CTRL_ANALOG_CENTER, sizeof(ctrlCurrent.analog));
// Set custom right analog to center
ctrlCurrent.unused[0] = CTRL_ANALOG_CENTER;
ctrlCurrent.unused[1] = CTRL_ANALOG_CENTER;
analogEnabled = false;

for (u32 i = 0; i < NUM_CTRL_BUFFERS; i++)
Expand Down
191 changes: 149 additions & 42 deletions UI/GamepadEmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "base/timeutil.h"
#include "math/math_util.h"
#include "ui/ui_context.h"
#include "Core/Util/AudioFormat.h" // for clamp_u8

static u32 GetButtonColor() {
return g_Config.iTouchButtonStyle != 0 ? 0xFFFFFF : 0xc0b080;
Expand Down Expand Up @@ -413,6 +414,115 @@ void PSPStick::Touch(const TouchInput &input) {
}

void PSPStick::ProcessTouch(float x, float y, bool down) {
if (down && centerX_ >= 0.0f) {
float inv_stick_size = 1.0f / (stick_size_ * scale_);

float dx = (x - centerX_) * inv_stick_size;
float dy = (y - centerY_) * inv_stick_size;
// Do not clamp to a circle! The PSP has nearly square range!

// Old code to clamp to a circle
// float len = sqrtf(dx * dx + dy * dy);
// if (len > 1.0f) {
// dx /= len;
// dy /= len;
//}

// Still need to clamp to a square
dx = std::min(1.0f, std::max(-1.0f, dx));
dy = std::min(1.0f, std::max(-1.0f, dy));

__CtrlSetAnalogX(dx, stick_);
__CtrlSetAnalogY(-dy, stick_);
} else {
__CtrlSetAnalogX(0.0f, stick_);
__CtrlSetAnalogY(0.0f, stick_);
}
}

PSPCustomStick::PSPCustomStick(int bgImg, int stickImg, int stickDownImg, float scale, UI::LayoutParams *layoutParams)
: GamepadView(layoutParams), dragPointerId_(-1), bgImg_(bgImg), stickImageIndex_(stickImg), stickDownImg_(stickDownImg), scale_(scale), centerX_(-1), centerY_(-1) {
stick_size_ = 50;
posX_ = clamp_u8((int)ceilf(127.5f));
posY_ = clamp_u8((int)ceilf(127.5f));
}

void PSPCustomStick::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
const AtlasImage &image = dc.Draw()->GetAtlas()->images[bgImg_];
w = image.w;
h = image.h;
}

void PSPCustomStick::Draw(UIContext &dc) {
float opacity = GetButtonOpacity();
if (opacity <= 0.0f)
return;

if (dragPointerId_ != -1 && g_Config.iTouchButtonStyle == 2) {
opacity *= 1.35f;
}

uint32_t colorBg = colorAlpha(GetButtonColor(), opacity);
uint32_t downBg = colorAlpha(0x00FFFFFF, opacity * 0.5f);
uint32_t color = colorAlpha(0x808080, opacity);

if (centerX_ < 0.0f) {
centerX_ = bounds_.centerX();
centerY_ = bounds_.centerY();
}

float stickX = centerX_;
float stickY = centerY_;

float dx, dy;
dx = (posX_ - 127.5f) / 127.5f;
dy = -(posY_ - 127.5f) / 127.5f;

dc.Draw()->DrawImage(bgImg_, stickX, stickY, 1.0f * scale_, colorBg, ALIGN_CENTER);
if (dragPointerId_ != -1 && g_Config.iTouchButtonStyle == 2 && stickDownImg_ != stickImageIndex_)
dc.Draw()->DrawImage(stickDownImg_, stickX + dx * stick_size_ * scale_, stickY - dy * stick_size_ * scale_, 1.0f * scale_, downBg, ALIGN_CENTER);
dc.Draw()->DrawImage(stickImageIndex_, stickX + dx * stick_size_ * scale_, stickY - dy * stick_size_ * scale_, 1.0f * scale_, colorBg, ALIGN_CENTER);
}

void PSPCustomStick::Touch(const TouchInput &input) {
GamepadView::Touch(input);
if (input.flags & TOUCH_RELEASE_ALL) {
dragPointerId_ = -1;
centerX_ = bounds_.centerX();
centerY_ = bounds_.centerY();
posX_ = clamp_u8((int)ceilf(127.5f));
posY_ = clamp_u8((int)ceilf(127.5f));
return;
}
if (input.flags & TOUCH_DOWN) {
if (dragPointerId_ == -1 && bounds_.Contains(input.x, input.y)) {
if (g_Config.bAutoCenterTouchAnalog) {
centerX_ = input.x;
centerY_ = input.y;
} else {
centerX_ = bounds_.centerX();
centerY_ = bounds_.centerY();
}
dragPointerId_ = input.id;
ProcessTouch(input.x, input.y, true);
}
}
if (input.flags & TOUCH_MOVE) {
if (input.id == dragPointerId_) {
ProcessTouch(input.x, input.y, true);
}
}
if (input.flags & TOUCH_UP) {
if (input.id == dragPointerId_) {
dragPointerId_ = -1;
centerX_ = bounds_.centerX();
centerY_ = bounds_.centerY();
ProcessTouch(input.x, input.y, false);
}
}
}

void PSPCustomStick::ProcessTouch(float x, float y, bool down) {
static const int button[16] = {CTRL_LTRIGGER, CTRL_RTRIGGER, CTRL_SQUARE, CTRL_TRIANGLE, CTRL_CIRCLE, CTRL_CROSS, CTRL_UP, CTRL_DOWN, CTRL_LEFT, CTRL_RIGHT, CTRL_START, CTRL_SELECT};

if (down && centerX_ >= 0.0f) {
Expand All @@ -433,53 +543,50 @@ void PSPStick::ProcessTouch(float x, float y, bool down) {
dx = std::min(1.0f, std::max(-1.0f, dx));
dy = std::min(1.0f, std::max(-1.0f, dy));

if (stick_ == 2) { // Custom right analog
if (g_Config.iRightAnalogRight != 0) {
if (dx > 0.5f)
__CtrlButtonDown(button[g_Config.iRightAnalogRight-1]);
else
__CtrlButtonUp(button[g_Config.iRightAnalogRight-1]);
}
if (g_Config.iRightAnalogLeft != 0) {
if (dx < -0.5f)
__CtrlButtonDown(button[g_Config.iRightAnalogLeft-1]);
else
__CtrlButtonUp(button[g_Config.iRightAnalogLeft-1]);
}
if (g_Config.iRightAnalogUp != 0) {
if (dy < -0.5f)
__CtrlButtonDown(button[g_Config.iRightAnalogUp-1]);
else
__CtrlButtonUp(button[g_Config.iRightAnalogUp-1]);
}
if (g_Config.iRightAnalogDown != 0) {
if (dy > 0.5f)
__CtrlButtonDown(button[g_Config.iRightAnalogDown-1]);
else
__CtrlButtonUp(button[g_Config.iRightAnalogDown-1]);
}
if (g_Config.iRightAnalogPress != 0)
__CtrlButtonDown(button[g_Config.iRightAnalogPress-1]);
if (g_Config.iRightAnalogRight != 0) {
if (dx > 0.5f)
__CtrlButtonDown(button[g_Config.iRightAnalogRight-1]);
else
__CtrlButtonUp(button[g_Config.iRightAnalogRight-1]);
}
if (g_Config.iRightAnalogLeft != 0) {
if (dx < -0.5f)
__CtrlButtonDown(button[g_Config.iRightAnalogLeft-1]);
else
__CtrlButtonUp(button[g_Config.iRightAnalogLeft-1]);
}
if (g_Config.iRightAnalogUp != 0) {
if (dy < -0.5f)
__CtrlButtonDown(button[g_Config.iRightAnalogUp-1]);
else
__CtrlButtonUp(button[g_Config.iRightAnalogUp-1]);
}
if (g_Config.iRightAnalogDown != 0) {
if (dy > 0.5f)
__CtrlButtonDown(button[g_Config.iRightAnalogDown-1]);
else
__CtrlButtonUp(button[g_Config.iRightAnalogDown-1]);
}
if (g_Config.iRightAnalogPress != 0)
__CtrlButtonDown(button[g_Config.iRightAnalogPress-1]);

posX_ = clamp_u8((int)ceilf(dx * 127.5f + 127.5f));
posY_ = clamp_u8((int)ceilf(dy * 127.5f + 127.5f));

__CtrlSetAnalogX(dx, stick_);
__CtrlSetAnalogY(-dy, stick_);
} else {
if (stick_ == 2) { // Custom right analog
if (g_Config.iRightAnalogUp != 0)
if (g_Config.iRightAnalogUp != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogUp-1]);
if (g_Config.iRightAnalogDown != 0)
if (g_Config.iRightAnalogDown != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogDown-1]);
if (g_Config.iRightAnalogLeft != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogLeft-1]);
if (g_Config.iRightAnalogRight != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogRight-1]);
if (g_Config.iRightAnalogPress != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogPress-1]);
}
if (g_Config.iRightAnalogLeft != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogLeft-1]);
if (g_Config.iRightAnalogRight != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogRight-1]);
if (g_Config.iRightAnalogPress != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogPress-1]);

__CtrlSetAnalogX(0.0f, stick_);
__CtrlSetAnalogY(0.0f, stick_);
posX_ = clamp_u8((int)ceilf(127.5f));
posY_ = clamp_u8((int)ceilf(127.5f));
}
}

Expand Down Expand Up @@ -697,7 +804,7 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) {

if (g_Config.touchRightAnalogStick.show) {
if (g_Config.bRightAnalogCustom)
root->Add(new PSPStick(stickBg, stickImage, I_STICK, 2, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick)));
root->Add(new PSPCustomStick(stickBg, stickImage, I_STICK, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick)));
else
root->Add(new PSPStick(stickBg, stickImage, I_STICK, 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick)));
}
Expand Down
24 changes: 24 additions & 0 deletions UI/GamepadEmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,30 @@ class PSPStick : public GamepadView {
float centerY_;
};

class PSPCustomStick : public GamepadView {
public:
PSPCustomStick(int bgImg, int stickImg, int stickDownImg, float scale, UI::LayoutParams *layoutParams);

void Touch(const TouchInput &input) override;
void Draw(UIContext &dc) override;
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;

private:
void ProcessTouch(float x, float y, bool down);

int dragPointerId_;
int bgImg_;
int stickImageIndex_;
int stickDownImg_;
float stick_size_;
float scale_;

float centerX_;
float centerY_;
u8 posX_;
u8 posY_;
};

//initializes the layout from Config. if a default layout does not exist,
//it sets up default values
void InitPadLayout(float xres, float yres, float globalScale = 1.15f);
Expand Down

0 comments on commit a266ca3

Please sign in to comment.