2020-12-05 13:08:24 +01:00
# include "stdafx.h"
2016-03-21 20:43:03 +01:00
# include "Emu/IdManager.h"
2022-07-04 15:02:17 +02:00
# include "Emu/System.h"
2016-03-21 20:43:03 +01:00
# include "Emu/Cell/PPUModule.h"
2014-08-23 22:40:04 +02:00
2016-03-21 20:43:03 +01:00
# include "Emu/Io/KeyboardHandler.h"
2014-09-03 18:33:30 +02:00
# include "cellKb.h"
2013-09-11 22:49:49 +02:00
2020-09-26 09:08:12 +02:00
extern void libio_sys_config_init ( ) ;
extern void libio_sys_config_end ( ) ;
2020-01-31 10:01:17 +01:00
LOG_CHANNEL ( sys_io ) ;
2013-09-11 22:49:49 +02:00
2017-05-15 13:30:14 +02:00
template < >
void fmt_class_string < CellKbError > : : format ( std : : string & out , u64 arg )
{
format_enum ( out , arg , [ ] ( auto error )
{
switch ( error )
{
STR_CASE ( CELL_KB_ERROR_FATAL ) ;
STR_CASE ( CELL_KB_ERROR_INVALID_PARAMETER ) ;
STR_CASE ( CELL_KB_ERROR_ALREADY_INITIALIZED ) ;
STR_CASE ( CELL_KB_ERROR_UNINITIALIZED ) ;
STR_CASE ( CELL_KB_ERROR_RESOURCE_ALLOCATION_FAILED ) ;
STR_CASE ( CELL_KB_ERROR_READ_FAILED ) ;
STR_CASE ( CELL_KB_ERROR_NO_DEVICE ) ;
STR_CASE ( CELL_KB_ERROR_SYS_SETTING_FAILED ) ;
}
return unknown ;
} ) ;
}
2022-07-04 15:02:17 +02:00
KeyboardHandlerBase : : KeyboardHandlerBase ( utils : : serial * ar )
{
if ( ! ar )
{
return ;
}
( * ar ) ( m_info . max_connect ) ;
if ( m_info . max_connect )
{
Emu . DeferDeserialization ( [ this ] ( )
{
Init ( m_info . max_connect ) ;
init . init ( ) ;
} ) ;
}
}
void KeyboardHandlerBase : : save ( utils : : serial & ar )
{
const auto inited = init . access ( ) ;
ar ( inited ? m_info . max_connect : 0 ) ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbInit ( u32 max_connect )
2013-09-11 22:49:49 +02:00
{
2016-01-12 22:57:16 +01:00
sys_io . warning ( " cellKbInit(max_connect=%d) " , max_connect ) ;
2015-01-26 20:01:47 +01:00
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2016-03-21 20:43:03 +01:00
2021-06-17 19:20:11 +02:00
auto init = handler . init . init ( ) ;
2019-09-19 00:50:08 +02:00
if ( ! init )
2016-03-21 20:43:03 +01:00
return CELL_KB_ERROR_ALREADY_INITIALIZED ;
2018-07-24 21:58:30 +02:00
if ( max_connect = = 0 | | max_connect > CELL_KB_MAX_KEYBOARDS )
2021-06-17 19:20:11 +02:00
{
init . cancel ( ) ;
2018-07-24 21:58:30 +02:00
return CELL_KB_ERROR_INVALID_PARAMETER ;
2021-06-17 19:20:11 +02:00
}
2018-07-24 21:58:30 +02:00
2020-09-26 09:08:12 +02:00
libio_sys_config_init ( ) ;
2021-03-02 12:59:19 +01:00
handler . Init ( std : : min ( max_connect , 7u ) ) ;
2015-01-26 20:01:47 +01:00
2013-09-11 22:49:49 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbEnd ( )
2013-09-11 22:49:49 +02:00
{
2016-03-21 20:43:03 +01:00
sys_io . notice ( " cellKbEnd() " ) ;
2015-01-26 20:01:47 +01:00
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2019-09-19 00:50:08 +02:00
2021-03-02 12:59:19 +01:00
const auto init = handler . init . reset ( ) ;
2019-09-19 00:50:08 +02:00
if ( ! init )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_UNINITIALIZED ;
2019-09-19 00:50:08 +02:00
// TODO
2020-09-26 09:08:12 +02:00
libio_sys_config_end ( ) ;
2013-09-11 22:49:49 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbClearBuf ( u32 port_no )
2013-09-11 22:49:49 +02:00
{
2016-01-12 22:57:16 +01:00
sys_io . trace ( " cellKbClearBuf(port_no=%d) " , port_no ) ;
2015-01-26 20:01:47 +01:00
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2016-03-21 20:43:03 +01:00
2021-03-02 12:59:19 +01:00
const auto init = handler . init . access ( ) ;
2019-09-19 00:50:08 +02:00
if ( ! init )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_UNINITIALIZED ;
2018-07-24 21:58:30 +02:00
if ( port_no > = CELL_KB_MAX_KEYBOARDS )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_INVALID_PARAMETER ;
2013-09-11 22:49:49 +02:00
2021-03-02 12:59:19 +01:00
std : : lock_guard < std : : mutex > lock ( handler . m_mutex ) ;
2018-07-17 01:23:14 +02:00
2021-03-02 12:59:19 +01:00
const KbInfo & current_info = handler . GetInfo ( ) ;
2018-07-24 21:58:30 +02:00
2021-03-02 12:59:19 +01:00
if ( port_no > = handler . GetKeyboards ( ) . size ( ) | | current_info . status [ port_no ] ! = CELL_KB_STATUS_CONNECTED )
2018-07-24 21:58:30 +02:00
return CELL_KB_ERROR_NO_DEVICE ;
2021-03-02 12:59:19 +01:00
KbData & current_data = handler . GetData ( port_no ) ;
2018-07-24 21:58:30 +02:00
current_data . len = 0 ;
current_data . led = 0 ;
current_data . mkey = 0 ;
for ( int i = 0 ; i < CELL_KB_MAX_KEYCODES ; i + + )
{
2022-04-04 21:04:04 +02:00
current_data . buttons [ i ] = KbButton ( CELL_KEYC_NO_EVENT , 0 , false ) ;
2018-07-24 21:58:30 +02:00
}
2013-09-11 22:49:49 +02:00
return CELL_OK ;
}
u16 cellKbCnvRawCode ( u32 arrange , u32 mkey , u32 led , u16 rawcode )
{
2019-08-17 16:21:37 +02:00
sys_io . trace ( " cellKbCnvRawCode(arrange=%d, mkey=%d, led=%d, rawcode=0x%x) " , arrange , mkey , led , rawcode ) ;
2013-09-11 22:49:49 +02:00
// CELL_KB_RAWDAT
2021-11-15 18:28:19 +01:00
if ( rawcode < = CELL_KEYC_E_UNDEF | |
rawcode = = CELL_KEYC_ESCAPE | |
rawcode = = CELL_KEYC_106_KANJI | |
( rawcode > = CELL_KEYC_CAPS_LOCK & & rawcode < = CELL_KEYC_NUM_LOCK ) | |
rawcode = = CELL_KEYC_APPLICATION | |
rawcode = = CELL_KEYC_KANA | |
rawcode = = CELL_KEYC_HENKAN | |
rawcode = = CELL_KEYC_MUHENKAN )
2015-01-26 20:01:47 +01:00
{
2021-11-15 18:28:19 +01:00
return rawcode | CELL_KB_RAWDAT ;
2015-01-26 20:01:47 +01:00
}
2013-09-11 22:49:49 +02:00
2019-08-17 16:21:37 +02:00
const bool is_alt = mkey & ( CELL_KB_MKEY_L_ALT | CELL_KB_MKEY_R_ALT ) ;
const bool is_shift = mkey & ( CELL_KB_MKEY_L_SHIFT | CELL_KB_MKEY_R_SHIFT ) ;
const bool is_caps_lock = led & ( CELL_KB_LED_CAPS_LOCK ) ;
const bool is_num_lock = led & ( CELL_KB_LED_NUM_LOCK ) ;
2013-09-11 22:49:49 +02:00
// CELL_KB_NUMPAD
2019-08-17 16:21:37 +02:00
if ( is_num_lock )
{
2021-11-15 18:28:19 +01:00
//if (rawcode == CELL_KEYC_KPAD_NUMLOCK) return 0x00 | CELL_KB_KEYPAD; // 'Num Lock' (unreachable)
if ( rawcode = = CELL_KEYC_KPAD_SLASH ) return 0x2F | CELL_KB_KEYPAD ; // '/'
if ( rawcode = = CELL_KEYC_KPAD_ASTERISK ) return 0x2A | CELL_KB_KEYPAD ; // '*'
if ( rawcode = = CELL_KEYC_KPAD_MINUS ) return 0x2D | CELL_KB_KEYPAD ; // '-'
if ( rawcode = = CELL_KEYC_KPAD_PLUS ) return 0x2B | CELL_KB_KEYPAD ; // '+'
if ( rawcode = = CELL_KEYC_KPAD_ENTER ) return 0x0A | CELL_KB_KEYPAD ; // '\n'
if ( rawcode = = CELL_KEYC_KPAD_0 ) return 0x30 | CELL_KB_KEYPAD ; // '0'
if ( rawcode > = CELL_KEYC_KPAD_1 & & rawcode < = CELL_KEYC_KPAD_9 ) return ( rawcode - 0x28 ) | CELL_KB_KEYPAD ; // '1' - '9'
2019-08-17 16:21:37 +02:00
}
2018-07-17 01:23:14 +02:00
2019-08-17 16:21:37 +02:00
// ASCII
2018-07-17 01:23:14 +02:00
2019-08-17 16:21:37 +02:00
const auto get_ascii = [ is_alt , is_shift , is_caps_lock ] ( u16 raw , u16 shifted = 0 , u16 altered = 0 )
2018-07-17 01:23:14 +02:00
{
2019-08-17 16:21:37 +02:00
if ( ( is_shift | | is_caps_lock ) & & shifted )
{
return shifted ;
}
else if ( is_alt & & altered )
{
return altered ;
}
return raw ;
2018-07-17 01:23:14 +02:00
} ;
if ( arrange = = CELL_KB_MAPPING_106 ) // (Japanese)
{
2019-08-17 16:21:37 +02:00
if ( rawcode = = CELL_KEYC_1 ) return get_ascii ( ' 1 ' , ' ! ' ) ;
if ( rawcode = = CELL_KEYC_2 ) return get_ascii ( ' 2 ' , ' " ' ) ;
if ( rawcode = = CELL_KEYC_3 ) return get_ascii ( ' 3 ' , ' # ' ) ;
if ( rawcode = = CELL_KEYC_4 ) return get_ascii ( ' 4 ' , ' $ ' ) ;
if ( rawcode = = CELL_KEYC_5 ) return get_ascii ( ' 5 ' , ' % ' ) ;
if ( rawcode = = CELL_KEYC_6 ) return get_ascii ( ' 6 ' , ' & ' ) ;
if ( rawcode = = CELL_KEYC_7 ) return get_ascii ( ' 7 ' , ' \' ' ) ;
if ( rawcode = = CELL_KEYC_8 ) return get_ascii ( ' 8 ' , ' ( ' ) ;
if ( rawcode = = CELL_KEYC_9 ) return get_ascii ( ' 9 ' , ' ) ' ) ;
if ( rawcode = = CELL_KEYC_0 ) return get_ascii ( ' 0 ' , ' ~ ' ) ;
if ( rawcode = = CELL_KEYC_ACCENT_CIRCONFLEX_106 ) return get_ascii ( ' ^ ' , ' ~ ' ) ;
if ( rawcode = = CELL_KEYC_ATMARK_106 ) return get_ascii ( ' @ ' , ' ` ' ) ;
if ( rawcode = = CELL_KEYC_LEFT_BRACKET_106 ) return get_ascii ( ' [ ' , ' { ' ) ;
if ( rawcode = = CELL_KEYC_RIGHT_BRACKET_106 ) return get_ascii ( ' ] ' , ' } ' ) ;
if ( rawcode = = CELL_KEYC_SEMICOLON ) return get_ascii ( ' ; ' , ' + ' ) ;
if ( rawcode = = CELL_KEYC_COLON_106 ) return get_ascii ( ' : ' , ' * ' ) ;
if ( rawcode = = CELL_KEYC_COMMA ) return get_ascii ( ' , ' , ' < ' ) ;
if ( rawcode = = CELL_KEYC_PERIOD ) return get_ascii ( ' . ' , ' > ' ) ;
if ( rawcode = = CELL_KEYC_SLASH ) return get_ascii ( ' / ' , ' ? ' ) ;
if ( rawcode = = CELL_KEYC_BACKSLASH_106 ) return get_ascii ( ' \\ ' , ' _ ' ) ;
2019-08-17 21:28:01 +02:00
if ( rawcode = = CELL_KEYC_YEN_106 ) return get_ascii ( 190 , ' | ' ) ; // ¥
2018-07-17 01:23:14 +02:00
}
else if ( arrange = = CELL_KB_MAPPING_101 ) // (US)
{
2019-08-17 16:21:37 +02:00
if ( rawcode = = CELL_KEYC_1 ) return get_ascii ( ' 1 ' , ' ! ' ) ;
if ( rawcode = = CELL_KEYC_2 ) return get_ascii ( ' 2 ' , ' @ ' ) ;
if ( rawcode = = CELL_KEYC_3 ) return get_ascii ( ' 3 ' , ' # ' ) ;
if ( rawcode = = CELL_KEYC_4 ) return get_ascii ( ' 4 ' , ' $ ' ) ;
if ( rawcode = = CELL_KEYC_5 ) return get_ascii ( ' 5 ' , ' % ' ) ;
if ( rawcode = = CELL_KEYC_6 ) return get_ascii ( ' 6 ' , ' ^ ' ) ;
if ( rawcode = = CELL_KEYC_7 ) return get_ascii ( ' 7 ' , ' & ' ) ;
if ( rawcode = = CELL_KEYC_8 ) return get_ascii ( ' 8 ' , ' * ' ) ;
if ( rawcode = = CELL_KEYC_9 ) return get_ascii ( ' 9 ' , ' ( ' ) ;
if ( rawcode = = CELL_KEYC_0 ) return get_ascii ( ' 0 ' , ' ) ' ) ;
if ( rawcode = = CELL_KEYC_MINUS ) return get_ascii ( ' - ' , ' _ ' ) ;
if ( rawcode = = CELL_KEYC_EQUAL_101 ) return get_ascii ( ' = ' , ' + ' ) ;
if ( rawcode = = CELL_KEYC_LEFT_BRACKET_101 ) return get_ascii ( ' [ ' , ' { ' ) ;
if ( rawcode = = CELL_KEYC_RIGHT_BRACKET_101 ) return get_ascii ( ' ] ' , ' } ' ) ;
if ( rawcode = = CELL_KEYC_BACKSLASH_101 ) return get_ascii ( ' \\ ' , ' | ' ) ;
if ( rawcode = = CELL_KEYC_SEMICOLON ) return get_ascii ( ' ; ' , ' : ' ) ;
if ( rawcode = = CELL_KEYC_QUOTATION_101 ) return get_ascii ( ' \' ' , ' " ' ) ;
if ( rawcode = = CELL_KEYC_COMMA ) return get_ascii ( ' , ' , ' < ' ) ;
if ( rawcode = = CELL_KEYC_PERIOD ) return get_ascii ( ' . ' , ' > ' ) ;
if ( rawcode = = CELL_KEYC_SLASH ) return get_ascii ( ' / ' , ' ? ' ) ;
if ( rawcode = = CELL_KEYC_BACK_QUOTE ) return get_ascii ( ' ` ' , ' ~ ' ) ;
2018-07-17 01:23:14 +02:00
}
else if ( arrange = = CELL_KB_MAPPING_GERMAN_GERMANY )
{
2019-08-17 16:21:37 +02:00
if ( rawcode = = CELL_KEYC_1 ) return get_ascii ( ' 1 ' , ' ! ' ) ;
if ( rawcode = = CELL_KEYC_2 ) return get_ascii ( ' 2 ' , ' " ' ) ;
2019-08-17 21:28:01 +02:00
if ( rawcode = = CELL_KEYC_3 ) return get_ascii ( ' 3 ' , 245 ) ; // §
2019-08-17 16:21:37 +02:00
if ( rawcode = = CELL_KEYC_4 ) return get_ascii ( ' 4 ' , ' $ ' ) ;
if ( rawcode = = CELL_KEYC_5 ) return get_ascii ( ' 5 ' , ' % ' ) ;
if ( rawcode = = CELL_KEYC_6 ) return get_ascii ( ' 6 ' , ' & ' ) ;
if ( rawcode = = CELL_KEYC_7 ) return get_ascii ( ' 7 ' , ' / ' , ' { ' ) ;
if ( rawcode = = CELL_KEYC_8 ) return get_ascii ( ' 8 ' , ' ( ' , ' [ ' ) ;
if ( rawcode = = CELL_KEYC_9 ) return get_ascii ( ' 9 ' , ' ) ' , ' ] ' ) ;
if ( rawcode = = CELL_KEYC_0 ) return get_ascii ( ' 0 ' , ' = ' , ' } ' ) ;
if ( rawcode = = CELL_KEYC_MINUS ) return get_ascii ( ' - ' , ' _ ' ) ;
2019-08-17 21:28:01 +02:00
if ( rawcode = = CELL_KEYC_ACCENT_CIRCONFLEX_106 ) return get_ascii ( ' ^ ' , 248 ) ; // °
2019-08-17 16:21:37 +02:00
if ( rawcode = = CELL_KEYC_COMMA ) return get_ascii ( ' , ' , ' ; ' ) ;
if ( rawcode = = CELL_KEYC_PERIOD ) return get_ascii ( ' . ' , ' : ' ) ;
if ( rawcode = = CELL_KEYC_KPAD_PLUS ) return get_ascii ( ' + ' , ' * ' , ' ~ ' ) ;
if ( rawcode = = CELL_KEYC_LESS ) return get_ascii ( ' < ' , ' > ' , ' | ' ) ;
if ( rawcode = = CELL_KEYC_HASHTAG ) return get_ascii ( ' # ' , ' \' ' ) ;
2019-08-17 21:28:01 +02:00
if ( rawcode = = CELL_KEYC_SSHARP ) return get_ascii ( 225 , ' ? ' , ' \\ ' ) ; // ß
if ( rawcode = = CELL_KEYC_BACK_QUOTE ) return get_ascii ( 239 , ' ` ' ) ; // ´
2019-08-17 16:21:37 +02:00
if ( rawcode = = CELL_KEYC_Q ) return get_ascii ( ' q ' , ' Q ' , ' @ ' ) ;
2018-07-17 01:23:14 +02:00
}
2021-11-15 18:28:19 +01:00
if ( rawcode > = CELL_KEYC_A & & rawcode < = CELL_KEYC_Z ) // 'A' - 'Z'
2013-09-13 19:29:54 +02:00
{
2018-02-09 15:49:37 +01:00
rawcode - =
2018-07-17 01:23:14 +02:00
( is_shift )
? ( ( led & ( CELL_KB_LED_CAPS_LOCK ) ) ? 0 : 0x20 )
: ( ( led & ( CELL_KB_LED_CAPS_LOCK ) ) ? 0x20 : 0 ) ;
2013-09-13 19:29:54 +02:00
return rawcode + 0x5D ;
2017-12-31 12:01:11 +01:00
}
2021-11-15 18:28:19 +01:00
if ( rawcode > = CELL_KEYC_1 & & rawcode < = CELL_KEYC_9 ) return rawcode + 0x13 ; // '1' - '9'
if ( rawcode = = CELL_KEYC_0 ) return 0x30 ; // '0'
if ( rawcode = = CELL_KEYC_ENTER ) return 0x0A ; // '\n'
//if (rawcode == CELL_KEYC_ESC) return 0x1B; // 'ESC' (unreachable)
if ( rawcode = = CELL_KEYC_BS ) return 0x08 ; // '\b'
if ( rawcode = = CELL_KEYC_TAB ) return 0x09 ; // '\t'
if ( rawcode = = CELL_KEYC_SPACE ) return 0x20 ; // 'space'
2013-09-11 22:49:49 +02:00
2019-08-17 16:21:37 +02:00
// TODO: Add more keys and layouts
2013-09-11 22:49:49 +02:00
return 0x0000 ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbGetInfo ( vm : : ptr < CellKbInfo > info )
2013-09-11 22:49:49 +02:00
{
2016-01-12 22:57:16 +01:00
sys_io . trace ( " cellKbGetInfo(info=*0x%x) " , info ) ;
2015-01-26 20:01:47 +01:00
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2019-09-19 00:50:08 +02:00
2021-03-02 12:59:19 +01:00
const auto init = handler . init . access ( ) ;
2016-03-21 20:43:03 +01:00
2019-09-19 00:50:08 +02:00
if ( ! init )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_UNINITIALIZED ;
2013-09-11 22:49:49 +02:00
2018-07-24 21:58:30 +02:00
if ( ! info )
return CELL_KB_ERROR_INVALID_PARAMETER ;
2019-12-20 04:51:16 +01:00
std : : memset ( info . get_ptr ( ) , 0 , info . size ( ) ) ;
2021-03-02 12:59:19 +01:00
std : : lock_guard < std : : mutex > lock ( handler . m_mutex ) ;
2018-07-17 01:23:14 +02:00
2021-03-02 12:59:19 +01:00
const KbInfo & current_info = handler . GetInfo ( ) ;
2014-08-28 03:18:35 +02:00
info - > max_connect = current_info . max_connect ;
info - > now_connect = current_info . now_connect ;
info - > info = current_info . info ;
2015-01-26 20:01:47 +01:00
2018-07-24 21:58:30 +02:00
for ( u32 i = 0 ; i < CELL_KB_MAX_KEYBOARDS ; i + + )
2013-09-11 22:49:49 +02:00
{
2014-08-28 03:18:35 +02:00
info - > status [ i ] = current_info . status [ i ] ;
2013-09-11 22:49:49 +02:00
}
2017-12-31 12:01:11 +01:00
2013-09-11 22:49:49 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbRead ( u32 port_no , vm : : ptr < CellKbData > data )
2013-09-11 22:49:49 +02:00
{
2016-01-12 22:57:16 +01:00
sys_io . trace ( " cellKbRead(port_no=%d, data=*0x%x) " , port_no , data ) ;
2013-09-11 22:49:49 +02:00
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2016-03-21 20:43:03 +01:00
2021-03-02 12:59:19 +01:00
const auto init = handler . init . access ( ) ;
2019-09-19 00:50:08 +02:00
if ( ! init )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_UNINITIALIZED ;
2018-07-24 21:58:30 +02:00
if ( port_no > = CELL_KB_MAX_KEYBOARDS | | ! data )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_INVALID_PARAMETER ;
2013-09-11 22:49:49 +02:00
2021-03-02 12:59:19 +01:00
std : : lock_guard < std : : mutex > lock ( handler . m_mutex ) ;
2018-07-17 01:23:14 +02:00
2021-03-02 12:59:19 +01:00
const KbInfo & current_info = handler . GetInfo ( ) ;
2018-07-24 21:58:30 +02:00
2021-03-02 12:59:19 +01:00
if ( port_no > = handler . GetKeyboards ( ) . size ( ) | | current_info . status [ port_no ] ! = CELL_KB_STATUS_CONNECTED )
2018-07-24 21:58:30 +02:00
return CELL_KB_ERROR_NO_DEVICE ;
2021-03-02 12:59:19 +01:00
KbData & current_data = handler . GetData ( port_no ) ;
2022-04-19 22:30:20 +02:00
if ( current_info . is_null_handler | | ( current_info . info & CELL_KB_INFO_INTERCEPTED ) )
{
data - > led = 0 ;
data - > mkey = 0 ;
data - > len = 0 ;
}
else
{
data - > led = current_data . led ;
data - > mkey = current_data . mkey ;
data - > len = std : : min < s32 > ( CELL_KB_MAX_KEYCODES , current_data . len ) ;
}
2015-01-26 20:01:47 +01:00
2021-10-07 01:32:48 +02:00
if ( current_data . len > 0 )
2013-09-11 22:49:49 +02:00
{
2021-10-07 01:32:48 +02:00
for ( s32 i = 0 ; i < current_data . len ; i + + )
{
2022-04-04 21:04:04 +02:00
data - > keycode [ i ] = current_data . buttons [ i ] . m_keyCode ;
2021-10-07 01:32:48 +02:00
}
KbConfig & current_config = handler . GetConfig ( port_no ) ;
// For single character mode to work properly we need to "flush" the buffer after reading or else we'll constantly get the same key presses with each call.
// Actual key repeats are handled by adding a new key code to the buffer periodically. Key releases are handled in a similar fashion.
// Warning: Don't do this in packet mode, which is basically the mouse and keyboard gaming mode. Otherwise games like Unreal Tournament will be unplayable.
if ( current_config . read_mode = = CELL_KB_RMODE_INPUTCHAR )
{
current_data . len = 0 ;
}
2013-09-11 22:49:49 +02:00
}
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbSetCodeType ( u32 port_no , u32 type )
2013-09-11 22:49:49 +02:00
{
2017-05-15 13:30:14 +02:00
sys_io . trace ( " cellKbSetCodeType(port_no=%d, type=%d) " , port_no , type ) ;
2015-01-26 20:01:47 +01:00
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2019-09-19 00:50:08 +02:00
2021-03-02 12:59:19 +01:00
const auto init = handler . init . access ( ) ;
2016-03-21 20:43:03 +01:00
2019-09-19 00:50:08 +02:00
if ( ! init )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_UNINITIALIZED ;
2017-10-01 03:00:56 +02:00
2018-07-24 21:58:30 +02:00
if ( port_no > = CELL_KB_MAX_KEYBOARDS | | type > CELL_KB_CODETYPE_ASCII )
2017-10-01 03:00:56 +02:00
return CELL_KB_ERROR_INVALID_PARAMETER ;
2017-12-31 12:01:11 +01:00
2021-03-02 12:59:19 +01:00
if ( port_no > = handler . GetKeyboards ( ) . size ( ) )
2018-07-24 21:58:30 +02:00
return CELL_OK ;
2021-03-02 12:59:19 +01:00
std : : lock_guard < std : : mutex > lock ( handler . m_mutex ) ;
2018-07-17 01:23:14 +02:00
2021-03-02 12:59:19 +01:00
KbConfig & current_config = handler . GetConfig ( port_no ) ;
2013-09-11 22:49:49 +02:00
current_config . code_type = type ;
2018-07-24 21:58:30 +02:00
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED
2013-09-11 22:49:49 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbSetLEDStatus ( u32 port_no , u8 led )
2013-09-11 22:49:49 +02:00
{
2018-07-24 21:58:30 +02:00
sys_io . trace ( " cellKbSetLEDStatus(port_no=%d, led=%d) " , port_no , led ) ;
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2019-09-19 00:50:08 +02:00
2021-03-02 12:59:19 +01:00
const auto init = handler . init . access ( ) ;
2018-07-24 21:58:30 +02:00
2019-09-19 00:50:08 +02:00
if ( ! init )
2018-07-24 21:58:30 +02:00
return CELL_KB_ERROR_UNINITIALIZED ;
if ( port_no > = CELL_KB_MAX_KEYBOARDS )
return CELL_KB_ERROR_INVALID_PARAMETER ;
if ( led > 7 )
return CELL_KB_ERROR_SYS_SETTING_FAILED ;
2021-03-02 12:59:19 +01:00
if ( port_no > = handler . GetKeyboards ( ) . size ( ) | | handler . GetInfo ( ) . status [ port_no ] ! = CELL_KB_STATUS_CONNECTED )
2018-07-24 21:58:30 +02:00
return CELL_KB_ERROR_FATAL ;
2021-03-02 12:59:19 +01:00
std : : lock_guard < std : : mutex > lock ( handler . m_mutex ) ;
2018-07-17 01:23:14 +02:00
2021-03-02 12:59:19 +01:00
KbData & current_data = handler . GetData ( port_no ) ;
2018-07-24 21:58:30 +02:00
current_data . led = static_cast < u32 > ( led ) ;
2013-09-11 22:49:49 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbSetReadMode ( u32 port_no , u32 rmode )
2013-09-11 22:49:49 +02:00
{
2017-05-15 13:30:14 +02:00
sys_io . trace ( " cellKbSetReadMode(port_no=%d, rmode=%d) " , port_no , rmode ) ;
2015-01-26 20:01:47 +01:00
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2016-03-21 20:43:03 +01:00
2021-03-02 12:59:19 +01:00
const auto init = handler . init . access ( ) ;
2019-09-19 00:50:08 +02:00
if ( ! init )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_UNINITIALIZED ;
2017-10-01 03:00:56 +02:00
2018-07-24 21:58:30 +02:00
if ( port_no > = CELL_KB_MAX_KEYBOARDS | | rmode > CELL_KB_RMODE_PACKET )
2017-10-01 03:00:56 +02:00
return CELL_KB_ERROR_INVALID_PARAMETER ;
2017-12-31 12:01:11 +01:00
2021-03-02 12:59:19 +01:00
if ( port_no > = handler . GetKeyboards ( ) . size ( ) )
2018-07-24 21:58:30 +02:00
return CELL_OK ;
2021-03-02 12:59:19 +01:00
std : : lock_guard < std : : mutex > lock ( handler . m_mutex ) ;
2018-07-17 01:23:14 +02:00
2021-03-02 12:59:19 +01:00
KbConfig & current_config = handler . GetConfig ( port_no ) ;
2013-09-11 22:49:49 +02:00
current_config . read_mode = rmode ;
2021-10-07 01:32:48 +02:00
// Key repeat must be disabled in packet mode. But let's just always enable it otherwise.
Keyboard & keyboard = handler . GetKeyboards ( ) [ port_no ] ;
keyboard . m_key_repeat = rmode ! = CELL_KB_RMODE_PACKET ;
2018-07-24 21:58:30 +02:00
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED
2013-09-11 22:49:49 +02:00
return CELL_OK ;
}
2017-05-15 13:30:14 +02:00
error_code cellKbGetConfiguration ( u32 port_no , vm : : ptr < CellKbConfig > config )
2013-09-11 22:49:49 +02:00
{
2016-01-12 22:57:16 +01:00
sys_io . trace ( " cellKbGetConfiguration(port_no=%d, config=*0x%x) " , port_no , config ) ;
2015-01-26 20:01:47 +01:00
2021-03-02 12:59:19 +01:00
auto & handler = g_fxo - > get < KeyboardHandlerBase > ( ) ;
2019-09-19 00:50:08 +02:00
2021-03-02 12:59:19 +01:00
const auto init = handler . init . access ( ) ;
2016-03-21 20:43:03 +01:00
2019-09-19 00:50:08 +02:00
if ( ! init )
2015-01-26 20:01:47 +01:00
return CELL_KB_ERROR_UNINITIALIZED ;
2013-09-11 22:49:49 +02:00
2018-07-24 21:58:30 +02:00
if ( port_no > = CELL_KB_MAX_KEYBOARDS )
return CELL_KB_ERROR_INVALID_PARAMETER ;
2021-03-02 12:59:19 +01:00
std : : lock_guard < std : : mutex > lock ( handler . m_mutex ) ;
2018-07-17 01:23:14 +02:00
2021-03-02 12:59:19 +01:00
const KbInfo & current_info = handler . GetInfo ( ) ;
2018-07-24 21:58:30 +02:00
2021-03-02 12:59:19 +01:00
if ( port_no > = handler . GetKeyboards ( ) . size ( ) | | current_info . status [ port_no ] ! = CELL_KB_STATUS_CONNECTED )
2018-07-24 21:58:30 +02:00
return CELL_KB_ERROR_NO_DEVICE ;
// tests show that config is checked only after the device's status
if ( ! config )
2017-10-01 03:00:56 +02:00
return CELL_KB_ERROR_INVALID_PARAMETER ;
2021-03-02 12:59:19 +01:00
const KbConfig & current_config = handler . GetConfig ( port_no ) ;
2014-08-28 03:18:35 +02:00
config - > arrange = current_config . arrange ;
config - > read_mode = current_config . read_mode ;
config - > code_type = current_config . code_type ;
2013-09-11 22:49:49 +02:00
2018-07-24 21:58:30 +02:00
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED
2013-09-11 22:49:49 +02:00
return CELL_OK ;
}
2014-09-03 18:33:30 +02:00
void cellKb_init ( )
{
2015-02-20 14:58:40 +01:00
REG_FUNC ( sys_io , cellKbInit ) ;
REG_FUNC ( sys_io , cellKbEnd ) ;
REG_FUNC ( sys_io , cellKbClearBuf ) ;
REG_FUNC ( sys_io , cellKbCnvRawCode ) ;
REG_FUNC ( sys_io , cellKbGetInfo ) ;
REG_FUNC ( sys_io , cellKbRead ) ;
REG_FUNC ( sys_io , cellKbSetCodeType ) ;
REG_FUNC ( sys_io , cellKbSetLEDStatus ) ;
REG_FUNC ( sys_io , cellKbSetReadMode ) ;
REG_FUNC ( sys_io , cellKbGetConfiguration ) ;
2014-09-03 18:33:30 +02:00
}