Skip to content

Commit

Permalink
Merge pull request #8284 from unknownbrackets/tilt
Browse files Browse the repository at this point in the history
Add support for trigger buttons in tilt handling
  • Loading branch information
hrydgard committed Dec 23, 2015
2 parents b66a975 + 64da0f5 commit d5219eb
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 75 deletions.
2 changes: 1 addition & 1 deletion UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,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

0 comments on commit d5219eb

Please sign in to comment.