2012-11-01 16:19:01 +01:00
// Copyright (c) 2012- 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
2012-11-04 23:01:49 +01:00
// the Free Software Foundation, version 2.0 or later versions.
2012-11-01 16:19:01 +01:00
// 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/.
2015-12-26 11:31:37 -08:00
# include <algorithm>
2020-08-15 20:53:08 +02:00
2020-10-01 13:05:04 +02:00
# include "Common/Data/Color/RGBAUtil.h"
2021-02-21 16:38:02 -08:00
# include "Common/Data/Text/I18n.h"
2020-10-04 10:10:55 +02:00
# include "Common/System/Display.h"
2020-10-04 10:30:18 +02:00
# include "Common/System/System.h"
2020-10-04 23:24:14 +02:00
# include "Common/Render/TextureAtlas.h"
2020-10-04 00:25:21 +02:00
# include "Common/Math/math_util.h"
2020-10-04 20:48:47 +02:00
# include "Common/UI/Context.h"
2013-09-17 00:48:14 -04:00
2020-08-15 20:53:08 +02:00
# include "Common/Log.h"
# include "Common/TimeUtil.h"
# include "Core/Config.h"
# include "Core/Core.h"
# include "Core/System.h"
# include "Core/HLE/sceCtrl.h"
2021-03-04 10:37:35 +01:00
# include "Core/ControlMapper.h"
2020-08-15 20:53:08 +02:00
# include "UI/GamepadEmu.h"
2013-12-10 23:19:37 +01:00
static u32 GetButtonColor ( ) {
2018-09-30 16:48:02 -07:00
return g_Config . iTouchButtonStyle ! = 0 ? 0xFFFFFF : 0xc0b080 ;
2013-12-10 23:19:37 +01:00
}
2021-02-21 16:38:02 -08:00
GamepadView : : GamepadView ( const char * key , UI : : LayoutParams * layoutParams ) : UI : : View ( layoutParams ) , key_ ( key ) {
2016-01-17 19:23:28 +01:00
lastFrameTime_ = time_now_d ( ) ;
}
2015-12-20 12:40:47 -08:00
void GamepadView : : Touch ( const TouchInput & input ) {
2015-12-26 11:31:37 -08:00
secondsWithoutTouch_ = 0.0f ;
2015-12-20 12:40:47 -08:00
}
2017-03-14 22:01:18 -07:00
void GamepadView : : Update ( ) {
2020-08-16 00:13:19 +02:00
const double now = time_now_d ( ) ;
2015-12-26 11:31:37 -08:00
float delta = now - lastFrameTime_ ;
if ( delta > 0 ) {
secondsWithoutTouch_ + = delta ;
}
lastFrameTime_ = now ;
2015-12-20 12:40:47 -08:00
}
2021-02-21 16:38:02 -08:00
std : : string GamepadView : : DescribeText ( ) const {
auto co = GetI18NCategory ( " Controls " ) ;
return co - > T ( key_ ) ;
}
2015-12-20 12:40:47 -08:00
float GamepadView : : GetButtonOpacity ( ) {
2020-12-19 19:59:06 +01:00
if ( coreState ! = CORE_RUNNING ) {
return 0.0f ;
}
2015-12-26 11:31:37 -08:00
float fadeAfterSeconds = g_Config . iTouchButtonHideSeconds ;
float fadeTransitionSeconds = std : : min ( fadeAfterSeconds , 0.5f ) ;
2015-12-20 12:40:47 -08:00
float opacity = g_Config . iTouchButtonOpacity / 100.0f ;
float multiplier = 1.0f ;
2015-12-26 11:31:37 -08:00
if ( secondsWithoutTouch_ > = fadeAfterSeconds & & fadeAfterSeconds > 0.0f ) {
if ( secondsWithoutTouch_ > = fadeAfterSeconds + fadeTransitionSeconds ) {
2015-12-20 12:40:47 -08:00
multiplier = 0.0f ;
} else {
2015-12-26 11:31:37 -08:00
float secondsIntoFade = secondsWithoutTouch_ - fadeAfterSeconds ;
multiplier = 1.0f - ( secondsIntoFade / fadeTransitionSeconds ) ;
2015-12-20 12:40:47 -08:00
}
}
return opacity * multiplier ;
}
2013-07-20 12:06:06 +02:00
void MultiTouchButton : : GetContentDimensions ( const UIContext & dc , float & w , float & h ) const {
2020-02-29 21:51:14 +01:00
const AtlasImage * image = dc . Draw ( ) - > GetAtlas ( ) - > getImage ( bgImg_ ) ;
if ( image ) {
w = image - > w * scale_ ;
h = image - > h * scale_ ;
} else {
w = 0.0f ;
h = 0.0f ;
}
2013-07-20 12:06:06 +02:00
}
void MultiTouchButton : : Touch ( const TouchInput & input ) {
2015-12-20 12:40:47 -08:00
GamepadView : : Touch ( input ) ;
2013-07-20 12:06:06 +02:00
if ( ( input . flags & TOUCH_DOWN ) & & bounds_ . Contains ( input . x , input . y ) ) {
pointerDownMask_ | = 1 < < input . id ;
}
if ( input . flags & TOUCH_MOVE ) {
if ( bounds_ . Contains ( input . x , input . y ) )
pointerDownMask_ | = 1 < < input . id ;
else
pointerDownMask_ & = ~ ( 1 < < input . id ) ;
}
if ( input . flags & TOUCH_UP ) {
pointerDownMask_ & = ~ ( 1 < < input . id ) ;
}
2015-05-21 10:49:47 +02:00
if ( input . flags & TOUCH_RELEASE_ALL ) {
pointerDownMask_ = 0 ;
}
2013-07-20 12:06:06 +02:00
}
void MultiTouchButton : : Draw ( UIContext & dc ) {
2015-12-20 12:40:47 -08:00
float opacity = GetButtonOpacity ( ) ;
2017-01-26 11:10:33 +01:00
if ( opacity < = 0.0f )
return ;
2013-10-10 16:44:12 +02:00
2013-07-20 12:06:06 +02:00
float scale = scale_ ;
if ( IsDown ( ) ) {
2018-09-30 16:48:02 -07:00
if ( g_Config . iTouchButtonStyle = = 2 ) {
opacity * = 1.35f ;
} else {
scale * = 2.0f ;
opacity * = 1.15f ;
}
2013-07-20 12:06:06 +02:00
}
2015-05-31 18:25:43 +02:00
2013-12-10 23:19:37 +01:00
uint32_t colorBg = colorAlpha ( GetButtonColor ( ) , opacity ) ;
2018-09-30 16:48:02 -07:00
uint32_t downBg = colorAlpha ( 0xFFFFFF , opacity * 0.5f ) ;
2013-07-20 12:06:06 +02:00
uint32_t color = colorAlpha ( 0xFFFFFF , opacity ) ;
2018-09-30 16:48:02 -07:00
if ( IsDown ( ) & & g_Config . iTouchButtonStyle = = 2 ) {
if ( bgImg_ ! = bgDownImg_ )
dc . Draw ( ) - > DrawImageRotated ( bgDownImg_ , bounds_ . centerX ( ) , bounds_ . centerY ( ) , scale , bgAngle_ * ( M_PI * 2 / 360.0f ) , downBg , flipImageH_ ) ;
}
2018-06-16 23:00:21 -07:00
dc . Draw ( ) - > DrawImageRotated ( bgImg_ , bounds_ . centerX ( ) , bounds_ . centerY ( ) , scale , bgAngle_ * ( M_PI * 2 / 360.0f ) , colorBg , flipImageH_ ) ;
2013-12-11 20:18:54 +01:00
int y = bounds_ . centerY ( ) ;
// Hack round the fact that the center of the rectangular picture the triangle is contained in
// is not at the "weight center" of the triangle.
2020-02-29 21:51:14 +01:00
if ( img_ = = ImageID ( " I_TRIANGLE " ) )
2013-12-11 20:18:54 +01:00
y - = 2.8f * scale ;
dc . Draw ( ) - > DrawImageRotated ( img_ , bounds_ . centerX ( ) , y , scale , angle_ * ( M_PI * 2 / 360.0f ) , color ) ;
2013-07-20 14:05:07 +02:00
}
void BoolButton : : Touch ( const TouchInput & input ) {
bool lastDown = pointerDownMask_ ! = 0 ;
MultiTouchButton : : Touch ( input ) ;
bool down = pointerDownMask_ ! = 0 ;
if ( down ! = lastDown ) {
* value_ = down ;
2018-06-23 11:06:56 -07:00
UI : : EventParams params { this } ;
params . a = down ;
OnChange . Trigger ( params ) ;
2013-07-20 14:05:07 +02:00
}
2013-07-20 12:06:06 +02:00
}
void PSPButton : : Touch ( const TouchInput & input ) {
bool lastDown = pointerDownMask_ ! = 0 ;
MultiTouchButton : : Touch ( input ) ;
bool down = pointerDownMask_ ! = 0 ;
if ( down & & ! lastDown ) {
2013-10-10 16:44:12 +02:00
if ( g_Config . bHapticFeedback ) {
Vibrate ( HAPTIC_VIRTUAL_KEY ) ;
}
2013-07-20 12:06:06 +02:00
__CtrlButtonDown ( pspButtonBit_ ) ;
} else if ( lastDown & & ! down ) {
__CtrlButtonUp ( pspButtonBit_ ) ;
}
}
2021-03-04 10:37:35 +01:00
bool ComboKey : : IsDown ( ) {
return ( toggle_ & & on_ ) | | ( ! toggle_ & & pointerDownMask_ ! = 0 ) ;
}
2021-08-04 09:18:23 +02:00
void ComboKey : : GetContentDimensions ( const UIContext & dc , float & w , float & h ) const {
MultiTouchButton : : GetContentDimensions ( dc , w , h ) ;
if ( invertedContextDimension_ ) {
float tmp = w ;
w = h ;
h = tmp ;
}
}
2015-06-28 13:34:05 +08:00
void ComboKey : : Touch ( const TouchInput & input ) {
2021-03-04 10:37:35 +01:00
using namespace CustomKey ;
2015-06-28 13:34:05 +08:00
bool lastDown = pointerDownMask_ ! = 0 ;
MultiTouchButton : : Touch ( input ) ;
bool down = pointerDownMask_ ! = 0 ;
2021-03-04 10:37:35 +01:00
if ( down & & ! lastDown ) {
if ( g_Config . bHapticFeedback )
Vibrate ( HAPTIC_VIRTUAL_KEY ) ;
for ( int i = 0 ; i < ARRAY_SIZE ( comboKeyList ) ; i + + ) {
2021-07-19 10:31:28 +02:00
if ( pspButtonBit_ & ( 1ULL < < i ) ) {
2021-03-04 10:37:35 +01:00
controllMapper_ - > pspKey ( comboKeyList [ i ] . c , ( on_ & & toggle_ ) ? KEY_UP : KEY_DOWN ) ;
}
}
if ( toggle_ )
on_ = ! on_ ;
} else if ( ! toggle_ & & lastDown & & ! down ) {
for ( int i = 0 ; i < ARRAY_SIZE ( comboKeyList ) ; i + + ) {
2021-07-19 10:31:28 +02:00
if ( pspButtonBit_ & ( 1ULL < < i ) ) {
2021-03-04 10:37:35 +01:00
controllMapper_ - > pspKey ( comboKeyList [ i ] . c , KEY_UP ) ;
2015-06-28 13:34:05 +08:00
}
}
}
}
2013-07-20 12:06:06 +02:00
bool PSPButton : : IsDown ( ) {
2013-07-20 12:54:33 +02:00
return ( __CtrlPeekButtons ( ) & pspButtonBit_ ) ! = 0 ;
}
2021-02-21 16:38:02 -08:00
PSPDpad : : PSPDpad ( ImageID arrowIndex , const char * key , ImageID arrowDownIndex , ImageID overlayIndex , float scale , float spacing , UI : : LayoutParams * layoutParams )
: GamepadView ( key , layoutParams ) , arrowIndex_ ( arrowIndex ) , arrowDownIndex_ ( arrowDownIndex ) , overlayIndex_ ( overlayIndex ) ,
2013-12-02 15:15:19 +01:00
scale_ ( scale ) , spacing_ ( spacing ) , dragPointerId_ ( - 1 ) , down_ ( 0 ) {
2013-07-20 12:54:33 +02:00
}
2013-12-02 15:15:19 +01:00
void PSPDpad : : GetContentDimensions ( const UIContext & dc , float & w , float & h ) const {
w = D_pad_Radius * spacing_ * 4 ;
h = D_pad_Radius * spacing_ * 4 ;
2013-07-20 12:54:33 +02:00
}
2013-12-02 15:15:19 +01:00
void PSPDpad : : Touch ( const TouchInput & input ) {
2015-12-20 12:40:47 -08:00
GamepadView : : Touch ( input ) ;
2013-07-20 12:54:33 +02:00
if ( input . flags & TOUCH_DOWN ) {
if ( dragPointerId_ = = - 1 & & bounds_ . Contains ( input . x , input . y ) ) {
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_ ) {
2013-07-20 14:05:07 +02:00
dragPointerId_ = - 1 ;
2013-07-20 12:54:33 +02:00
ProcessTouch ( input . x , input . y , false ) ;
}
}
}
2013-12-02 15:15:19 +01:00
void PSPDpad : : ProcessTouch ( float x , float y , bool down ) {
float stick_size = spacing_ * D_pad_Radius * scale_ ;
2014-07-21 01:22:21 +02:00
float inv_stick_size = 1.0f / stick_size ;
2013-07-20 12:54:33 +02:00
const float deadzone = 0.17f ;
float dx = ( x - bounds_ . centerX ( ) ) * inv_stick_size ;
float dy = ( y - bounds_ . centerY ( ) ) * inv_stick_size ;
2013-12-02 15:15:19 +01:00
float rad = sqrtf ( dx * dx + dy * dy ) ;
2013-07-20 14:05:07 +02:00
if ( rad < deadzone | | rad > 2.0f )
2013-07-20 12:54:33 +02:00
down = false ;
int ctrlMask = 0 ;
int lastDown = down_ ;
2013-12-10 18:58:47 +01:00
2013-12-10 23:38:02 +01:00
bool fourWay = g_Config . bDisableDpadDiagonals | | rad < 0.7f ;
2013-07-20 12:54:33 +02:00
if ( down ) {
2013-12-10 18:58:47 +01:00
if ( fourWay ) {
2013-12-02 15:50:09 +01:00
int direction = ( int ) ( floorf ( ( atan2f ( dy , dx ) / ( 2 * M_PI ) * 4 ) + 0.5f ) ) & 3 ;
switch ( direction ) {
case 0 : ctrlMask | = CTRL_RIGHT ; break ;
case 1 : ctrlMask | = CTRL_DOWN ; break ;
case 2 : ctrlMask | = CTRL_LEFT ; break ;
case 3 : ctrlMask | = CTRL_UP ; break ;
}
// 4 way pad
} else {
// 8 way pad
int direction = ( int ) ( floorf ( ( atan2f ( dy , dx ) / ( 2 * M_PI ) * 8 ) + 0.5f ) ) & 7 ;
switch ( direction ) {
case 0 : ctrlMask | = CTRL_RIGHT ; break ;
case 1 : ctrlMask | = CTRL_RIGHT | CTRL_DOWN ; break ;
case 2 : ctrlMask | = CTRL_DOWN ; break ;
case 3 : ctrlMask | = CTRL_DOWN | CTRL_LEFT ; break ;
case 4 : ctrlMask | = CTRL_LEFT ; break ;
case 5 : ctrlMask | = CTRL_UP | CTRL_LEFT ; break ;
case 6 : ctrlMask | = CTRL_UP ; break ;
case 7 : ctrlMask | = CTRL_UP | CTRL_RIGHT ; break ;
}
2013-07-20 12:54:33 +02:00
}
}
down_ = ctrlMask ;
int pressed = down_ & ~ lastDown ;
int released = ( ~ down_ ) & lastDown ;
static const int dir [ 4 ] = { CTRL_RIGHT , CTRL_DOWN , CTRL_LEFT , CTRL_UP } ;
for ( int i = 0 ; i < 4 ; i + + ) {
2013-10-10 16:44:12 +02:00
if ( pressed & dir [ i ] ) {
if ( g_Config . bHapticFeedback ) {
Vibrate ( HAPTIC_VIRTUAL_KEY ) ;
}
__CtrlButtonDown ( dir [ i ] ) ;
}
if ( released & dir [ i ] ) {
__CtrlButtonUp ( dir [ i ] ) ;
}
2013-07-20 12:54:33 +02:00
}
}
2013-12-02 15:15:19 +01:00
void PSPDpad : : Draw ( UIContext & dc ) {
2015-12-20 12:40:47 -08:00
float opacity = GetButtonOpacity ( ) ;
2017-01-26 11:10:33 +01:00
if ( opacity < = 0.0f )
return ;
2013-07-20 12:54:33 +02:00
static const float xoff [ 4 ] = { 1 , 0 , - 1 , 0 } ;
static const float yoff [ 4 ] = { 0 , 1 , 0 , - 1 } ;
static const int dir [ 4 ] = { CTRL_RIGHT , CTRL_DOWN , CTRL_LEFT , CTRL_UP } ;
int buttons = __CtrlPeekButtons ( ) ;
2013-12-11 20:52:13 +01:00
float r = D_pad_Radius * spacing_ ;
2013-07-20 12:54:33 +02:00
for ( int i = 0 ; i < 4 ; i + + ) {
2018-09-30 16:48:02 -07:00
bool isDown = ( buttons & dir [ i ] ) ! = 0 ;
2013-12-11 20:52:13 +01:00
float x = bounds_ . centerX ( ) + xoff [ i ] * r ;
float y = bounds_ . centerY ( ) + yoff [ i ] * r ;
float x2 = bounds_ . centerX ( ) + xoff [ i ] * ( r + 10.f * scale_ ) ;
float y2 = bounds_ . centerY ( ) + yoff [ i ] * ( r + 10.f * scale_ ) ;
2013-07-20 12:54:33 +02:00
float angle = i * M_PI / 2 ;
2018-09-30 16:48:02 -07:00
float imgScale = isDown ? scale_ * 2 : scale_ ;
float imgOpacity = opacity ;
if ( isDown & & g_Config . iTouchButtonStyle = = 2 ) {
imgScale = scale_ ;
imgOpacity * = 1.35f ;
uint32_t downBg = colorAlpha ( 0x00FFFFFF , imgOpacity * 0.5f ) ;
if ( arrowIndex_ ! = arrowDownIndex_ )
dc . Draw ( ) - > DrawImageRotated ( arrowDownIndex_ , x , y , imgScale , angle + PI , downBg , false ) ;
}
uint32_t colorBg = colorAlpha ( GetButtonColor ( ) , imgOpacity ) ;
uint32_t color = colorAlpha ( 0xFFFFFF , imgOpacity ) ;
2013-07-20 12:54:33 +02:00
dc . Draw ( ) - > DrawImageRotated ( arrowIndex_ , x , y , imgScale , angle + PI , colorBg , false ) ;
2020-02-29 21:51:14 +01:00
if ( overlayIndex_ . isValid ( ) )
2013-12-11 20:52:13 +01:00
dc . Draw ( ) - > DrawImageRotated ( overlayIndex_ , x2 , y2 , imgScale , angle + PI , color ) ;
2013-07-20 12:54:33 +02:00
}
2013-07-20 12:06:06 +02:00
}
2021-02-21 16:38:02 -08:00
PSPStick : : PSPStick ( ImageID bgImg , const char * key , ImageID stickImg , ImageID stickDownImg , int stick , float scale , UI : : LayoutParams * layoutParams )
: GamepadView ( key , layoutParams ) , dragPointerId_ ( - 1 ) , bgImg_ ( bgImg ) , stickImageIndex_ ( stickImg ) , stickDownImg_ ( stickDownImg ) , stick_ ( stick ) , scale_ ( scale ) , centerX_ ( - 1 ) , centerY_ ( - 1 ) {
2013-07-20 14:05:07 +02:00
stick_size_ = 50 ;
}
void PSPStick : : GetContentDimensions ( const UIContext & dc , float & w , float & h ) const {
2020-02-29 21:51:14 +01:00
dc . Draw ( ) - > GetAtlas ( ) - > measureImage ( bgImg_ , & w , & h ) ;
2013-07-20 14:05:07 +02:00
}
void PSPStick : : Draw ( UIContext & dc ) {
2015-12-20 12:40:47 -08:00
float opacity = GetButtonOpacity ( ) ;
2017-01-26 11:10:33 +01:00
if ( opacity < = 0.0f )
return ;
2013-07-20 14:05:07 +02:00
2018-09-30 16:48:02 -07:00
if ( dragPointerId_ ! = - 1 & & g_Config . iTouchButtonStyle = = 2 ) {
opacity * = 1.35f ;
}
2013-12-10 23:19:37 +01:00
uint32_t colorBg = colorAlpha ( GetButtonColor ( ) , opacity ) ;
2018-09-30 16:48:02 -07:00
uint32_t downBg = colorAlpha ( 0x00FFFFFF , opacity * 0.5f ) ;
2013-07-20 14:05:07 +02:00
2015-03-05 10:58:25 +01:00
if ( centerX_ < 0.0f ) {
centerX_ = bounds_ . centerX ( ) ;
centerY_ = bounds_ . centerY ( ) ;
}
float stickX = centerX_ ;
float stickY = centerY_ ;
2013-07-20 14:05:07 +02:00
float dx , dy ;
__CtrlPeekAnalog ( stick_ , & dx , & dy ) ;
dc . Draw ( ) - > DrawImage ( bgImg_ , stickX , stickY , 1.0f * scale_ , colorBg , ALIGN_CENTER ) ;
2018-09-30 16:48:02 -07:00
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 ) ;
2013-07-20 18:20:41 +02:00
dc . Draw ( ) - > DrawImage ( stickImageIndex_ , stickX + dx * stick_size_ * scale_ , stickY - dy * stick_size_ * scale_ , 1.0f * scale_ , colorBg , ALIGN_CENTER ) ;
2013-07-20 14:05:07 +02:00
}
void PSPStick : : Touch ( const TouchInput & input ) {
2015-12-20 12:40:47 -08:00
GamepadView : : Touch ( input ) ;
2015-05-21 10:49:47 +02:00
if ( input . flags & TOUCH_RELEASE_ALL ) {
dragPointerId_ = - 1 ;
centerX_ = bounds_ . centerX ( ) ;
centerY_ = bounds_ . centerY ( ) ;
2021-07-09 10:41:26 +02:00
__CtrlSetAnalogXY ( stick_ , 0.0f , 0.0f ) ;
2015-05-21 10:49:47 +02:00
return ;
}
2013-07-20 14:05:07 +02:00
if ( input . flags & TOUCH_DOWN ) {
if ( dragPointerId_ = = - 1 & & bounds_ . Contains ( input . x , input . y ) ) {
2015-03-05 10:58:25 +01:00
if ( g_Config . bAutoCenterTouchAnalog ) {
centerX_ = input . x ;
centerY_ = input . y ;
} else {
centerX_ = bounds_ . centerX ( ) ;
centerY_ = bounds_ . centerY ( ) ;
}
2013-07-20 14:05:07 +02:00
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 ;
2015-03-05 10:58:25 +01:00
centerX_ = bounds_ . centerX ( ) ;
centerY_ = bounds_ . centerY ( ) ;
2013-07-20 14:05:07 +02:00
ProcessTouch ( input . x , input . y , false ) ;
}
}
}
void PSPStick : : ProcessTouch ( float x , float y , bool down ) {
2015-03-05 10:58:25 +01:00
if ( down & & centerX_ > = 0.0f ) {
2013-07-20 14:05:07 +02:00
float inv_stick_size = 1.0f / ( stick_size_ * scale_ ) ;
2015-03-05 10:58:25 +01:00
float dx = ( x - centerX_ ) * inv_stick_size ;
float dy = ( y - centerY_ ) * inv_stick_size ;
2013-07-20 14:05:07 +02:00
// 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 ) ) ;
2021-07-09 10:41:26 +02:00
__CtrlSetAnalogXY ( stick_ , dx , - dy ) ;
2013-07-20 14:05:07 +02:00
} else {
2021-07-09 10:41:26 +02:00
__CtrlSetAnalogXY ( stick_ , 0.0f , 0.0f ) ;
2013-07-20 14:05:07 +02:00
}
}
2021-02-21 16:38:02 -08:00
PSPCustomStick : : PSPCustomStick ( ImageID bgImg , const char * key , ImageID stickImg , ImageID stickDownImg , float scale , UI : : LayoutParams * layoutParams )
: PSPStick ( bgImg , key , stickImg , stickDownImg , - 1 , scale , layoutParams ) {
2019-11-13 18:55:18 +01:00
}
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 ) ;
if ( centerX_ < 0.0f ) {
centerX_ = bounds_ . centerX ( ) ;
centerY_ = bounds_ . centerY ( ) ;
}
float stickX = centerX_ ;
float stickY = centerY_ ;
float dx , dy ;
2020-03-05 18:29:35 +01:00
dx = posX_ ;
dy = - posY_ ;
2019-11-13 18:55:18 +01:00
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 ( ) ;
2020-03-05 18:29:35 +01:00
posX_ = 0.0f ;
posY_ = 0.0f ;
2019-11-13 18:55:18 +01:00
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 ) {
float inv_stick_size = 1.0f / ( stick_size_ * scale_ ) ;
float dx = ( x - centerX_ ) * inv_stick_size ;
float dy = ( y - centerY_ ) * inv_stick_size ;
dx = std : : min ( 1.0f , std : : max ( - 1.0f , dx ) ) ;
dy = std : : min ( 1.0f , std : : max ( - 1.0f , dy ) ) ;
if ( g_Config . iRightAnalogRight ! = 0 ) {
2021-08-07 12:47:50 +02:00
if ( dx > 0.5f & & ( ! g_Config . bRightAnalogDisableDiagonal | | fabs ( dx ) > fabs ( dy ) ) )
2019-11-13 18:55:18 +01:00
__CtrlButtonDown ( button [ g_Config . iRightAnalogRight - 1 ] ) ;
else
__CtrlButtonUp ( button [ g_Config . iRightAnalogRight - 1 ] ) ;
}
if ( g_Config . iRightAnalogLeft ! = 0 ) {
2021-08-07 12:47:50 +02:00
if ( dx < - 0.5f & & ( ! g_Config . bRightAnalogDisableDiagonal | | fabs ( dx ) > fabs ( dy ) ) )
2019-11-13 18:55:18 +01:00
__CtrlButtonDown ( button [ g_Config . iRightAnalogLeft - 1 ] ) ;
else
__CtrlButtonUp ( button [ g_Config . iRightAnalogLeft - 1 ] ) ;
}
if ( g_Config . iRightAnalogUp ! = 0 ) {
2021-08-07 12:47:50 +02:00
if ( dy < - 0.5f & & ( ! g_Config . bRightAnalogDisableDiagonal | | fabs ( dx ) < = fabs ( dy ) ) )
2019-11-13 18:55:18 +01:00
__CtrlButtonDown ( button [ g_Config . iRightAnalogUp - 1 ] ) ;
else
__CtrlButtonUp ( button [ g_Config . iRightAnalogUp - 1 ] ) ;
}
if ( g_Config . iRightAnalogDown ! = 0 ) {
2021-08-07 12:47:50 +02:00
if ( dy > 0.5f & & ( ! g_Config . bRightAnalogDisableDiagonal | | fabs ( dx ) < = fabs ( dy ) ) )
2019-11-13 18:55:18 +01:00
__CtrlButtonDown ( button [ g_Config . iRightAnalogDown - 1 ] ) ;
else
__CtrlButtonUp ( button [ g_Config . iRightAnalogDown - 1 ] ) ;
}
if ( g_Config . iRightAnalogPress ! = 0 )
__CtrlButtonDown ( button [ g_Config . iRightAnalogPress - 1 ] ) ;
2020-03-05 18:29:35 +01:00
posX_ = dx ;
posY_ = dy ;
2019-11-13 18:55:18 +01:00
} else {
if ( g_Config . iRightAnalogUp ! = 0 )
__CtrlButtonUp ( button [ g_Config . iRightAnalogUp - 1 ] ) ;
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 ] ) ;
2020-03-05 18:29:35 +01:00
posX_ = 0.0f ;
posY_ = 0.0f ;
2019-11-13 18:55:18 +01:00
}
}
2014-02-10 15:55:21 +01:00
void InitPadLayout ( float xres , float yres , float globalScale ) {
2013-12-02 15:15:19 +01:00
const float scale = globalScale ;
2018-06-16 22:14:41 -07:00
const int halfW = xres / 2 ;
auto initTouchPos = [ = ] ( ConfigTouchPos & touch , float x , float y ) {
if ( touch . x = = - 1.0f | | touch . y = = - 1.0f ) {
touch . x = x / xres ;
touch . y = y / yres ;
touch . scale = scale ;
}
} ;
2013-10-10 01:45:56 +05:30
2013-11-29 16:46:47 +01:00
// PSP buttons (triangle, circle, square, cross)---------------------
// space between the PSP buttons (triangle, circle, square and cross)
2013-12-02 15:15:19 +01:00
if ( g_Config . fActionButtonSpacing < 0 ) {
g_Config . fActionButtonSpacing = 1.0f ;
2013-10-10 01:45:56 +05:30
}
2013-11-29 16:46:47 +01:00
// Position of the circle button (the PSP circle button). It is the farthest to the left
2013-12-02 15:15:19 +01:00
float Action_button_spacing = g_Config . fActionButtonSpacing * baseActionButtonSpacing ;
2014-02-10 15:55:21 +01:00
int Action_button_center_X = xres - Action_button_spacing * 2 ;
int Action_button_center_Y = yres - Action_button_spacing * 2 ;
2019-07-18 03:16:46 +02:00
if ( g_Config . touchRightAnalogStick . show ) {
Action_button_center_Y - = 150 * scale ;
}
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchActionButtonCenter , Action_button_center_X , Action_button_center_Y ) ;
2013-10-10 01:45:56 +05:30
2013-11-29 16:46:47 +01:00
//D-PAD (up down left right) (aka PSP cross)----------------------------
2013-10-10 01:45:56 +05:30
//radius to the D-pad
2013-12-02 15:15:19 +01:00
// TODO: Make configurable
2013-10-10 01:45:56 +05:30
2013-12-02 15:15:19 +01:00
int D_pad_X = 2.5 * D_pad_Radius * scale ;
2014-02-10 15:55:21 +01:00
int D_pad_Y = yres - D_pad_Radius * scale ;
2018-06-16 22:14:41 -07:00
if ( g_Config . touchAnalogStick . show ) {
2013-10-10 01:45:56 +05:30
D_pad_Y - = 200 * scale ;
}
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchDpad , D_pad_X , D_pad_Y ) ;
2013-10-10 01:45:56 +05:30
//analog stick-------------------------------------------------------
//keep the analog stick right below the D pad
int analog_stick_X = D_pad_X ;
2014-02-10 15:55:21 +01:00
int analog_stick_Y = yres - 80 * scale ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchAnalogStick , analog_stick_X , analog_stick_Y ) ;
2013-10-10 01:45:56 +05:30
2019-07-18 03:16:46 +02:00
//right analog stick-------------------------------------------------
//keep the right analog stick right below the face buttons
int right_analog_stick_X = Action_button_center_X ;
int right_analog_stick_Y = yres - 80 * scale ;
initTouchPos ( g_Config . touchRightAnalogStick , right_analog_stick_X , right_analog_stick_Y ) ;
2013-10-10 01:45:56 +05:30
//select, start, throttle--------------------------------------------
//space between the bottom keys (space between select, start and un-throttle)
2014-07-22 10:37:20 +02:00
float bottom_key_spacing = 100 ;
if ( dp_xres < 750 ) {
bottom_key_spacing * = 0.8f ;
}
2013-11-29 16:46:47 +01:00
2018-06-16 22:14:41 -07:00
int start_key_X = halfW + bottom_key_spacing * scale ;
2014-02-10 15:55:21 +01:00
int start_key_Y = yres - 60 * scale ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchStartKey , start_key_X , start_key_Y ) ;
2013-10-10 01:45:56 +05:30
2018-06-16 22:14:41 -07:00
int select_key_X = halfW ;
2014-02-10 15:55:21 +01:00
int select_key_Y = yres - 60 * scale ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchSelectKey , select_key_X , select_key_Y ) ;
2013-10-10 01:45:56 +05:30
2021-08-17 16:48:47 +02:00
int fast_forward_key_X = halfW - bottom_key_spacing * scale ;
int fast_forward_key_Y = yres - 60 * scale ;
initTouchPos ( g_Config . touchFastForwardKey , fast_forward_key_X , fast_forward_key_Y ) ;
2013-10-10 01:45:56 +05:30
2015-05-12 19:45:14 +02:00
// L and R------------------------------------------------------------
// Put them above the analog stick / above the buttons to the right.
// The corners were very hard to reach..
int l_key_X = 60 * scale ;
2015-05-31 18:25:43 +02:00
int l_key_Y = yres - 380 * scale ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchLKey , l_key_X , l_key_Y ) ;
2013-10-10 01:45:56 +05:30
2014-02-10 15:55:21 +01:00
int r_key_X = xres - 60 * scale ;
2015-05-31 18:25:43 +02:00
int r_key_Y = l_key_Y ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchRKey , r_key_X , r_key_Y ) ;
2015-06-28 13:34:05 +08:00
//Combo key
2018-06-16 22:14:41 -07:00
int combo_key_X = halfW + bottom_key_spacing * scale * 1.2f ;
2015-06-28 13:34:05 +08:00
int combo_key_Y = yres / 2 ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchCombo0 , combo_key_X , combo_key_Y ) ;
2015-06-28 13:34:05 +08:00
2018-06-16 22:14:41 -07:00
int combo1_key_X = halfW + bottom_key_spacing * scale * 2.2f ;
2015-06-28 13:34:05 +08:00
int combo1_key_Y = yres / 2 ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchCombo1 , combo1_key_X , combo1_key_Y ) ;
2015-06-28 13:34:05 +08:00
2018-06-16 22:14:41 -07:00
int combo2_key_X = halfW + bottom_key_spacing * scale * 3.2f ;
2015-06-28 13:34:05 +08:00
int combo2_key_Y = yres / 2 ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchCombo2 , combo2_key_X , combo2_key_Y ) ;
2015-06-28 13:34:05 +08:00
2018-06-16 22:14:41 -07:00
int combo3_key_X = halfW + bottom_key_spacing * scale * 1.2f ;
2015-06-28 13:34:05 +08:00
int combo3_key_Y = yres / 3 ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchCombo3 , combo3_key_X , combo3_key_Y ) ;
2015-06-28 13:34:05 +08:00
2018-06-16 22:14:41 -07:00
int combo4_key_X = halfW + bottom_key_spacing * scale * 2.2f ;
2015-06-28 13:34:05 +08:00
int combo4_key_Y = yres / 3 ;
2018-06-16 22:14:41 -07:00
initTouchPos ( g_Config . touchCombo4 , combo4_key_X , combo4_key_Y ) ;
2021-03-04 10:37:35 +01:00
int combo5_key_X = halfW - bottom_key_spacing * scale * 1.2f ;
int combo5_key_Y = yres / 2 ;
initTouchPos ( g_Config . touchCombo5 , combo5_key_X , combo5_key_Y ) ;
int combo6_key_X = halfW - bottom_key_spacing * scale * 2.2f ;
int combo6_key_Y = yres / 2 ;
initTouchPos ( g_Config . touchCombo6 , combo6_key_X , combo6_key_Y ) ;
int combo7_key_X = halfW - bottom_key_spacing * scale * 3.2f ;
int combo7_key_Y = yres / 2 ;
initTouchPos ( g_Config . touchCombo7 , combo7_key_X , combo7_key_Y ) ;
int combo8_key_X = halfW - bottom_key_spacing * scale * 1.2f ;
int combo8_key_Y = yres / 3 ;
initTouchPos ( g_Config . touchCombo8 , combo8_key_X , combo8_key_Y ) ;
int combo9_key_X = halfW - bottom_key_spacing * scale * 2.2f ;
int combo9_key_Y = yres / 3 ;
initTouchPos ( g_Config . touchCombo9 , combo9_key_X , combo9_key_Y ) ;
2018-06-16 22:14:41 -07:00
}
2013-10-10 01:45:56 +05:30
2021-03-04 10:37:35 +01:00
UI : : ViewGroup * CreatePadLayout ( float xres , float yres , bool * pause , ControlMapper * controllMapper ) {
2013-07-20 12:06:06 +02:00
using namespace UI ;
AnchorLayout * root = new AnchorLayout ( new LayoutParams ( FILL_PARENT , FILL_PARENT ) ) ;
2018-06-16 22:14:41 -07:00
if ( ! g_Config . bShowTouchControls ) {
return root ;
}
struct ButtonOffset {
float x ;
float y ;
} ;
auto buttonLayoutParams = [ = ] ( const ConfigTouchPos & touch , ButtonOffset off = { 0 , 0 } ) {
return new AnchorLayoutParams ( touch . x * xres + off . x , touch . y * yres + off . y , NONE , NONE , true ) ;
} ;
// Space between the PSP buttons (traingle, circle, square and cross)
const float actionButtonSpacing = g_Config . fActionButtonSpacing * baseActionButtonSpacing ;
// Position of the circle button (the PSP circle button). It is the farthest to the right.
ButtonOffset circleOffset { actionButtonSpacing , 0.0f } ;
ButtonOffset crossOffset { 0.0f , actionButtonSpacing } ;
ButtonOffset triangleOffset { 0.0f , - actionButtonSpacing } ;
ButtonOffset squareOffset { - actionButtonSpacing , 0.0f } ;
2015-06-28 13:34:05 +08:00
2014-02-10 15:55:21 +01:00
const int halfW = xres / 2 ;
2013-07-20 12:54:33 +02:00
2020-02-29 21:51:14 +01:00
const ImageID roundImage = g_Config . iTouchButtonStyle ? ImageID ( " I_ROUND_LINE " ) : ImageID ( " I_ROUND " ) ;
const ImageID rectImage = g_Config . iTouchButtonStyle ? ImageID ( " I_RECT_LINE " ) : ImageID ( " I_RECT " ) ;
const ImageID shoulderImage = g_Config . iTouchButtonStyle ? ImageID ( " I_SHOULDER_LINE " ) : ImageID ( " I_SHOULDER " ) ;
const ImageID dirImage = g_Config . iTouchButtonStyle ? ImageID ( " I_DIR_LINE " ) : ImageID ( " I_DIR " ) ;
const ImageID stickImage = g_Config . iTouchButtonStyle ? ImageID ( " I_STICK_LINE " ) : ImageID ( " I_STICK " ) ;
const ImageID stickBg = g_Config . iTouchButtonStyle ? ImageID ( " I_STICK_BG_LINE " ) : ImageID ( " I_STICK_BG " ) ;
2013-12-10 23:19:37 +01:00
2021-02-21 16:38:02 -08:00
auto addPSPButton = [ = ] ( int buttonBit , const char * key , ImageID bgImg , ImageID bgDownImg , ImageID img , const ConfigTouchPos & touch , ButtonOffset off = { 0 , 0 } ) - > PSPButton * {
2018-06-16 22:14:41 -07:00
if ( touch . show ) {
2021-02-21 16:38:02 -08:00
return root - > Add ( new PSPButton ( buttonBit , key , bgImg , bgDownImg , img , touch . scale , buttonLayoutParams ( touch , off ) ) ) ;
2017-03-07 10:33:53 +01:00
}
2018-06-16 22:14:41 -07:00
return nullptr ;
} ;
2021-02-21 16:38:02 -08:00
auto addBoolButton = [ = ] ( bool * value , const char * key , ImageID bgImg , ImageID bgDownImg , ImageID img , const ConfigTouchPos & touch ) - > BoolButton * {
2018-06-16 22:14:41 -07:00
if ( touch . show ) {
2021-02-21 16:38:02 -08:00
return root - > Add ( new BoolButton ( value , key , bgImg , bgDownImg , img , touch . scale , buttonLayoutParams ( touch ) ) ) ;
2018-06-16 22:14:41 -07:00
}
return nullptr ;
} ;
2021-03-04 10:37:35 +01:00
auto addComboKey = [ = ] ( const ConfigCustomButton & cfg , const char * key , const ConfigTouchPos & touch ) - > ComboKey * {
using namespace CustomKey ;
2018-06-16 23:00:21 -07:00
if ( touch . show ) {
2021-03-04 10:37:35 +01:00
auto aux = root - > Add ( new ComboKey ( cfg . key , key , cfg . toggle , controllMapper ,
g_Config . iTouchButtonStyle = = 0 ? comboKeyShapes [ cfg . shape ] . i : comboKeyShapes [ cfg . shape ] . l , comboKeyShapes [ cfg . shape ] . i ,
2021-08-04 09:18:23 +02:00
comboKeyImages [ cfg . image ] . i , touch . scale , comboKeyShapes [ cfg . shape ] . d , buttonLayoutParams ( touch ) ) ) ;
2021-03-04 10:37:35 +01:00
aux - > SetAngle ( comboKeyImages [ cfg . image ] . r , comboKeyShapes [ cfg . shape ] . r ) ;
aux - > FlipImageH ( comboKeyShapes [ cfg . shape ] . f ) ;
return aux ;
2018-06-16 23:00:21 -07:00
}
return nullptr ;
} ;
2018-06-16 22:14:41 -07:00
if ( ! System_GetPropertyBool ( SYSPROP_HAS_BACK_BUTTON ) | | g_Config . bShowTouchPause ) {
2021-02-21 16:38:02 -08:00
root - > Add ( new BoolButton ( pause , " Pause button " , roundImage , ImageID ( " I_ROUND " ) , ImageID ( " I_ARROW " ) , 1.0f , new AnchorLayoutParams ( halfW , 20 , NONE , NONE , true ) ) ) - > SetAngle ( 90 ) ;
2018-06-16 22:14:41 -07:00
}
// touchActionButtonCenter.show will always be true, since that's the default.
if ( g_Config . bShowTouchCircle )
2021-02-21 16:38:02 -08:00
addPSPButton ( CTRL_CIRCLE , " Circle button " , roundImage , ImageID ( " I_ROUND " ) , ImageID ( " I_CIRCLE " ) , g_Config . touchActionButtonCenter , circleOffset ) ;
2018-06-16 22:14:41 -07:00
if ( g_Config . bShowTouchCross )
2021-02-21 16:38:02 -08:00
addPSPButton ( CTRL_CROSS , " Cross button " , roundImage , ImageID ( " I_ROUND " ) , ImageID ( " I_CROSS " ) , g_Config . touchActionButtonCenter , crossOffset ) ;
2018-06-16 22:14:41 -07:00
if ( g_Config . bShowTouchTriangle )
2021-02-21 16:38:02 -08:00
addPSPButton ( CTRL_TRIANGLE , " Triangle button " , roundImage , ImageID ( " I_ROUND " ) , ImageID ( " I_TRIANGLE " ) , g_Config . touchActionButtonCenter , triangleOffset ) ;
2018-06-16 22:14:41 -07:00
if ( g_Config . bShowTouchSquare )
2021-02-21 16:38:02 -08:00
addPSPButton ( CTRL_SQUARE , " Square button " , roundImage , ImageID ( " I_ROUND " ) , ImageID ( " I_SQUARE " ) , g_Config . touchActionButtonCenter , squareOffset ) ;
2018-06-16 22:14:41 -07:00
2021-02-21 16:38:02 -08:00
addPSPButton ( CTRL_START , " Start button " , rectImage , ImageID ( " I_RECT " ) , ImageID ( " I_START " ) , g_Config . touchStartKey ) ;
addPSPButton ( CTRL_SELECT , " Select button " , rectImage , ImageID ( " I_RECT " ) , ImageID ( " I_SELECT " ) , g_Config . touchSelectKey ) ;
2018-06-16 22:14:41 -07:00
2021-08-17 16:48:47 +02:00
BoolButton * fastForward = addBoolButton ( & PSP_CoreParameter ( ) . fastForward , " Fast-forward button " , rectImage , ImageID ( " I_RECT " ) , ImageID ( " I_ARROW " ) , g_Config . touchFastForwardKey ) ;
if ( fastForward ) {
fastForward - > SetAngle ( 180.0f ) ;
fastForward - > OnChange . Add ( [ ] ( UI : : EventParams & e ) {
2018-12-30 12:16:33 -08:00
if ( e . a & & coreState = = CORE_STEPPING ) {
2018-06-23 11:06:56 -07:00
Core_EnableStepping ( false ) ;
}
return UI : : EVENT_DONE ;
} ) ;
}
2018-06-16 23:00:21 -07:00
2021-02-21 16:38:02 -08:00
addPSPButton ( CTRL_LTRIGGER , " Left shoulder button " , shoulderImage , ImageID ( " I_SHOULDER " ) , ImageID ( " I_L " ) , g_Config . touchLKey ) ;
PSPButton * rTrigger = addPSPButton ( CTRL_RTRIGGER , " Right shoulder button " , shoulderImage , ImageID ( " I_SHOULDER " ) , ImageID ( " I_R " ) , g_Config . touchRKey ) ;
2018-06-16 22:14:41 -07:00
if ( rTrigger )
rTrigger - > FlipImageH ( true ) ;
if ( g_Config . touchDpad . show )
2021-02-21 16:38:02 -08:00
root - > Add ( new PSPDpad ( dirImage , " D-pad " , ImageID ( " I_DIR " ) , ImageID ( " I_ARROW " ) , g_Config . touchDpad . scale , g_Config . fDpadSpacing , buttonLayoutParams ( g_Config . touchDpad ) ) ) ;
2018-06-16 22:14:41 -07:00
if ( g_Config . touchAnalogStick . show )
2021-02-21 16:38:02 -08:00
root - > Add ( new PSPStick ( stickBg , " Left analog stick " , stickImage , ImageID ( " I_STICK " ) , 0 , g_Config . touchAnalogStick . scale , buttonLayoutParams ( g_Config . touchAnalogStick ) ) ) ;
2018-06-16 22:14:41 -07:00
2019-11-13 18:55:18 +01:00
if ( g_Config . touchRightAnalogStick . show ) {
if ( g_Config . bRightAnalogCustom )
2021-02-21 16:38:02 -08:00
root - > Add ( new PSPCustomStick ( stickBg , " Right analog stick " , stickImage , ImageID ( " I_STICK " ) , g_Config . touchRightAnalogStick . scale , buttonLayoutParams ( g_Config . touchRightAnalogStick ) ) ) ;
2019-11-13 18:55:18 +01:00
else
2021-02-21 16:38:02 -08:00
root - > Add ( new PSPStick ( stickBg , " Right analog stick " , stickImage , ImageID ( " I_STICK " ) , 1 , g_Config . touchRightAnalogStick . scale , buttonLayoutParams ( g_Config . touchRightAnalogStick ) ) ) ;
2019-11-13 18:55:18 +01:00
}
2019-07-18 03:16:46 +02:00
2021-03-04 10:37:35 +01:00
addComboKey ( g_Config . CustomKey0 , " Custom 1 button " , g_Config . touchCombo0 ) ;
addComboKey ( g_Config . CustomKey1 , " Custom 2 button " , g_Config . touchCombo1 ) ;
addComboKey ( g_Config . CustomKey2 , " Custom 3 button " , g_Config . touchCombo2 ) ;
addComboKey ( g_Config . CustomKey3 , " Custom 4 button " , g_Config . touchCombo3 ) ;
addComboKey ( g_Config . CustomKey4 , " Custom 5 button " , g_Config . touchCombo4 ) ;
addComboKey ( g_Config . CustomKey5 , " Custom 6 button " , g_Config . touchCombo5 ) ;
addComboKey ( g_Config . CustomKey6 , " Custom 7 button " , g_Config . touchCombo6 ) ;
addComboKey ( g_Config . CustomKey7 , " Custom 8 button " , g_Config . touchCombo7 ) ;
addComboKey ( g_Config . CustomKey8 , " Custom 9 button " , g_Config . touchCombo8 ) ;
addComboKey ( g_Config . CustomKey9 , " Custom 10 button " , g_Config . touchCombo9 ) ;
2012-11-01 16:19:01 +01:00
2013-07-20 14:05:07 +02:00
return root ;
2012-11-01 16:19:01 +01:00
}