Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for trigger buttons in tilt handling #8284

Merged
merged 3 commits into from
Dec 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ void GameSettingsScreen::CreateViews() {

#if defined(MOBILE_DEVICE)
controlsSettings->Add(new CheckBox(&g_Config.bHapticFeedback, co->T("HapticFeedback", "Haptic Feedback (vibration)")));
static const char *tiltTypes[] = { "None (Disabled)", "Analog Stick", "D-PAD", "PSP Action Buttons"};
static const char *tiltTypes[] = { "None (Disabled)", "Analog Stick", "D-PAD", "PSP Action Buttons", "L/R Trigger Buttons"};
controlsSettings->Add(new PopupMultiChoice(&g_Config.iTiltInputType, co->T("Tilt Input Type"), tiltTypes, 0, ARRAY_SIZE(tiltTypes), co->GetName(), screenManager()))->OnClick.Handle(this, &GameSettingsScreen::OnTiltTypeChange);

Choice *customizeTilt = controlsSettings->Add(new Choice(co->T("Customize tilt")));
Expand Down
15 changes: 1 addition & 14 deletions UI/NativeApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -892,20 +892,7 @@ bool NativeAxis(const AxisInput &axis) {
//now transform out current tilt to the calibrated coordinate system
Tilt trueTilt = GenTilt(baseTilt, currentTilt, g_Config.bInvertTiltX, g_Config.bInvertTiltY, g_Config.fDeadzoneRadius, xSensitivity, ySensitivity);

//now send the appropriate tilt event
switch (g_Config.iTiltInputType) {
case TILT_ANALOG:
GenerateAnalogStickEvent(trueTilt);
break;

case TILT_DPAD:
GenerateDPadEvent(trueTilt);
break;

case TILT_ACTION_BUTTON:
GenerateActionButtonEvent(trueTilt);
break;
}
TranslateTiltToInput(trueTilt);
return true;
}

Expand Down
126 changes: 74 additions & 52 deletions UI/TiltEventProcessor.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
#define _USE_MATH_DEFINES
#include <cmath>
#include "TiltEventProcessor.h"
#include "UI/TiltEventProcessor.h"
#include "Core/Config.h"
#include "Core/HLE/sceCtrl.h"
#include "math.h"
#include "base/logging.h"


using namespace TiltEventProcessor;

static u32 tiltButtonsDown = 0;
static bool tiltAnalogSet = false;

//deadzone is normalized - 0 to 1
//sensitivity controls how fast the deadzone reaches max value
inline float tiltInputCurve (float x, float deadzone, float sensitivity) {

const float factor = sensitivity * 1.0f / (1.0f - deadzone);

if (x > deadzone) {
Expand All @@ -37,7 +40,6 @@ inline float clamp(float f) {
return f;
}


Tilt TiltEventProcessor::NormalizeTilt(const Tilt &tilt){
// Normalise the accelerometer manually per-platform, to 'g'
#if defined(ANDROID) || defined(BLACKBERRY) || defined(__SYMBIAN32__)
Expand All @@ -49,8 +51,7 @@ Tilt TiltEventProcessor::NormalizeTilt(const Tilt &tilt){

return Tilt(tilt.x_ / maxX, tilt.y_ / maxY);

};

}

Tilt TiltEventProcessor::GenTilt(const Tilt &baseTilt, const Tilt &currentTilt, bool invertX, bool invertY, float deadzone, float xSensitivity, float ySensitivity) {
//first convert to the correct coordinate system
Expand All @@ -70,27 +71,48 @@ Tilt TiltEventProcessor::GenTilt(const Tilt &baseTilt, const Tilt &currentTilt,

//finally, dampen the tilt according to our curve.
return dampTilt(transformedTilt, deadzone, xSensitivity, ySensitivity);
};
}

void TiltEventProcessor::TranslateTiltToInput(const Tilt &tilt) {
switch (g_Config.iTiltInputType) {
case TILT_NULL:
break;

case TILT_ANALOG:
GenerateAnalogStickEvent(tilt);
break;

case TILT_DPAD:
GenerateDPadEvent(tilt);
break;

case TILT_ACTION_BUTTON:
GenerateActionButtonEvent(tilt);
break;

case TILT_TRIGGER_BUTTON:
GenerateTriggerButtonEvent(tilt);
break;
}
}

void TiltEventProcessor::GenerateAnalogStickEvent(const Tilt &tilt) {
__CtrlSetAnalogX(clamp(tilt.x_), CTRL_STICK_LEFT);
__CtrlSetAnalogY(clamp(tilt.y_), CTRL_STICK_LEFT);
};

tiltAnalogSet = true;
}

void TiltEventProcessor::GenerateDPadEvent(const Tilt &tilt) {
static const int dir[4] = {CTRL_RIGHT, CTRL_DOWN, CTRL_LEFT, CTRL_UP};

if (tilt.x_ == 0) {
__CtrlButtonUp(CTRL_RIGHT);
__CtrlButtonUp(CTRL_LEFT);

__CtrlButtonUp(CTRL_RIGHT | CTRL_LEFT);
tiltButtonsDown &= ~(CTRL_LEFT | CTRL_RIGHT);
}

if (tilt.y_ == 0) {
__CtrlButtonUp(CTRL_UP);
__CtrlButtonUp(CTRL_DOWN);

__CtrlButtonUp(CTRL_UP | CTRL_DOWN);
tiltButtonsDown &= ~(CTRL_UP | CTRL_DOWN);
}

if (tilt.x_ == 0 && tilt.y_ == 0) {
Expand All @@ -110,25 +132,21 @@ void TiltEventProcessor::GenerateDPadEvent(const Tilt &tilt) {
case 7: ctrlMask |= CTRL_UP | CTRL_RIGHT; break;
}

for (int i = 0; i < 4; i++) {
if (ctrlMask & dir[i]) {
__CtrlButtonDown(dir[i]);
}
}
};

__CtrlButtonDown(ctrlMask);
tiltButtonsDown |= ctrlMask;
}

void TiltEventProcessor::GenerateActionButtonEvent(const Tilt &tilt) {
static const int buttons[4] = {CTRL_CIRCLE, CTRL_CROSS, CTRL_SQUARE, CTRL_TRIANGLE};

if (tilt.x_ == 0) {
__CtrlButtonUp(CTRL_SQUARE);
__CtrlButtonUp(CTRL_CIRCLE);
__CtrlButtonUp(CTRL_SQUARE | CTRL_CIRCLE);
tiltButtonsDown &= ~(CTRL_SQUARE | CTRL_CIRCLE);
}

if (tilt.y_ == 0) {
__CtrlButtonUp(CTRL_TRIANGLE);
__CtrlButtonUp(CTRL_CROSS);
__CtrlButtonUp(CTRL_TRIANGLE | CTRL_CROSS);
tiltButtonsDown &= ~(CTRL_TRIANGLE | CTRL_CROSS);
}

if (tilt.x_ == 0 && tilt.y_ == 0) {
Expand All @@ -137,32 +155,36 @@ void TiltEventProcessor::GenerateActionButtonEvent(const Tilt &tilt) {

int direction = (int)(floorf((atan2f(tilt.y_, tilt.x_) / (2.0f * (float)M_PI) * 4.0f) + 0.5f)) & 3;
__CtrlButtonDown(buttons[direction]);
};
tiltButtonsDown |= buttons[direction];
}

void TiltEventProcessor::GenerateTriggerButtonEvent(const Tilt &tilt) {
u32 upButtons = 0;
u32 downButtons = 0;
// KISS, let's only look at X. Expect deadzone to already be applied.
if (tilt.x_ == 0.0f) {
upButtons = CTRL_LTRIGGER | CTRL_RTRIGGER;
} else if (tilt.x_ < 0.0f) {
downButtons = CTRL_LTRIGGER;
upButtons = CTRL_RTRIGGER;
} else if (tilt.x_ > 0.0f) {
downButtons = CTRL_RTRIGGER;
upButtons = CTRL_LTRIGGER;
}

__CtrlButtonUp(upButtons);
__CtrlButtonDown(downButtons);
tiltButtonsDown = (tiltButtonsDown & ~upButtons) | downButtons;
}

void TiltEventProcessor::ResetTiltEvents() {
//this is ugly, but it's needed since the entire tilt system is
//stateless. So, when a tilt option is changed, we have to reset
//the tilt.
//this scenario will take place without this:
//1) tilt is Analog based. the device is tilted. Analog controller is being moved
//2) user changes mode to D-Pad and goes back to game
//3) the event handling loop sends all events to D-Pad now.
// The analog controller doesn't know that the type of tilt input has changed.
// It keeps sending tilt events for the analog.

//D-Pad
__CtrlButtonUp(CTRL_RIGHT);
__CtrlButtonUp(CTRL_LEFT);
__CtrlButtonUp(CTRL_UP);
__CtrlButtonUp(CTRL_DOWN);

//action buttons
__CtrlButtonUp(CTRL_SQUARE);
__CtrlButtonUp(CTRL_CIRCLE);
__CtrlButtonUp(CTRL_TRIANGLE);
__CtrlButtonUp(CTRL_CROSS);

//analog
__CtrlSetAnalogX(0.0f, CTRL_STICK_LEFT);
__CtrlSetAnalogY(0.0f, CTRL_STICK_LEFT);
};
// Reset the buttons we have marked pressed.
__CtrlButtonUp(tiltButtonsDown);
tiltButtonsDown = 0;

if (tiltAnalogSet) {
__CtrlSetAnalogX(0.0f, CTRL_STICK_LEFT);
__CtrlSetAnalogY(0.0f, CTRL_STICK_LEFT);
tiltAnalogSet = false;
}
}
18 changes: 10 additions & 8 deletions UI/TiltEventProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ namespace TiltEventProcessor {
TILT_NULL = 0,
TILT_ANALOG,
TILT_DPAD,
TILT_ACTION_BUTTON
TILT_ACTION_BUTTON,
TILT_TRIGGER_BUTTON,
};


//Represents a generic Tilt event
struct Tilt{
struct Tilt {
Tilt() : x_(0), y_(0) {}
Tilt(const float x, const float y) : x_(x), y_(y) {}

float x_, y_;

Tilt () : x_(0), y_(0) {};
Tilt (const float x, const float y) : x_(x), y_(y){}
};


Expand All @@ -28,12 +28,14 @@ namespace TiltEventProcessor {
//NOTE- both base and current tilt *MUST BE NORMALIZED* by calling the NormalizeTilt() function.
Tilt GenTilt(const Tilt &baseTilt, const Tilt &currentTilt, bool invertX, bool invertY, float deadzone, float xSensitivity, float ySensitivity);

void TranslateTiltToInput(const Tilt &tilt);

//the next 3 functions generate tilt events given the current Tilt amount,
//and the deadzone radius.
//the next functions generate tilt events given the current Tilt amount,
//and the deadzone radius.
void GenerateAnalogStickEvent(const Tilt &tilt);
void GenerateDPadEvent(const Tilt &tilt);
void GenerateActionButtonEvent(const Tilt &tilt);
void GenerateActionButtonEvent(const Tilt &tilt);
void GenerateTriggerButtonEvent(const Tilt &tilt);

void ResetTiltEvents();

Expand Down