2013-08-16 16:48:43 +02:00
// 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/.
2021-03-02 20:42:55 -08:00
# include "ppsspp_config.h"
2014-09-05 23:21:07 +02:00
# include <algorithm>
# include <deque>
2017-02-27 21:57:46 +01:00
# include <mutex>
2014-09-05 23:21:07 +02:00
2020-10-04 23:24:14 +02:00
# include "Common/Render/TextureAtlas.h"
2020-10-04 20:48:47 +02:00
# include "Common/UI/Root.h"
# include "Common/UI/UI.h"
# include "Common/UI/Context.h"
# include "Common/UI/View.h"
# include "Common/UI/ViewGroup.h"
2013-08-16 16:48:43 +02:00
2020-10-04 10:30:18 +02:00
# include "Common/Log.h"
2020-10-01 13:05:04 +02:00
# include "Common/Data/Color/RGBAUtil.h"
# include "Common/Data/Text/I18n.h"
# include "Common/Input/KeyCodes.h"
# include "Common/Input/InputState.h"
2020-10-04 10:30:18 +02:00
# include "Common/System/Display.h"
# include "Common/System/System.h"
2020-10-04 00:25:21 +02:00
# include "Core/KeyMap.h"
2019-02-17 12:17:41 -08:00
# include "Core/Host.h"
2013-08-16 16:48:43 +02:00
# include "Core/HLE/sceCtrl.h"
2013-09-07 11:29:44 -04:00
# include "Core/System.h"
2013-08-16 16:48:43 +02:00
# include "Core/Config.h"
# include "UI/ControlMappingScreen.h"
2013-09-25 01:37:25 +08:00
# include "UI/GameSettingsScreen.h"
2013-08-16 16:48:43 +02:00
2021-07-09 00:05:47 +02:00
class SingleControlMapper : public UI : : LinearLayout {
2013-08-17 10:34:38 +02:00
public :
2021-07-09 00:05:47 +02:00
SingleControlMapper ( ControlMappingScreen * ctrlScreen , int pspKey , std : : string keyName , ScreenManager * scrm , UI : : LinearLayoutParams * layoutParams = 0 ) ;
2013-08-17 10:34:38 +02:00
2017-03-14 22:01:18 -07:00
void Update ( ) override ;
2014-06-08 15:38:13 +02:00
int GetPspKey ( ) const { return pspKey_ ; }
2013-08-17 10:34:38 +02:00
private :
void Refresh ( ) ;
UI : : EventReturn OnAdd ( UI : : EventParams & params ) ;
2017-04-27 10:09:57 +02:00
UI : : EventReturn OnAddMouse ( UI : : EventParams & params ) ;
2013-08-17 10:34:38 +02:00
UI : : EventReturn OnDelete ( UI : : EventParams & params ) ;
UI : : EventReturn OnReplace ( UI : : EventParams & params ) ;
UI : : EventReturn OnReplaceAll ( UI : : EventParams & params ) ;
void MappedCallback ( KeyDef key ) ;
enum Action {
NONE ,
REPLACEONE ,
REPLACEALL ,
ADD ,
} ;
2014-06-08 15:38:13 +02:00
ControlMappingScreen * ctrlScreen_ ;
2013-08-17 10:34:38 +02:00
Action action_ ;
int actionIndex_ ;
int pspKey_ ;
std : : string keyName_ ;
ScreenManager * scrm_ ;
bool refresh_ ;
} ;
2021-07-09 00:05:47 +02:00
SingleControlMapper : : SingleControlMapper ( ControlMappingScreen * ctrlScreen , int pspKey , std : : string keyName , ScreenManager * scrm , UI : : LinearLayoutParams * layoutParams )
2014-06-08 15:38:13 +02:00
: UI : : LinearLayout ( UI : : ORIENT_VERTICAL , layoutParams ) , ctrlScreen_ ( ctrlScreen ) , action_ ( NONE ) , pspKey_ ( pspKey ) , keyName_ ( keyName ) , scrm_ ( scrm ) , refresh_ ( false ) {
2013-08-17 10:34:38 +02:00
Refresh ( ) ;
}
2021-07-09 00:05:47 +02:00
void SingleControlMapper : : Update ( ) {
2013-08-17 10:34:38 +02:00
if ( refresh_ ) {
refresh_ = false ;
Refresh ( ) ;
2019-02-17 12:17:41 -08:00
host - > UpdateUI ( ) ;
2013-08-16 16:48:43 +02:00
}
}
2021-07-09 00:05:47 +02:00
void SingleControlMapper : : Refresh ( ) {
2014-06-08 15:38:13 +02:00
bool hasFocus = UI : : GetFocusedView ( ) = = this ;
2013-08-17 10:34:38 +02:00
Clear ( ) ;
2020-01-26 10:43:18 -08:00
auto mc = GetI18NCategory ( " MappableControls " ) ;
2013-08-30 16:01:17 +02:00
2020-02-29 21:51:14 +01:00
std : : map < std : : string , ImageID > keyImages ;
keyImages [ " Circle " ] = ImageID ( " I_CIRCLE " ) ;
keyImages [ " Cross " ] = ImageID ( " I_CROSS " ) ;
keyImages [ " Square " ] = ImageID ( " I_SQUARE " ) ;
keyImages [ " Triangle " ] = ImageID ( " I_TRIANGLE " ) ;
keyImages [ " Start " ] = ImageID ( " I_START " ) ;
keyImages [ " Select " ] = ImageID ( " I_SELECT " ) ;
keyImages [ " L " ] = ImageID ( " I_L " ) ;
keyImages [ " R " ] = ImageID ( " I_R " ) ;
2013-08-17 10:34:38 +02:00
using namespace UI ;
2013-08-16 16:48:43 +02:00
2013-12-06 16:45:25 +01:00
float itemH = 45 ;
2014-06-09 22:26:23 +02:00
LinearLayout * root = Add ( new LinearLayout ( ORIENT_HORIZONTAL , new LinearLayoutParams ( 550 , WRAP_CONTENT ) ) ) ;
2013-12-06 16:45:25 +01:00
root - > SetSpacing ( 3.0f ) ;
2013-08-30 16:01:17 +02:00
auto iter = keyImages . find ( keyName_ ) ;
// First, look among images.
if ( iter ! = keyImages . end ( ) ) {
2013-12-06 16:45:25 +01:00
Choice * c = root - > Add ( new Choice ( iter - > second , new LinearLayoutParams ( 200 , itemH ) ) ) ;
2021-07-09 00:05:47 +02:00
c - > OnClick . Handle ( this , & SingleControlMapper : : OnReplaceAll ) ;
2013-08-30 16:01:17 +02:00
} else {
// No image? Let's translate.
2013-12-06 16:45:25 +01:00
Choice * c = new Choice ( mc - > T ( keyName_ . c_str ( ) ) , new LinearLayoutParams ( 200 , itemH ) ) ;
c - > SetCentered ( true ) ;
2021-07-09 00:05:47 +02:00
root - > Add ( c ) - > OnClick . Handle ( this , & SingleControlMapper : : OnReplaceAll ) ;
2013-08-30 16:01:17 +02:00
}
2016-08-15 20:40:44 -07:00
Choice * p = root - > Add ( new Choice ( " + " , new LayoutParams ( WRAP_CONTENT , itemH ) ) ) ;
2021-07-09 00:05:47 +02:00
p - > OnClick . Handle ( this , & SingleControlMapper : : OnAdd ) ;
2017-04-27 10:09:57 +02:00
if ( g_Config . bMouseControl ) {
Choice * p = root - > Add ( new Choice ( " M " , new LayoutParams ( WRAP_CONTENT , itemH ) ) ) ;
2021-07-09 00:05:47 +02:00
p - > OnClick . Handle ( this , & SingleControlMapper : : OnAddMouse ) ;
2017-04-27 10:09:57 +02:00
}
2014-06-09 22:26:23 +02:00
2013-12-06 16:45:25 +01:00
LinearLayout * rightColumn = root - > Add ( new LinearLayout ( ORIENT_VERTICAL , new LinearLayoutParams ( FILL_PARENT , WRAP_CONTENT , 1.0f ) ) ) ;
2013-08-20 15:40:19 +02:00
rightColumn - > SetSpacing ( 2.0f ) ;
2013-08-17 10:34:38 +02:00
std : : vector < KeyDef > mappings ;
2019-07-14 08:50:01 +02:00
KeyMap : : KeyFromPspButton ( pspKey_ , & mappings , false ) ;
2013-08-16 16:48:43 +02:00
2013-08-17 10:34:38 +02:00
for ( size_t i = 0 ; i < mappings . size ( ) ; i + + ) {
std : : string deviceName = GetDeviceName ( mappings [ i ] . deviceId ) ;
2013-08-17 11:18:45 +02:00
std : : string keyName = KeyMap : : GetKeyOrAxisName ( mappings [ i ] . keyCode ) ;
2013-08-17 10:34:38 +02:00
LinearLayout * row = rightColumn - > Add ( new LinearLayout ( ORIENT_HORIZONTAL , new LinearLayoutParams ( FILL_PARENT , WRAP_CONTENT ) ) ) ;
2013-12-06 16:45:25 +01:00
row - > SetSpacing ( 1.0f ) ;
2013-08-17 10:34:38 +02:00
2013-12-06 16:45:25 +01:00
Choice * c = row - > Add ( new Choice ( deviceName + " . " + keyName , new LinearLayoutParams ( FILL_PARENT , itemH , 1.0f ) ) ) ;
2013-08-17 13:26:19 +02:00
char tagbuf [ 16 ] ;
2013-08-20 19:20:03 +02:00
sprintf ( tagbuf , " %i " , ( int ) i ) ;
2013-08-17 13:26:19 +02:00
c - > SetTag ( tagbuf ) ;
2021-07-09 00:05:47 +02:00
c - > OnClick . Handle ( this , & SingleControlMapper : : OnReplace ) ;
2013-08-20 19:20:03 +02:00
2016-08-15 20:40:44 -07:00
Choice * d = row - > Add ( new Choice ( " X " , new LayoutParams ( WRAP_CONTENT , itemH ) ) ) ;
2013-08-17 13:26:19 +02:00
d - > SetTag ( tagbuf ) ;
2021-07-09 00:05:47 +02:00
d - > OnClick . Handle ( this , & SingleControlMapper : : OnDelete ) ;
2013-08-16 16:48:43 +02:00
}
2013-08-17 10:34:38 +02:00
if ( mappings . size ( ) = = 0 ) {
// look like an empty line
2013-12-06 16:45:25 +01:00
Choice * c = rightColumn - > Add ( new Choice ( " " , new LinearLayoutParams ( FILL_PARENT , itemH ) ) ) ;
2021-07-09 00:05:47 +02:00
c - > OnClick . Handle ( this , & SingleControlMapper : : OnAdd ) ;
2013-08-17 10:34:38 +02:00
}
2014-06-08 15:38:13 +02:00
if ( hasFocus )
this - > SetFocus ( ) ;
2013-08-17 10:34:38 +02:00
}
2021-07-09 00:05:47 +02:00
void SingleControlMapper : : MappedCallback ( KeyDef kdf ) {
2013-08-17 10:34:38 +02:00
switch ( action_ ) {
2013-08-17 11:18:45 +02:00
case ADD :
KeyMap : : SetKeyMapping ( pspKey_ , kdf , false ) ;
break ;
2013-08-17 10:34:38 +02:00
case REPLACEALL :
KeyMap : : SetKeyMapping ( pspKey_ , kdf , true ) ;
break ;
case REPLACEONE :
KeyMap : : g_controllerMap [ pspKey_ ] [ actionIndex_ ] = kdf ;
2019-02-17 12:17:41 -08:00
KeyMap : : g_controllerMapGeneration + + ;
2013-08-17 10:34:38 +02:00
break ;
2013-08-17 13:26:19 +02:00
default :
;
2013-08-17 10:34:38 +02:00
}
2017-04-26 16:48:55 +02:00
g_Config . bMapMouse = false ;
2013-08-17 10:34:38 +02:00
refresh_ = true ;
2014-06-08 15:38:13 +02:00
ctrlScreen_ - > KeyMapped ( pspKey_ ) ;
// After this, we do not exist any more. So the refresh_ = true is probably irrelevant.
2013-08-17 10:34:38 +02:00
}
2021-07-09 00:05:47 +02:00
UI : : EventReturn SingleControlMapper : : OnReplace ( UI : : EventParams & params ) {
2013-08-17 10:34:38 +02:00
actionIndex_ = atoi ( params . v - > Tag ( ) . c_str ( ) ) ;
action_ = REPLACEONE ;
2020-01-26 10:43:18 -08:00
auto km = GetI18NCategory ( " KeyMapping " ) ;
2021-07-09 00:05:47 +02:00
scrm_ - > push ( new KeyMappingNewKeyDialog ( pspKey_ , true , std : : bind ( & SingleControlMapper : : MappedCallback , this , std : : placeholders : : _1 ) , km ) ) ;
2013-08-17 10:34:38 +02:00
return UI : : EVENT_DONE ;
}
2021-07-09 00:05:47 +02:00
UI : : EventReturn SingleControlMapper : : OnReplaceAll ( UI : : EventParams & params ) {
2013-08-17 10:34:38 +02:00
action_ = REPLACEALL ;
2020-01-26 10:43:18 -08:00
auto km = GetI18NCategory ( " KeyMapping " ) ;
2021-07-09 00:05:47 +02:00
scrm_ - > push ( new KeyMappingNewKeyDialog ( pspKey_ , true , std : : bind ( & SingleControlMapper : : MappedCallback , this , std : : placeholders : : _1 ) , km ) ) ;
2013-08-17 10:34:38 +02:00
return UI : : EVENT_DONE ;
}
2021-07-09 00:05:47 +02:00
UI : : EventReturn SingleControlMapper : : OnAdd ( UI : : EventParams & params ) {
2013-08-17 11:18:45 +02:00
action_ = ADD ;
2020-01-26 10:43:18 -08:00
auto km = GetI18NCategory ( " KeyMapping " ) ;
2021-07-09 00:05:47 +02:00
scrm_ - > push ( new KeyMappingNewKeyDialog ( pspKey_ , true , std : : bind ( & SingleControlMapper : : MappedCallback , this , std : : placeholders : : _1 ) , km ) ) ;
2013-08-17 10:34:38 +02:00
return UI : : EVENT_DONE ;
}
2021-07-09 00:05:47 +02:00
UI : : EventReturn SingleControlMapper : : OnAddMouse ( UI : : EventParams & params ) {
2017-04-27 10:09:57 +02:00
action_ = ADD ;
g_Config . bMapMouse = true ;
2020-01-26 10:43:18 -08:00
auto km = GetI18NCategory ( " KeyMapping " ) ;
2021-07-09 00:05:47 +02:00
scrm_ - > push ( new KeyMappingNewMouseKeyDialog ( pspKey_ , true , std : : bind ( & SingleControlMapper : : MappedCallback , this , std : : placeholders : : _1 ) , km ) ) ;
2017-04-27 10:09:57 +02:00
return UI : : EVENT_DONE ;
}
2013-08-17 10:34:38 +02:00
2021-07-09 00:05:47 +02:00
UI : : EventReturn SingleControlMapper : : OnDelete ( UI : : EventParams & params ) {
2013-08-17 11:18:45 +02:00
int index = atoi ( params . v - > Tag ( ) . c_str ( ) ) ;
KeyMap : : g_controllerMap [ pspKey_ ] . erase ( KeyMap : : g_controllerMap [ pspKey_ ] . begin ( ) + index ) ;
2019-02-17 12:17:41 -08:00
KeyMap : : g_controllerMapGeneration + + ;
2013-08-17 10:34:38 +02:00
refresh_ = true ;
return UI : : EVENT_DONE ;
}
void ControlMappingScreen : : CreateViews ( ) {
using namespace UI ;
2014-06-08 15:38:13 +02:00
mappers_ . clear ( ) ;
2013-08-17 10:34:38 +02:00
2020-01-26 10:43:18 -08:00
auto km = GetI18NCategory ( " KeyMapping " ) ;
2013-08-17 10:34:38 +02:00
root_ = new LinearLayout ( ORIENT_HORIZONTAL ) ;
2015-07-04 08:01:32 -07:00
LinearLayout * leftColumn = new LinearLayout ( ORIENT_VERTICAL , new LinearLayoutParams ( 200 , FILL_PARENT , Margins ( 10 , 0 , 0 , 10 ) ) ) ;
2015-07-01 23:54:35 +02:00
leftColumn - > Add ( new Choice ( km - > T ( " Clear All " ) ) ) - > OnClick . Handle ( this , & ControlMappingScreen : : OnClearMapping ) ;
leftColumn - > Add ( new Choice ( km - > T ( " Default All " ) ) ) - > OnClick . Handle ( this , & ControlMappingScreen : : OnDefaultMapping ) ;
2015-10-04 13:25:22 +02:00
std : : string sysName = System_GetProperty ( SYSPROP_NAME ) ;
// If there's a builtin controller, restore to default should suffice. No need to conf the controller on top.
if ( ! KeyMap : : HasBuiltinController ( sysName ) & & KeyMap : : GetSeenPads ( ) . size ( ) ) {
2015-07-01 23:54:35 +02:00
leftColumn - > Add ( new Choice ( km - > T ( " Autoconfigure " ) ) ) - > OnClick . Handle ( this , & ControlMappingScreen : : OnAutoConfigure ) ;
2014-05-19 23:29:35 +02:00
}
2021-07-09 13:10:16 +02:00
2013-08-17 10:34:38 +02:00
leftColumn - > Add ( new Spacer ( new LinearLayoutParams ( 1.0f ) ) ) ;
2015-07-04 08:01:32 -07:00
AddStandardBack ( leftColumn ) ;
2013-12-02 15:15:19 +01:00
2014-06-08 15:38:13 +02:00
rightScroll_ = new ScrollView ( ORIENT_VERTICAL , new LinearLayoutParams ( 1.0f ) ) ;
2016-01-22 22:52:13 -08:00
rightScroll_ - > SetTag ( " ControlMapping " ) ;
2014-06-08 15:38:13 +02:00
rightScroll_ - > SetScrollToTop ( false ) ;
2021-02-21 18:41:08 -08:00
LinearLayout * rightColumn = new LinearLayoutList ( ORIENT_VERTICAL , new LinearLayoutParams ( 1.0f ) ) ;
2014-06-08 15:38:13 +02:00
rightScroll_ - > Add ( rightColumn ) ;
2013-08-17 10:34:38 +02:00
root_ - > Add ( leftColumn ) ;
2014-06-08 15:38:13 +02:00
root_ - > Add ( rightScroll_ ) ;
2013-08-17 10:34:38 +02:00
std : : vector < KeyMap : : KeyMap_IntStrPair > mappableKeys = KeyMap : : GetMappableKeys ( ) ;
for ( size_t i = 0 ; i < mappableKeys . size ( ) ; i + + ) {
2021-07-09 00:05:47 +02:00
SingleControlMapper * mapper = rightColumn - > Add ( new SingleControlMapper ( this , mappableKeys [ i ] . key , mappableKeys [ i ] . name , screenManager ( ) , new LinearLayoutParams ( FILL_PARENT , WRAP_CONTENT ) ) ) ;
2014-06-08 15:38:13 +02:00
mappers_ . push_back ( mapper ) ;
2013-08-17 10:34:38 +02:00
}
}
UI : : EventReturn ControlMappingScreen : : OnClearMapping ( UI : : EventParams & params ) {
KeyMap : : g_controllerMap . clear ( ) ;
2013-08-18 00:41:19 +02:00
RecreateViews ( ) ;
return UI : : EVENT_DONE ;
}
2013-08-17 10:34:38 +02:00
2013-08-18 00:41:19 +02:00
UI : : EventReturn ControlMappingScreen : : OnDefaultMapping ( UI : : EventParams & params ) {
KeyMap : : RestoreDefault ( ) ;
2013-08-17 10:34:38 +02:00
RecreateViews ( ) ;
return UI : : EVENT_DONE ;
2013-08-16 16:48:43 +02:00
}
2014-05-19 23:29:35 +02:00
UI : : EventReturn ControlMappingScreen : : OnAutoConfigure ( UI : : EventParams & params ) {
std : : vector < std : : string > items ;
2014-05-21 08:40:00 -07:00
const auto seenPads = KeyMap : : GetSeenPads ( ) ;
for ( auto s = seenPads . begin ( ) , end = seenPads . end ( ) ; s ! = end ; + + s ) {
items . push_back ( * s ) ;
2014-05-19 23:29:35 +02:00
}
2020-01-26 10:43:18 -08:00
auto km = GetI18NCategory ( " KeyMapping " ) ;
2015-07-01 23:54:35 +02:00
ListPopupScreen * autoConfList = new ListPopupScreen ( km - > T ( " Autoconfigure for device " ) , items , - 1 ) ;
2017-03-21 18:27:57 -07:00
if ( params . v )
autoConfList - > SetPopupOrigin ( params . v ) ;
2014-05-19 23:29:35 +02:00
screenManager ( ) - > push ( autoConfList ) ;
return UI : : EVENT_DONE ;
}
void ControlMappingScreen : : dialogFinished ( const Screen * dialog , DialogResult result ) {
if ( result = = DR_OK & & dialog - > tag ( ) = = " listpopup " ) {
ListPopupScreen * popup = ( ListPopupScreen * ) dialog ;
KeyMap : : AutoConfForPad ( popup - > GetChoiceString ( ) ) ;
RecreateViews ( ) ;
}
}
2014-06-08 15:38:13 +02:00
void ControlMappingScreen : : KeyMapped ( int pspkey ) { // Notification to let us refocus the same one after recreating views.
2014-06-15 10:01:54 -07:00
for ( size_t i = 0 ; i < mappers_ . size ( ) ; i + + ) {
2014-06-08 15:38:13 +02:00
if ( mappers_ [ i ] - > GetPspKey ( ) = = pspkey )
SetFocusedView ( mappers_ [ i ] ) ;
}
}
2013-08-16 17:16:11 +02:00
void KeyMappingNewKeyDialog : : CreatePopupContents ( UI : : ViewGroup * parent ) {
using namespace UI ;
2013-08-16 16:48:43 +02:00
2020-01-26 10:43:18 -08:00
auto km = GetI18NCategory ( " KeyMapping " ) ;
auto mc = GetI18NCategory ( " MappableControls " ) ;
2013-08-16 16:48:43 +02:00
2013-08-16 17:16:11 +02:00
std : : string pspButtonName = KeyMap : : GetPspButtonName ( this - > pspBtn_ ) ;
2013-08-16 16:48:43 +02:00
2017-08-14 11:33:14 +02:00
parent - > Add ( new TextView ( std : : string ( km - > T ( " Map a new key for " ) ) + " " + mc - > T ( pspButtonName ) , new LinearLayoutParams ( Margins ( 10 , 0 ) ) ) ) ;
2013-08-16 16:48:43 +02:00
}
2014-06-15 13:04:59 +02:00
bool KeyMappingNewKeyDialog : : key ( const KeyInput & key ) {
2014-06-08 15:38:13 +02:00
if ( mapped_ )
2014-06-15 13:04:59 +02:00
return false ;
2013-08-16 16:48:43 +02:00
if ( key . flags & KEY_DOWN ) {
2017-04-27 11:12:11 +02:00
if ( key . keyCode = = NKCODE_EXT_MOUSEBUTTON_1 ) {
2014-06-15 13:04:59 +02:00
return true ;
2013-08-16 16:48:43 +02:00
}
2013-08-20 00:49:25 +02:00
2014-06-08 15:38:13 +02:00
mapped_ = true ;
2013-08-17 10:34:38 +02:00
KeyDef kdf ( key . deviceId , key . keyCode ) ;
2017-03-19 17:43:03 -07:00
TriggerFinish ( DR_OK ) ;
2013-08-17 10:34:38 +02:00
if ( callback_ )
callback_ ( kdf ) ;
2013-08-16 16:48:43 +02:00
}
2014-06-15 13:04:59 +02:00
return true ;
2013-08-16 16:48:43 +02:00
}
2017-04-27 11:12:11 +02:00
void KeyMappingNewMouseKeyDialog : : CreatePopupContents ( UI : : ViewGroup * parent ) {
using namespace UI ;
2020-01-26 10:43:18 -08:00
auto km = GetI18NCategory ( " KeyMapping " ) ;
2017-04-27 11:12:11 +02:00
parent - > Add ( new TextView ( std : : string ( km - > T ( " You can press ESC to cancel. " ) ) , new LinearLayoutParams ( Margins ( 10 , 0 ) ) ) ) ;
}
bool KeyMappingNewMouseKeyDialog : : key ( const KeyInput & key ) {
if ( mapped_ )
return false ;
if ( key . flags & KEY_DOWN ) {
if ( key . keyCode = = NKCODE_ESCAPE ) {
TriggerFinish ( DR_OK ) ;
g_Config . bMapMouse = false ;
return false ;
}
mapped_ = true ;
KeyDef kdf ( key . deviceId , key . keyCode ) ;
TriggerFinish ( DR_OK ) ;
g_Config . bMapMouse = false ;
if ( callback_ )
callback_ ( kdf ) ;
}
return true ;
}
2016-09-11 18:47:21 +02:00
static bool IgnoreAxisForMapping ( int axis ) {
switch ( axis ) {
// Ignore the accelerometer for mapping for now.
2014-01-06 23:58:59 +01:00
case JOYSTICK_AXIS_ACCELEROMETER_X :
case JOYSTICK_AXIS_ACCELEROMETER_Y :
case JOYSTICK_AXIS_ACCELEROMETER_Z :
2016-09-11 18:47:21 +02:00
return true ;
2014-01-07 00:01:41 +01:00
2016-09-11 18:47:21 +02:00
// Also ignore some weird axis events we get on Ouya.
2014-01-07 00:01:41 +01:00
case JOYSTICK_AXIS_OUYA_UNKNOWN1 :
case JOYSTICK_AXIS_OUYA_UNKNOWN2 :
case JOYSTICK_AXIS_OUYA_UNKNOWN3 :
case JOYSTICK_AXIS_OUYA_UNKNOWN4 :
2016-09-11 18:47:21 +02:00
return true ;
2014-01-07 00:01:41 +01:00
2014-01-06 23:58:59 +01:00
default :
2016-09-11 18:47:21 +02:00
return false ;
2014-01-06 23:58:59 +01:00
}
2016-09-11 18:47:21 +02:00
}
bool KeyMappingNewKeyDialog : : axis ( const AxisInput & axis ) {
if ( mapped_ )
return false ;
if ( IgnoreAxisForMapping ( axis . axisId ) )
2017-04-27 11:12:11 +02:00
return false ;
if ( axis . value > AXIS_BIND_THRESHOLD ) {
mapped_ = true ;
KeyDef kdf ( axis . deviceId , KeyMap : : TranslateKeyCodeFromAxis ( axis . axisId , 1 ) ) ;
TriggerFinish ( DR_OK ) ;
if ( callback_ )
callback_ ( kdf ) ;
}
if ( axis . value < - AXIS_BIND_THRESHOLD ) {
mapped_ = true ;
KeyDef kdf ( axis . deviceId , KeyMap : : TranslateKeyCodeFromAxis ( axis . axisId , - 1 ) ) ;
TriggerFinish ( DR_OK ) ;
if ( callback_ )
callback_ ( kdf ) ;
}
return true ;
}
bool KeyMappingNewMouseKeyDialog : : axis ( const AxisInput & axis ) {
if ( mapped_ )
return false ;
if ( IgnoreAxisForMapping ( axis . axisId ) )
2016-09-11 18:47:21 +02:00
return false ;
2014-01-06 23:58:59 +01:00
2013-08-16 16:48:43 +02:00
if ( axis . value > AXIS_BIND_THRESHOLD ) {
2014-06-08 15:38:13 +02:00
mapped_ = true ;
2013-08-17 10:34:38 +02:00
KeyDef kdf ( axis . deviceId , KeyMap : : TranslateKeyCodeFromAxis ( axis . axisId , 1 ) ) ;
2017-03-19 17:43:03 -07:00
TriggerFinish ( DR_OK ) ;
2013-08-17 10:34:38 +02:00
if ( callback_ )
callback_ ( kdf ) ;
2013-08-16 16:48:43 +02:00
}
2013-08-16 17:16:11 +02:00
2013-08-16 16:48:43 +02:00
if ( axis . value < - AXIS_BIND_THRESHOLD ) {
2014-06-08 15:38:13 +02:00
mapped_ = true ;
2013-08-17 10:34:38 +02:00
KeyDef kdf ( axis . deviceId , KeyMap : : TranslateKeyCodeFromAxis ( axis . axisId , - 1 ) ) ;
2017-03-19 17:43:03 -07:00
TriggerFinish ( DR_OK ) ;
2013-08-17 10:34:38 +02:00
if ( callback_ )
callback_ ( kdf ) ;
2013-08-16 16:48:43 +02:00
}
2014-06-15 13:04:59 +02:00
return true ;
2013-08-16 16:48:43 +02:00
}
2014-09-05 23:21:07 +02:00
2021-07-09 17:04:59 +02:00
enum class StickHistoryViewType {
INPUT ,
OUTPUT
} ;
2014-09-05 23:21:07 +02:00
class JoystickHistoryView : public UI : : InertView {
public :
2021-07-09 17:04:59 +02:00
JoystickHistoryView ( StickHistoryViewType type , std : : string title , UI : : LayoutParams * layoutParams = nullptr )
: UI : : InertView ( layoutParams ) , title_ ( title ) , type_ ( type ) { }
2014-09-09 22:28:35 +02:00
void Draw ( UIContext & dc ) override ;
2021-07-09 13:10:16 +02:00
std : : string DescribeText ( ) const override { return " Analog Stick View " ; }
2017-03-14 22:01:18 -07:00
void Update ( ) override ;
2021-07-09 13:10:16 +02:00
void SetXY ( float x , float y ) {
curX_ = x ;
curY_ = y ;
2014-09-09 22:28:35 +02:00
}
private :
struct Location {
float x ;
float y ;
} ;
2019-09-03 00:05:18 +02:00
float curX_ = 0.0f ;
float curY_ = 0.0f ;
2014-09-09 22:28:35 +02:00
std : : deque < Location > locations_ ;
2019-09-03 00:05:18 +02:00
int maxCount_ = 500 ;
2021-07-09 13:10:16 +02:00
std : : string title_ ;
2021-07-09 17:04:59 +02:00
StickHistoryViewType type_ ;
2014-09-05 23:21:07 +02:00
} ;
void JoystickHistoryView : : Draw ( UIContext & dc ) {
2021-07-09 13:10:16 +02:00
const AtlasImage * image = dc . Draw ( ) - > GetAtlas ( ) - > getImage ( ImageID ( " I_CROSS " ) ) ;
if ( ! image ) {
return ;
}
float minRadius = std : : min ( bounds_ . w , bounds_ . h ) * 0.5f - image - > w ;
dc . Begin ( ) ;
dc . DrawTextShadow ( title_ . c_str ( ) , bounds_ . centerX ( ) , bounds_ . y2 ( ) , 0xFFFFFFFF , ALIGN_BOTTOM | ALIGN_HCENTER ) ;
dc . Flush ( ) ;
dc . BeginNoTex ( ) ;
dc . Draw ( ) - > RectOutline ( bounds_ . centerX ( ) - minRadius , bounds_ . centerY ( ) - minRadius , minRadius * 2.0f , minRadius * 2.0f , 0x80FFFFFF ) ;
dc . Flush ( ) ;
dc . Begin ( ) ;
2021-07-09 17:04:59 +02:00
// First draw a grid.
float dx = 1.0f / 10.0f ;
for ( int ix = - 10 ; ix < = 10 ; ix + + ) {
// First draw vertical lines.
float fx = ix * dx ;
for ( int iy = - 10 ; iy < 10 ; iy + + ) {
float ax = fx ;
float ay = iy * dx ;
float bx = fx ;
float by = ( iy + 1 ) * dx ;
if ( type_ = = StickHistoryViewType : : OUTPUT ) {
ConvertAnalogStick ( ax , ay ) ;
ConvertAnalogStick ( bx , by ) ;
}
ax = ax * minRadius + bounds_ . centerX ( ) ;
ay = ay * minRadius + bounds_ . centerY ( ) ;
bx = bx * minRadius + bounds_ . centerX ( ) ;
by = by * minRadius + bounds_ . centerY ( ) ;
dc . Draw ( ) - > Line ( dc . theme - > whiteImage , ax , ay , bx , by , 1.0 , 0x70FFFFFF ) ;
}
}
for ( int iy = - 10 ; iy < = 10 ; iy + + ) {
// Then horizontal.
float fy = iy * dx ;
for ( int ix = - 10 ; ix < 10 ; ix + + ) {
float ax = ix * dx ;
float ay = fy ;
float bx = ( ix + 1 ) * dx ;
float by = fy ;
if ( type_ = = StickHistoryViewType : : OUTPUT ) {
ConvertAnalogStick ( ax , ay ) ;
ConvertAnalogStick ( bx , by ) ;
}
ax = ax * minRadius + bounds_ . centerX ( ) ;
ay = ay * minRadius + bounds_ . centerY ( ) ;
bx = bx * minRadius + bounds_ . centerX ( ) ;
by = by * minRadius + bounds_ . centerY ( ) ;
dc . Draw ( ) - > Line ( dc . theme - > whiteImage , ax , ay , bx , by , 1.0 , 0x70FFFFFF ) ;
}
}
2021-07-09 13:10:16 +02:00
int a = maxCount_ - ( int ) locations_ . size ( ) ;
for ( auto iter = locations_ . begin ( ) ; iter ! = locations_ . end ( ) ; + + iter ) {
float x = bounds_ . centerX ( ) + minRadius * iter - > x ;
float y = bounds_ . centerY ( ) - minRadius * iter - > y ;
float alpha = ( float ) a / ( float ) ( maxCount_ - 1 ) ;
if ( alpha < 0.0f ) {
alpha = 0.0f ;
2020-02-29 21:51:14 +01:00
}
2021-07-09 13:10:16 +02:00
// Emphasize the newest (higher) ones.
alpha = powf ( alpha , 3.7f ) ;
2021-07-09 17:04:59 +02:00
// Highlight the output.
if ( alpha > = 1.0f & & type_ = = StickHistoryViewType : : OUTPUT ) {
2021-07-09 13:10:16 +02:00
dc . Draw ( ) - > DrawImage ( ImageID ( " I_CIRCLE " ) , x , y , 1.0f , colorAlpha ( 0xFFFFFF , 1.0 ) , ALIGN_CENTER ) ;
} else {
dc . Draw ( ) - > DrawImage ( ImageID ( " I_CIRCLE " ) , x , y , 0.8f , colorAlpha ( 0xC0C0C0 , alpha * 0.5f ) , ALIGN_CENTER ) ;
2014-09-05 23:21:07 +02:00
}
2021-07-09 13:10:16 +02:00
a + + ;
2014-09-05 23:21:07 +02:00
}
2021-07-09 13:10:16 +02:00
dc . Flush ( ) ;
2014-09-05 23:21:07 +02:00
}
2017-03-14 22:01:18 -07:00
void JoystickHistoryView : : Update ( ) {
2021-07-09 13:10:16 +02:00
locations_ . push_back ( Location { curX_ , curY_ } ) ;
if ( ( int ) locations_ . size ( ) > maxCount_ ) {
locations_ . pop_front ( ) ;
2014-09-05 23:21:07 +02:00
}
}
2021-07-09 16:14:32 +02:00
AnalogSetupScreen : : AnalogSetupScreen ( ) {
mapper_ . SetCallbacks ( [ ] ( int vkey ) { } , [ ] ( int vkey ) { } , [ & ] ( int stick , float x , float y ) {
analogX_ [ stick ] = x ;
analogY_ [ stick ] = y ;
} ) ;
mapper_ . SetRawCallback ( [ & ] ( int stick , float x , float y ) {
rawX_ [ stick ] = x ;
rawY_ [ stick ] = y ;
} ) ;
}
void AnalogSetupScreen : : update ( ) {
mapper_ . Update ( ) ;
// We ignore the secondary stick for now and just use the two views
// for raw and psp input.
if ( stickView_ [ 0 ] ) {
2021-07-09 17:04:59 +02:00
stickView_ [ 0 ] - > SetXY ( analogX_ [ 0 ] , analogY_ [ 0 ] ) ;
2021-07-09 16:14:32 +02:00
}
if ( stickView_ [ 1 ] ) {
2021-07-09 17:04:59 +02:00
stickView_ [ 1 ] - > SetXY ( rawX_ [ 0 ] , rawY_ [ 0 ] ) ;
2021-07-09 16:14:32 +02:00
}
UIScreen : : update ( ) ;
}
2021-07-09 13:10:16 +02:00
bool AnalogSetupScreen : : key ( const KeyInput & key ) {
2021-07-09 16:14:32 +02:00
// Allow testing auto-rotation
bool pauseTrigger = false ;
mapper_ . Key ( key , & pauseTrigger ) ;
2015-09-17 22:46:59 +02:00
if ( UI : : IsEscapeKey ( key ) ) {
2017-03-19 17:43:03 -07:00
TriggerFinish ( DR_BACK ) ;
2015-09-17 22:46:59 +02:00
return true ;
}
2021-07-09 17:04:59 +02:00
return true ;
2015-01-03 17:55:15 +01:00
}
2021-07-09 13:10:16 +02:00
bool AnalogSetupScreen : : axis ( const AxisInput & axis ) {
// We DON'T call UIScreen::Axis here! Otherwise it'll try to move the UI focus around.
// UIScreen::axis(axis);
// Instead we just send the input directly to the mapper, that we'll visualize.
2021-07-09 17:04:59 +02:00
return mapper_ . Axis ( axis ) ;
2015-08-28 01:22:45 +02:00
}
2021-07-09 13:10:16 +02:00
void AnalogSetupScreen : : CreateViews ( ) {
2015-01-03 17:55:15 +01:00
using namespace UI ;
2020-01-26 10:43:18 -08:00
auto di = GetI18NCategory ( " Dialog " ) ;
2015-01-04 02:01:05 +01:00
2021-07-09 13:10:16 +02:00
root_ = new LinearLayout ( ORIENT_HORIZONTAL ) ;
2014-09-05 23:21:07 +02:00
2021-07-09 13:10:16 +02:00
LinearLayout * leftColumn = root_ - > Add ( new LinearLayout ( ORIENT_VERTICAL , new LinearLayoutParams ( 300.0f , FILL_PARENT ) ) ) ;
LinearLayout * rightColumn = root_ - > Add ( new LinearLayout ( ORIENT_VERTICAL , new LinearLayoutParams ( 1.0f ) ) ) ;
2014-09-05 23:21:07 +02:00
2021-07-09 13:10:16 +02:00
auto co = GetI18NCategory ( " Controls " ) ;
2021-07-09 17:25:00 +02:00
ScrollView * scroll = leftColumn - > Add ( new ScrollView ( ORIENT_VERTICAL , new LinearLayoutParams ( 1.0 ) ) ) ;
LinearLayout * scrollContents = scroll - > Add ( new LinearLayout ( ORIENT_VERTICAL , new LinearLayoutParams ( 300.0f , WRAP_CONTENT ) ) ) ;
scrollContents - > Add ( new ItemHeader ( co - > T ( " Analog Settings " , " Analog Settings " ) ) ) ;
scrollContents - > Add ( new PopupSliderChoiceFloat ( & g_Config . fAnalogDeadzone , 0.0f , 1.0f , co - > T ( " Deadzone Radius " ) , 0.01f , screenManager ( ) , " / 1.0 " ) ) ;
scrollContents - > Add ( new PopupSliderChoiceFloat ( & g_Config . fAnalogInverseDeadzone , 0.0f , 1.0f , co - > T ( " Low End Radius " , " Low End " ) , 0.01f , screenManager ( ) , " / 1.0 " ) ) ;
scrollContents - > Add ( new PopupSliderChoiceFloat ( & g_Config . fAnalogSensitivity , 0.0f , 10.0f , co - > T ( " Sensitivity " , " Sensitivity (scale factor) " ) , 0.01f , screenManager ( ) , " x " ) ) ;
scrollContents - > Add ( new CheckBox ( & g_Config . bAnalogIsCircular , co - > T ( " Circular Stick Input " ) ) ) ;
scrollContents - > Add ( new PopupSliderChoiceFloat ( & g_Config . fAnalogAutoRotSpeed , 0.0f , 25.0f , co - > T ( " Auto-rotation speed " ) , 1.0f , screenManager ( ) ) ) ;
scrollContents - > Add ( new Choice ( co - > T ( " Reset to defaults " ) ) ) - > OnClick . Handle ( this , & AnalogSetupScreen : : OnResetToDefaults ) ;
2014-09-05 23:21:07 +02:00
2021-07-09 13:10:16 +02:00
LinearLayout * theTwo = new LinearLayout ( ORIENT_HORIZONTAL , new LinearLayoutParams ( 1.0f ) ) ;
2014-09-05 23:21:07 +02:00
2021-07-09 17:13:08 +02:00
stickView_ [ 0 ] = theTwo - > Add ( new JoystickHistoryView ( StickHistoryViewType : : OUTPUT , co - > T ( " Calibrated " ) , new LinearLayoutParams ( 1.0f ) ) ) ;
2021-07-09 17:04:59 +02:00
stickView_ [ 1 ] = theTwo - > Add ( new JoystickHistoryView ( StickHistoryViewType : : INPUT , co - > T ( " Raw Stick Input " ) , new LinearLayoutParams ( 1.0f ) ) ) ;
2014-09-05 23:21:07 +02:00
2021-07-09 13:10:16 +02:00
rightColumn - > Add ( theTwo ) ;
2014-09-05 23:21:07 +02:00
2021-07-09 13:10:16 +02:00
leftColumn - > Add ( new Button ( di - > T ( " Back " ) , new LayoutParams ( FILL_PARENT , WRAP_CONTENT ) ) ) - > OnClick . Handle < UIScreen > ( this , & UIScreen : : OnBack ) ;
}
2015-01-03 17:55:15 +01:00
2021-07-09 17:13:08 +02:00
UI : : EventReturn AnalogSetupScreen : : OnResetToDefaults ( UI : : EventParams & e ) {
2021-07-09 17:25:00 +02:00
g_Config . fAnalogDeadzone = 0.15f ;
2021-07-09 17:13:08 +02:00
g_Config . fAnalogInverseDeadzone = 0.0f ;
g_Config . fAnalogSensitivity = 1.1f ;
g_Config . bAnalogIsCircular = false ;
g_Config . fAnalogAutoRotSpeed = 8.0f ;
return UI : : EVENT_DONE ;
}
2019-10-02 22:03:02 +02:00
bool TouchTestScreen : : touch ( const TouchInput & touch ) {
UIDialogScreenWithBackground : : touch ( touch ) ;
if ( touch . flags & TOUCH_DOWN ) {
bool found = false ;
for ( int i = 0 ; i < MAX_TOUCH_POINTS ; i + + ) {
if ( touches_ [ i ] . id = = touch . id ) {
2020-08-15 16:13:24 +02:00
WARN_LOG ( SYSTEM , " Double touch " ) ;
2019-10-02 22:03:02 +02:00
touches_ [ i ] . x = touch . x ;
touches_ [ i ] . y = touch . y ;
found = true ;
}
}
if ( ! found ) {
for ( int i = 0 ; i < MAX_TOUCH_POINTS ; i + + ) {
if ( touches_ [ i ] . id = = - 1 ) {
touches_ [ i ] . id = touch . id ;
touches_ [ i ] . x = touch . x ;
touches_ [ i ] . y = touch . y ;
break ;
}
}
}
}
if ( touch . flags & TOUCH_MOVE ) {
bool found = false ;
for ( int i = 0 ; i < MAX_TOUCH_POINTS ; i + + ) {
if ( touches_ [ i ] . id = = touch . id ) {
touches_ [ i ] . x = touch . x ;
touches_ [ i ] . y = touch . y ;
found = true ;
}
}
if ( ! found ) {
2020-08-15 16:13:24 +02:00
WARN_LOG ( SYSTEM , " Move without touch down: %d " , touch . id ) ;
2019-10-02 22:03:02 +02:00
}
}
if ( touch . flags & TOUCH_UP ) {
bool found = false ;
for ( int i = 0 ; i < MAX_TOUCH_POINTS ; i + + ) {
if ( touches_ [ i ] . id = = touch . id ) {
found = true ;
touches_ [ i ] . id = - 1 ;
break ;
}
}
if ( ! found ) {
2020-08-15 16:13:24 +02:00
WARN_LOG ( SYSTEM , " Touch release without touch down " ) ;
2019-10-02 22:03:02 +02:00
}
}
return true ;
}
void TouchTestScreen : : CreateViews ( ) {
using namespace UI ;
2020-01-26 10:43:18 -08:00
auto di = GetI18NCategory ( " Dialog " ) ;
auto gr = GetI18NCategory ( " Graphics " ) ;
2019-10-02 22:03:02 +02:00
root_ = new LinearLayout ( ORIENT_VERTICAL ) ;
2021-07-09 17:04:59 +02:00
LinearLayout * theTwo = new LinearLayout ( ORIENT_VERTICAL , new LinearLayoutParams ( 1.0f ) ) ;
lastLastKeyEvent_ = theTwo - > Add ( new TextView ( " - " , new LayoutParams ( FILL_PARENT , WRAP_CONTENT ) ) ) ;
lastLastKeyEvent_ - > SetTextColor ( 0x80FFFFFF ) ; // semi-transparent
lastKeyEvent_ = theTwo - > Add ( new TextView ( " - " , new LayoutParams ( FILL_PARENT , WRAP_CONTENT ) ) ) ;
2019-10-02 22:03:02 +02:00
root_ - > Add ( theTwo ) ;
2020-05-09 14:06:54 -07:00
# if !PPSSPP_PLATFORM(UWP)
static const char * renderingBackend [ ] = { " OpenGL " , " Direct3D 9 " , " Direct3D 11 " , " Vulkan " } ;
PopupMultiChoice * renderingBackendChoice = root_ - > Add ( new PopupMultiChoice ( & g_Config . iGPUBackend , gr - > T ( " Backend " ) , renderingBackend , ( int ) GPUBackend : : OPENGL , ARRAY_SIZE ( renderingBackend ) , gr - > GetName ( ) , screenManager ( ) ) ) ;
renderingBackendChoice - > OnChoice . Handle ( this , & TouchTestScreen : : OnRenderingBackend ) ;
if ( ! g_Config . IsBackendEnabled ( GPUBackend : : OPENGL ) )
renderingBackendChoice - > HideChoice ( ( int ) GPUBackend : : OPENGL ) ;
if ( ! g_Config . IsBackendEnabled ( GPUBackend : : DIRECT3D9 ) )
renderingBackendChoice - > HideChoice ( ( int ) GPUBackend : : DIRECT3D9 ) ;
if ( ! g_Config . IsBackendEnabled ( GPUBackend : : DIRECT3D11 ) )
renderingBackendChoice - > HideChoice ( ( int ) GPUBackend : : DIRECT3D11 ) ;
if ( ! g_Config . IsBackendEnabled ( GPUBackend : : VULKAN ) )
renderingBackendChoice - > HideChoice ( ( int ) GPUBackend : : VULKAN ) ;
# endif
# if PPSSPP_PLATFORM(ANDROID)
root_ - > Add ( new Choice ( gr - > T ( " Recreate Activity " ) ) ) - > OnClick . Handle ( this , & TouchTestScreen : : OnRecreateActivity ) ;
# endif
2019-10-02 22:03:02 +02:00
root_ - > Add ( new CheckBox ( & g_Config . bImmersiveMode , gr - > T ( " FullScreen " , " Full Screen " ) ) ) - > OnClick . Handle ( this , & TouchTestScreen : : OnImmersiveModeChange ) ;
root_ - > Add ( new Button ( di - > T ( " Back " ) ) ) - > OnClick . Handle < UIScreen > ( this , & UIScreen : : OnBack ) ;
}
2019-10-06 13:21:57 +02:00
# if PPSSPP_PLATFORM(ANDROID)
extern int display_xres ;
extern int display_yres ;
# endif
2021-07-09 17:04:59 +02:00
bool TouchTestScreen : : key ( const KeyInput & key ) {
char buf [ 512 ] ;
snprintf ( buf , sizeof ( buf ) , " Keycode: %d Device ID: %d [%s%s%s%s] " , key . keyCode , key . deviceId ,
( key . flags & KEY_IS_REPEAT ) ? " REP " : " " ,
( key . flags & KEY_UP ) ? " UP " : " " ,
( key . flags & KEY_DOWN ) ? " DOWN " : " " ,
( key . flags & KEY_CHAR ) ? " CHAR " : " " ) ;
if ( lastLastKeyEvent_ & & lastKeyEvent_ ) {
lastLastKeyEvent_ - > SetText ( lastKeyEvent_ - > GetText ( ) ) ;
lastKeyEvent_ - > SetText ( buf ) ;
}
return true ;
}
bool TouchTestScreen : : axis ( const AxisInput & axis ) {
// This is mainly to catch axis events that would otherwise get translated
// into arrow keys, since seeing keyboard arrow key events appear when using
// a controller would be confusing for the user.
if ( IgnoreAxisForMapping ( axis . axisId ) )
return false ;
const float AXIS_LOG_THRESHOLD = AXIS_BIND_THRESHOLD * 0.5f ;
if ( axis . value > AXIS_LOG_THRESHOLD | | axis . value < - AXIS_LOG_THRESHOLD ) {
char buf [ 512 ] ;
snprintf ( buf , sizeof ( buf ) , " Axis: %d (value %1.3f) Device ID: %d " ,
axis . axisId , axis . value , axis . deviceId ) ;
// Null-check just in case they weren't created yet.
if ( lastLastKeyEvent_ & & lastKeyEvent_ ) {
lastLastKeyEvent_ - > SetText ( lastKeyEvent_ - > GetText ( ) ) ;
lastKeyEvent_ - > SetText ( buf ) ;
}
}
return true ;
}
2019-10-02 22:03:02 +02:00
void TouchTestScreen : : render ( ) {
UIDialogScreenWithBackground : : render ( ) ;
2019-10-03 18:31:20 +02:00
UIContext * ui_context = screenManager ( ) - > getUIContext ( ) ;
2020-03-31 16:46:14 +02:00
Bounds bounds = ui_context - > GetLayoutBounds ( ) ;
2019-10-03 18:31:20 +02:00
ui_context - > BeginNoTex ( ) ;
2019-10-02 22:03:02 +02:00
for ( int i = 0 ; i < MAX_TOUCH_POINTS ; i + + ) {
if ( touches_ [ i ] . id ! = - 1 ) {
2019-10-03 18:31:20 +02:00
ui_context - > Draw ( ) - > Circle ( touches_ [ i ] . x , touches_ [ i ] . y , 100.0 , 3.0 , 80 , 0.0f , 0xFFFFFFFF , 1.0 ) ;
2019-10-02 22:03:02 +02:00
}
}
2019-10-03 18:31:20 +02:00
ui_context - > Flush ( ) ;
ui_context - > Begin ( ) ;
char buffer [ 1024 ] ;
for ( int i = 0 ; i < MAX_TOUCH_POINTS ; i + + ) {
if ( touches_ [ i ] . id ! = - 1 ) {
ui_context - > Draw ( ) - > Circle ( touches_ [ i ] . x , touches_ [ i ] . y , 100.0 , 3.0 , 80 , 0.0f , 0xFFFFFFFF , 1.0 ) ;
snprintf ( buffer , sizeof ( buffer ) , " %0.1fx%0.1f " , touches_ [ i ] . x , touches_ [ i ] . y ) ;
ui_context - > DrawText ( buffer , touches_ [ i ] . x , touches_ [ i ] . y + ( touches_ [ i ] . y > dp_yres - 100.0f ? - 135.0f : 95.0f ) , 0xFFFFFFFF , ALIGN_HCENTER | FLAG_DYNAMIC_ASCII ) ;
}
}
snprintf ( buffer , sizeof ( buffer ) ,
2019-10-06 13:21:57 +02:00
# if PPSSPP_PLATFORM(ANDROID)
" display_res: %dx%d \n "
# endif
2019-10-03 18:31:20 +02:00
" dp_res: %dx%d \n "
" pixel_res: %dx%d \n "
" g_dpi: %f \n "
" g_dpi_scale: %0.3fx%0.3f \n "
" g_dpi_scale_real: %0.3fx%0.3f \n " ,
2019-10-06 13:21:57 +02:00
# if PPSSPP_PLATFORM(ANDROID)
display_xres , display_yres ,
# endif
2019-10-03 18:31:20 +02:00
dp_xres , dp_yres ,
pixel_xres , pixel_yres ,
g_dpi ,
g_dpi_scale_x , g_dpi_scale_y ,
g_dpi_scale_real_x , g_dpi_scale_real_y ) ;
2021-07-09 17:04:59 +02:00
ui_context - > DrawTextShadow ( buffer , bounds . centerX ( ) , bounds . y + 20.0f , 0xFFFFFFFF , FLAG_DYNAMIC_ASCII ) ;
2019-10-03 18:31:20 +02:00
ui_context - > Flush ( ) ;
2019-10-02 22:03:02 +02:00
}
void RecreateActivity ( ) ;
UI : : EventReturn TouchTestScreen : : OnImmersiveModeChange ( UI : : EventParams & e ) {
System_SendMessage ( " immersive " , " " ) ;
if ( g_Config . iAndroidHwScale ! = 0 ) {
RecreateActivity ( ) ;
}
return UI : : EVENT_DONE ;
}
2020-05-09 14:06:54 -07:00
UI : : EventReturn TouchTestScreen : : OnRenderingBackend ( UI : : EventParams & e ) {
g_Config . Save ( " GameSettingsScreen::RenderingBackend " ) ;
System_SendMessage ( " graphics_restart " , " --touchscreentest " ) ;
return UI : : EVENT_DONE ;
}
UI : : EventReturn TouchTestScreen : : OnRecreateActivity ( UI : : EventParams & e ) {
RecreateActivity ( ) ;
return UI : : EVENT_DONE ;
}