mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-25 16:41:04 +00:00
Merge pull request #4340 from bollu/analogStickTiltControl
full tilt based analog controls
This commit is contained in:
commit
9c546b5d36
@ -1113,6 +1113,7 @@ set(NativeAppSource
|
||||
UI/MiscScreens.cpp
|
||||
UI/GameScreen.cpp
|
||||
UI/GameSettingsScreen.cpp
|
||||
UI/TiltAnalogSettingsScreen.cpp
|
||||
UI/TouchControlLayoutScreen.cpp
|
||||
UI/TouchControlVisibilityScreen.cpp
|
||||
UI/GamepadEmu.cpp
|
||||
|
@ -219,7 +219,15 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
|
||||
// control->Get("KeyMapping",iMappingMap);
|
||||
#ifdef USING_GLES2
|
||||
control->Get("AccelerometerToAnalogHoriz", &bAccelerometerToAnalogHoriz, false);
|
||||
control->Get("TiltSensitivity", &iTiltSensitivity, 100);
|
||||
|
||||
control->Get("TiltBaseX", &fTiltBaseX, 0);
|
||||
control->Get("TiltBaseY", &fTiltBaseY, 0);
|
||||
control->Get("InvertTiltX", &bInvertTiltX, false);
|
||||
control->Get("InvertTiltY", &bInvertTiltY, true);
|
||||
control->Get("TiltSensitivityX", &iTiltSensitivityX, 100);
|
||||
control->Get("TiltSensitivityY", &iTiltSensitivityY, 100);
|
||||
control->Get("DeadzoneRadius", &fDeadzoneRadius, 0.35);
|
||||
|
||||
#endif
|
||||
control->Get("TouchButtonOpacity", &iTouchButtonOpacity, 65);
|
||||
control->Get("ButtonScale", &fButtonScale, 1.15);
|
||||
@ -411,7 +419,13 @@ void Config::Save() {
|
||||
// control->Set("KeyMapping",iMappingMap);
|
||||
#ifdef USING_GLES2
|
||||
control->Set("AccelerometerToAnalogHoriz", bAccelerometerToAnalogHoriz);
|
||||
control->Set("TiltSensitivity", iTiltSensitivity);
|
||||
control->Set("TiltBaseX", fTiltBaseX);
|
||||
control->Set("TiltBaseY", fTiltBaseY);
|
||||
control->Set("InvertTiltX", bInvertTiltX);
|
||||
control->Set("InvertTiltY", bInvertTiltY);
|
||||
control->Set("TiltSensitivityX", iTiltSensitivityX);
|
||||
control->Set("TiltSensitivityY", iTiltSensitivityY);
|
||||
control->Set("DeadzoneRadius", fDeadzoneRadius);
|
||||
#endif
|
||||
control->Set("TouchButtonOpacity", iTouchButtonOpacity);
|
||||
control->Set("ButtonScale", fButtonScale);
|
||||
|
@ -110,7 +110,19 @@ public:
|
||||
int iShowFPSCounter;
|
||||
bool bShowDebugStats;
|
||||
bool bAccelerometerToAnalogHoriz;
|
||||
int iTiltSensitivity;
|
||||
|
||||
//Analog stick tilting
|
||||
//the base x and y tilt. this inclination is treated as (0,0) and the tilt input
|
||||
//considers this orientation to be equal to no movement of the analog stick.
|
||||
float fTiltBaseX, fTiltBaseY;
|
||||
//whether the x axes and y axes should invert directions (left becomes right, top becomes bottom.)
|
||||
bool bInvertTiltX, bInvertTiltY;
|
||||
//the sensitivity of the tilt in the x direction
|
||||
int iTiltSensitivityX;
|
||||
//the sensitivity of the tilt in the Y direction
|
||||
int iTiltSensitivityY;
|
||||
//the deadzone radius of the tilt
|
||||
float fDeadzoneRadius;
|
||||
|
||||
// The three tabs.
|
||||
bool bGridView1;
|
||||
|
@ -189,16 +189,20 @@ void EmuScreen::sendMessage(const char *message, const char *value) {
|
||||
}
|
||||
}
|
||||
|
||||
inline float curve1(float x) {
|
||||
const float deadzone = 0.15f;
|
||||
//tiltInputCurve implements a smooth deadzone as described here:
|
||||
//http://www.gamasutra.com/blogs/JoshSutphin/20130416/190541/Doing_Thumbstick_Dead_Zones_Right.php
|
||||
inline float tiltInputCurve(float x) {
|
||||
const float deadzone = g_Config.fDeadzoneRadius;
|
||||
const float factor = 1.0f / (1.0f - deadzone);
|
||||
|
||||
if (x > deadzone) {
|
||||
return (x - deadzone) * (x - deadzone) * factor;
|
||||
} else if (x < -0.1f) {
|
||||
} else if (x < -deadzone) {
|
||||
return -(x + deadzone) * (x + deadzone) * factor;
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline float clamp1(float x) {
|
||||
@ -468,9 +472,38 @@ void EmuScreen::update(InputState &input) {
|
||||
// TODO: Make into an axis
|
||||
#ifdef USING_GLES2
|
||||
if (g_Config.bAccelerometerToAnalogHoriz) {
|
||||
// TODO: Deadzone, etc.
|
||||
leftstick_x += clamp1(curve1(input.acc.y) * 2.0f) * g_Config.iTiltSensitivity / 100;
|
||||
|
||||
//get the "base" coordinate system which is setup by the calibration system
|
||||
float base_x = g_Config.fTiltBaseX;
|
||||
float base_y = g_Config.fTiltBaseY;
|
||||
|
||||
//convert the current input into base coordinates and normalize
|
||||
//TODO: check if all phones give values between [-50, 50]. I'm not sure how iOS works.
|
||||
float normalized_input_x = (input.acc.y - base_x) / 50.0 ;
|
||||
float normalized_input_y = (input.acc.x - base_y) / 50.0 ;
|
||||
|
||||
//TODO: need a better name for computed x and y.
|
||||
float delta_x = tiltInputCurve(normalized_input_x * 2.0 * (g_Config.iTiltSensitivityX)) ;
|
||||
|
||||
//if the invert is enabled, invert the motion
|
||||
if (g_Config.bInvertTiltX) {
|
||||
delta_x *= -1;
|
||||
}
|
||||
|
||||
float delta_y = tiltInputCurve(normalized_input_y * 2.0 * (g_Config.iTiltSensitivityY)) ;
|
||||
|
||||
if (g_Config.bInvertTiltY) {
|
||||
delta_y *= -1;
|
||||
}
|
||||
|
||||
//clamp the delta between [-1, 1]
|
||||
leftstick_x += clamp1(delta_x);
|
||||
__CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT);
|
||||
|
||||
|
||||
leftstick_y += clamp1(delta_y);
|
||||
__CtrlSetAnalogY(clamp1(leftstick_y), CTRL_STICK_LEFT);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "UI/DevScreens.h"
|
||||
#include "UI/TouchControlLayoutScreen.h"
|
||||
#include "UI/TouchControlVisibilityScreen.h"
|
||||
#include "UI/TiltAnalogSettingsScreen.h"
|
||||
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Host.h"
|
||||
@ -217,7 +218,9 @@ void GameSettingsScreen::CreateViews() {
|
||||
#ifdef USING_GLES2
|
||||
controlsSettings->Add(new CheckBox(&g_Config.bHapticFeedback, c->T("HapticFeedback", "Haptic Feedback (vibration)")));
|
||||
controlsSettings->Add(new CheckBox(&g_Config.bAccelerometerToAnalogHoriz, c->T("Tilt", "Tilt to Analog (horizontal)")));
|
||||
controlsSettings->Add(new PopupSliderChoice(&g_Config.iTiltSensitivity, 10, 200, c->T("Tilt Sensitivity"), screenManager()));
|
||||
Choice *tiltAnalog = controlsSettings->Add(new Choice(c->T("Customize tilt")));
|
||||
tiltAnalog->OnClick.Handle(this, &GameSettingsScreen::OnTiltAnalogSettings);
|
||||
tiltAnalog->SetEnabled(g_Config.bAccelerometerToAnalogHoriz);
|
||||
#endif
|
||||
controlsSettings->Add(new ItemHeader(c->T("OnScreen", "On-Screen Touch Controls")));
|
||||
controlsSettings->Add(new CheckBox(&g_Config.bShowTouchControls, c->T("OnScreen", "On-Screen Touch Controls")))->OnClick.Handle(this, &GameSettingsScreen::OnToggleTouchControls);
|
||||
@ -473,6 +476,11 @@ UI::EventReturn GameSettingsScreen::OnTouchControlLayout(UI::EventParams &e) {
|
||||
return UI::EVENT_DONE;
|
||||
};
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnTiltAnalogSettings(UI::EventParams &e){
|
||||
screenManager()->push(new TiltAnalogSettingsScreen());
|
||||
return UI::EVENT_DONE;
|
||||
};
|
||||
|
||||
void DeveloperToolsScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
root_ = new ScrollView(ORIENT_VERTICAL);
|
||||
|
@ -55,6 +55,8 @@ private:
|
||||
UI::EventReturn OnBack(UI::EventParams &e);
|
||||
UI::EventReturn OnReloadCheats(UI::EventParams &e);
|
||||
UI::EventReturn OnToggleTouchControls(UI::EventParams &e);
|
||||
UI::EventReturn OnTiltAnalogSettings(UI::EventParams &e);
|
||||
|
||||
|
||||
// Global settings handlers
|
||||
UI::EventReturn OnLanguage(UI::EventParams &e);
|
||||
|
69
UI/TiltAnalogSettingsScreen.cpp
Normal file
69
UI/TiltAnalogSettingsScreen.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "TiltAnalogSettingsScreen.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/System.h"
|
||||
#include "i18n/i18n.h"
|
||||
|
||||
TiltAnalogSettingsScreen::TiltAnalogSettingsScreen() : currentTiltX_(0), currentTiltY_(0) {};
|
||||
|
||||
void TiltAnalogSettingsScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
|
||||
I18NCategory *c = GetI18NCategory("Controls");
|
||||
|
||||
root_ = root_ = new ScrollView(ORIENT_VERTICAL);
|
||||
|
||||
LinearLayout *settings = new LinearLayout(ORIENT_VERTICAL);
|
||||
settings->SetSpacing(0);
|
||||
|
||||
|
||||
settings->Add(new ItemHeader(c->T("Invert Axes")));
|
||||
settings->Add(new CheckBox(&g_Config.bInvertTiltX, c->T("Invert Tilt along X axis")));
|
||||
settings->Add(new CheckBox(&g_Config.bInvertTiltY, c->T("Invert Tilt along Y axis")));
|
||||
|
||||
settings->Add(new ItemHeader(c->T("Sensitivity")));
|
||||
//TODO: allow values greater than 100? I'm not sure if that's needed.
|
||||
settings->Add(new PopupSliderChoice(&g_Config.iTiltSensitivityX, 0, 100, c->T("Tilt Sensitivity along X axis"), screenManager()));
|
||||
settings->Add(new PopupSliderChoice(&g_Config.iTiltSensitivityY, 0, 100, c->T("Tilt Sensitivity along Y axis"), screenManager()));
|
||||
settings->Add(new PopupSliderChoiceFloat(&g_Config.fDeadzoneRadius, 0.0, 1.0, c->T("Deadzone Radius"), screenManager()));
|
||||
|
||||
|
||||
settings->Add(new ItemHeader(c->T("Calibration")));
|
||||
InfoItem *calibrationInfo = new InfoItem("To calibrate, keep device on a flat surface and press calibrate.", "");
|
||||
settings->Add(calibrationInfo);
|
||||
|
||||
Choice *calibrate = new Choice(c->T("Calibrate D-Pad"));
|
||||
calibrate->OnClick.Handle(this, &TiltAnalogSettingsScreen::OnCalibrate);
|
||||
settings->Add(calibrate);
|
||||
|
||||
root_->Add(settings);
|
||||
};
|
||||
|
||||
void TiltAnalogSettingsScreen::update(InputState &input) {
|
||||
UIScreen::update(input);
|
||||
//I'm not sure why y is x and x is y. i's probably because of the orientation
|
||||
//of the screen (the x and y are in portrait coordinates). once portrait and
|
||||
//reverse-landscape is enabled, this will probably have to change.
|
||||
//If needed, we can add a "swap x and y" option.
|
||||
currentTiltX_ = input.acc.y;
|
||||
currentTiltY_ = input.acc.x;
|
||||
};
|
||||
|
||||
|
||||
UI::EventReturn TiltAnalogSettingsScreen::OnBack(UI::EventParams &e) {
|
||||
if (PSP_IsInited()) {
|
||||
screenManager()->finishDialog(this, DR_CANCEL);
|
||||
} else {
|
||||
screenManager()->finishDialog(this, DR_OK);
|
||||
}
|
||||
|
||||
return UI::EVENT_DONE;
|
||||
};
|
||||
|
||||
|
||||
UI::EventReturn TiltAnalogSettingsScreen::OnCalibrate(UI::EventParams &e) {
|
||||
g_Config.fTiltBaseX = currentTiltX_;
|
||||
g_Config.fTiltBaseY = currentTiltY_;
|
||||
|
||||
return UI::EVENT_DONE;
|
||||
};
|
||||
|
36
UI/TiltAnalogSettingsScreen.h
Normal file
36
UI/TiltAnalogSettingsScreen.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2013- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/functional.h"
|
||||
#include "ui/view.h"
|
||||
#include "MiscScreens.h"
|
||||
|
||||
class TiltAnalogSettingsScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
TiltAnalogSettingsScreen();
|
||||
|
||||
virtual void CreateViews();
|
||||
virtual void update(InputState &input);
|
||||
protected:
|
||||
virtual UI::EventReturn OnBack(UI::EventParams &e);
|
||||
private:
|
||||
UI::EventReturn OnCalibrate(UI::EventParams &e);
|
||||
float currentTiltX_, currentTiltY_;
|
||||
};
|
||||
|
@ -110,6 +110,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/UI/GameScreen.cpp \
|
||||
$(SRC)/UI/ControlMappingScreen.cpp \
|
||||
$(SRC)/UI/GameSettingsScreen.cpp \
|
||||
$(SRC)/UI/TiltAnalogSettingsScreen.cpp \
|
||||
$(SRC)/UI/TouchControlLayoutScreen.cpp \
|
||||
$(SRC)/UI/TouchControlVisibilityScreen.cpp \
|
||||
$(SRC)/UI/CwCheatScreen.cpp \
|
||||
|
Loading…
x
Reference in New Issue
Block a user