2019-10-31 18:00:42 +00:00
# include "SwitchVirtualGamepadHandler.h"
SwitchVirtualGamepadHandler : : SwitchVirtualGamepadHandler ( std : : unique_ptr < IController > & & controller )
2020-04-22 13:42:06 +00:00
: m_controller ( std : : move ( controller ) )
2019-10-31 18:00:42 +00:00
{
}
SwitchVirtualGamepadHandler : : ~ SwitchVirtualGamepadHandler ( )
{
}
Result SwitchVirtualGamepadHandler : : Initialize ( )
{
2020-04-22 13:42:06 +00:00
return m_controller - > Initialize ( ) ;
2019-10-31 18:00:42 +00:00
}
void SwitchVirtualGamepadHandler : : Exit ( )
{
2020-04-22 13:42:06 +00:00
m_controller - > Exit ( ) ;
2019-10-31 18:00:42 +00:00
}
2019-12-04 18:44:01 +00:00
void SwitchVirtualGamepadHandler : : InputThreadLoop ( void * handler )
2019-10-31 18:00:42 +00:00
{
2020-04-22 13:42:06 +00:00
do
{
2020-02-20 00:27:19 +00:00
static_cast < SwitchVirtualGamepadHandler * > ( handler ) - > UpdateInput ( ) ;
2020-04-22 13:42:06 +00:00
} while ( static_cast < SwitchVirtualGamepadHandler * > ( handler ) - > m_inputThreadIsRunning ) ;
2019-10-31 18:00:42 +00:00
}
2019-12-04 18:44:01 +00:00
void SwitchVirtualGamepadHandler : : OutputThreadLoop ( void * handler )
2019-10-31 18:00:42 +00:00
{
2020-04-22 13:42:06 +00:00
do
{
static_cast < SwitchVirtualGamepadHandler * > ( handler ) - > UpdateOutput ( ) ;
} while ( static_cast < SwitchVirtualGamepadHandler * > ( handler ) - > m_outputThreadIsRunning ) ;
2019-10-31 18:00:42 +00:00
}
2019-11-06 12:28:56 +00:00
Result SwitchVirtualGamepadHandler : : InitInputThread ( )
2019-10-31 18:00:42 +00:00
{
2020-02-20 00:27:19 +00:00
m_inputThreadIsRunning = true ;
2020-05-13 12:00:25 +00:00
R_ABORT_UNLESS ( threadCreate ( & m_inputThread , & SwitchVirtualGamepadHandler : : InputThreadLoop , this , input_thread_stack , sizeof ( input_thread_stack ) , 0x30 , - 2 ) ) ;
R_ABORT_UNLESS ( threadStart ( & m_inputThread ) ) ;
return 0 ;
2019-10-31 18:00:42 +00:00
}
void SwitchVirtualGamepadHandler : : ExitInputThread ( )
{
2020-02-20 00:27:19 +00:00
m_inputThreadIsRunning = false ;
2020-05-13 12:00:25 +00:00
svcCancelSynchronization ( m_inputThread . handle ) ;
threadWaitForExit ( & m_inputThread ) ;
threadClose ( & m_inputThread ) ;
2019-10-31 18:00:42 +00:00
}
2019-11-06 12:28:56 +00:00
Result SwitchVirtualGamepadHandler : : InitOutputThread ( )
2019-10-31 18:00:42 +00:00
{
2020-02-20 00:27:19 +00:00
m_outputThreadIsRunning = true ;
2020-05-13 12:00:25 +00:00
R_ABORT_UNLESS ( threadCreate ( & m_outputThread , & SwitchVirtualGamepadHandler : : OutputThreadLoop , this , output_thread_stack , sizeof ( output_thread_stack ) , 0x30 , - 2 ) ) ;
R_ABORT_UNLESS ( threadStart ( & m_outputThread ) ) ;
return 0 ;
2019-10-31 18:00:42 +00:00
}
void SwitchVirtualGamepadHandler : : ExitOutputThread ( )
{
2020-02-20 00:27:19 +00:00
m_outputThreadIsRunning = false ;
2020-05-13 12:00:25 +00:00
svcCancelSynchronization ( m_outputThread . handle ) ;
threadWaitForExit ( & m_outputThread ) ;
threadClose ( & m_outputThread ) ;
2020-04-22 13:42:06 +00:00
}
static_assert ( JOYSTICK_MAX = = 32767 & & JOYSTICK_MIN = = - 32767 ,
" JOYSTICK_MAX and/or JOYSTICK_MIN has incorrect values. Update libnx " ) ;
void SwitchVirtualGamepadHandler : : ConvertAxisToSwitchAxis ( float x , float y , float deadzone , s32 * x_out , s32 * y_out )
{
float floatRange = 2.0f ;
//JOYSTICK_MAX is 1 above and JOYSTICK_MIN is 1 below acceptable joystick values, causing crashes on various games including Xenoblade Chronicles 2 and Resident Evil 4
float newRange = ( JOYSTICK_MAX - JOYSTICK_MIN ) ;
* x_out = ( ( ( x + 1.0f ) * newRange ) / floatRange ) + JOYSTICK_MIN ;
* y_out = ( ( ( y + 1.0f ) * newRange ) / floatRange ) + JOYSTICK_MIN ;
/*
OldRange = ( OldMax - OldMin )
NewRange = ( NewMax - NewMin )
NewValue = ( ( ( OldValue - OldMin ) * NewRange ) / OldRange ) + NewMin
*/
}
Result SwitchVirtualGamepadHandler : : SetControllerVibration ( float strong_mag , float weak_mag )
{
strong_mag = std : : max < float > ( 0.0f , std : : min < float > ( strong_mag , 1.0f ) ) ;
weak_mag = std : : max < float > ( 0.0f , std : : min < float > ( weak_mag , 1.0f ) ) ;
return m_controller - > SetRumble ( static_cast < uint8_t > ( strong_mag * 255.0f ) , static_cast < uint8_t > ( weak_mag * 255.0f ) ) ;
2019-10-31 18:00:42 +00:00
}