@@ -272,7 +272,7 @@ error_code cellPadInit(ppu_thread& ppu, u32 max_connect)
272272
273273 for (usz i = 0 ; i < config.get_max_connect (); ++i)
274274 {
275- if (!pads[i]->is_fake_pad && ( pads[i]->m_port_status & CELL_PAD_STATUS_CONNECTED ))
275+ if (!pads[i]->is_fake_pad && pads[i]->is_connected ( ))
276276 {
277277 send_sys_io_connect_event (i, CELL_PAD_STATUS_CONNECTED);
278278 }
@@ -339,7 +339,7 @@ error_code cellPadClearBuf(u32 port_no)
339339 const auto & pads = handler->GetPads ();
340340 const auto & pad = pads[port_no];
341341
342- if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !( pad->m_port_status & CELL_PAD_STATUS_CONNECTED ))
342+ if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !pad->is_connected ( ))
343343 return not_an_error (CELL_PAD_ERROR_NO_DEVICE);
344344
345345 clear_pad_buffer (pad);
@@ -411,26 +411,59 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
411411 }
412412 };
413413
414- for (Button& button : pad->m_buttons )
414+ for (const Button& button : pad->m_buttons )
415415 {
416416 // here we check btns, and set pad accordingly,
417417 // if something changed, set btnChanged
418418
419+ bool pressed = button.m_pressed ;
420+ u16 value = button.m_value ;
421+
422+ // Merge copilots
423+ if (!pad->copilots .empty ())
424+ {
425+ for (const auto & copilot : pad->copilots )
426+ {
427+ if (!copilot || !copilot->is_connected ())
428+ {
429+ continue ;
430+ }
431+
432+ for (const Button& other : copilot->m_buttons )
433+ {
434+ if (button.m_offset == other.m_offset && button.m_outKeyCode == other.m_outKeyCode )
435+ {
436+ if (other.m_pressed )
437+ {
438+ pressed = true ;
439+
440+ if (value < other.m_value )
441+ {
442+ value = other.m_value ;
443+ }
444+ }
445+
446+ break ;
447+ }
448+ }
449+ }
450+ }
451+
419452 switch (button.m_offset )
420453 {
421454 case CELL_PAD_BTN_OFFSET_DIGITAL1:
422455 {
423- if (button. m_pressed )
456+ if (pressed )
424457 pad->m_digital_1 |= button.m_outKeyCode ;
425458 else
426459 pad->m_digital_1 &= ~button.m_outKeyCode ;
427460
428461 switch (button.m_outKeyCode )
429462 {
430- case CELL_PAD_CTRL_LEFT: set_value (pad->m_press_left , button. m_value ); break ;
431- case CELL_PAD_CTRL_DOWN: set_value (pad->m_press_down , button. m_value ); break ;
432- case CELL_PAD_CTRL_RIGHT: set_value (pad->m_press_right , button. m_value ); break ;
433- case CELL_PAD_CTRL_UP: set_value (pad->m_press_up , button. m_value ); break ;
463+ case CELL_PAD_CTRL_LEFT: set_value (pad->m_press_left , value ); break ;
464+ case CELL_PAD_CTRL_DOWN: set_value (pad->m_press_down , value ); break ;
465+ case CELL_PAD_CTRL_RIGHT: set_value (pad->m_press_right , value ); break ;
466+ case CELL_PAD_CTRL_UP: set_value (pad->m_press_up , value ); break ;
434467 // These arent pressure btns
435468 case CELL_PAD_CTRL_R3:
436469 case CELL_PAD_CTRL_L3:
@@ -442,21 +475,21 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
442475 }
443476 case CELL_PAD_BTN_OFFSET_DIGITAL2:
444477 {
445- if (button. m_pressed )
478+ if (pressed )
446479 pad->m_digital_2 |= button.m_outKeyCode ;
447480 else
448481 pad->m_digital_2 &= ~button.m_outKeyCode ;
449482
450483 switch (button.m_outKeyCode )
451484 {
452- case CELL_PAD_CTRL_SQUARE: set_value (pad->m_press_square , button. m_value ); break ;
453- case CELL_PAD_CTRL_CROSS: set_value (pad->m_press_cross , button. m_value ); break ;
454- case CELL_PAD_CTRL_CIRCLE: set_value (pad->m_press_circle , button. m_value ); break ;
455- case CELL_PAD_CTRL_TRIANGLE: set_value (pad->m_press_triangle , button. m_value ); break ;
456- case CELL_PAD_CTRL_R1: set_value (pad->m_press_R1 , button. m_value ); break ;
457- case CELL_PAD_CTRL_L1: set_value (pad->m_press_L1 , button. m_value ); break ;
458- case CELL_PAD_CTRL_R2: set_value (pad->m_press_R2 , button. m_value ); break ;
459- case CELL_PAD_CTRL_L2: set_value (pad->m_press_L2 , button. m_value ); break ;
485+ case CELL_PAD_CTRL_SQUARE: set_value (pad->m_press_square , value ); break ;
486+ case CELL_PAD_CTRL_CROSS: set_value (pad->m_press_cross , value ); break ;
487+ case CELL_PAD_CTRL_CIRCLE: set_value (pad->m_press_circle , value ); break ;
488+ case CELL_PAD_CTRL_TRIANGLE: set_value (pad->m_press_triangle , value ); break ;
489+ case CELL_PAD_CTRL_R1: set_value (pad->m_press_R1 , value ); break ;
490+ case CELL_PAD_CTRL_L1: set_value (pad->m_press_L1 , value ); break ;
491+ case CELL_PAD_CTRL_R2: set_value (pad->m_press_R2 , value ); break ;
492+ case CELL_PAD_CTRL_L2: set_value (pad->m_press_L2 , value ); break ;
460493 default : break ;
461494 }
462495 break ;
@@ -465,18 +498,18 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
465498 {
466499 switch (button.m_outKeyCode )
467500 {
468- case CELL_PAD_CTRL_PRESS_RIGHT: set_value (pad->m_press_right , button. m_value , true ); break ;
469- case CELL_PAD_CTRL_PRESS_LEFT: set_value (pad->m_press_left , button. m_value , true ); break ;
470- case CELL_PAD_CTRL_PRESS_UP: set_value (pad->m_press_up , button. m_value , true ); break ;
471- case CELL_PAD_CTRL_PRESS_DOWN: set_value (pad->m_press_down , button. m_value , true ); break ;
472- case CELL_PAD_CTRL_PRESS_TRIANGLE: set_value (pad->m_press_triangle , button. m_value , true , 255 , 63 ); break ; // Infrared on RIDE Skateboard
473- case CELL_PAD_CTRL_PRESS_CIRCLE: set_value (pad->m_press_circle , button. m_value , true , 255 , 63 ); break ; // Infrared on RIDE Skateboard
474- case CELL_PAD_CTRL_PRESS_CROSS: set_value (pad->m_press_cross , button. m_value , true , 255 , 63 ); break ; // Infrared on RIDE Skateboard
475- case CELL_PAD_CTRL_PRESS_SQUARE: set_value (pad->m_press_square , button. m_value , true , 255 , 63 ); break ; // Infrared on RIDE Skateboard
476- case CELL_PAD_CTRL_PRESS_L1: set_value (pad->m_press_L1 , button. m_value , true ); break ;
477- case CELL_PAD_CTRL_PRESS_R1: set_value (pad->m_press_R1 , button. m_value , true ); break ;
478- case CELL_PAD_CTRL_PRESS_L2: set_value (pad->m_press_L2 , button. m_value , true ); break ;
479- case CELL_PAD_CTRL_PRESS_R2: set_value (pad->m_press_R2 , button. m_value , true ); break ;
501+ case CELL_PAD_CTRL_PRESS_RIGHT: set_value (pad->m_press_right , value , true ); break ;
502+ case CELL_PAD_CTRL_PRESS_LEFT: set_value (pad->m_press_left , value , true ); break ;
503+ case CELL_PAD_CTRL_PRESS_UP: set_value (pad->m_press_up , value , true ); break ;
504+ case CELL_PAD_CTRL_PRESS_DOWN: set_value (pad->m_press_down , value , true ); break ;
505+ case CELL_PAD_CTRL_PRESS_TRIANGLE: set_value (pad->m_press_triangle , value , true , 255 , 63 ); break ; // Infrared on RIDE Skateboard
506+ case CELL_PAD_CTRL_PRESS_CIRCLE: set_value (pad->m_press_circle , value , true , 255 , 63 ); break ; // Infrared on RIDE Skateboard
507+ case CELL_PAD_CTRL_PRESS_CROSS: set_value (pad->m_press_cross , value , true , 255 , 63 ); break ; // Infrared on RIDE Skateboard
508+ case CELL_PAD_CTRL_PRESS_SQUARE: set_value (pad->m_press_square , value , true , 255 , 63 ); break ; // Infrared on RIDE Skateboard
509+ case CELL_PAD_CTRL_PRESS_L1: set_value (pad->m_press_L1 , value , true ); break ;
510+ case CELL_PAD_CTRL_PRESS_R1: set_value (pad->m_press_R1 , value , true ); break ;
511+ case CELL_PAD_CTRL_PRESS_L2: set_value (pad->m_press_L2 , value , true ); break ;
512+ case CELL_PAD_CTRL_PRESS_R2: set_value (pad->m_press_R2 , value , true ); break ;
480513 default : break ;
481514 }
482515 break ;
@@ -488,12 +521,44 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
488521
489522 for (const AnalogStick& stick : pad->m_sticks )
490523 {
524+ u16 value = stick.m_value ;
525+
526+ // Merge copilots
527+ if (!pad->copilots .empty ())
528+ {
529+ const auto normalize = [](s32 value)
530+ {
531+ return (value - 128 ) / 127 .0f ;
532+ };
533+
534+ f32 accumulated_value = normalize (value);
535+
536+ for (const auto & copilot : pad->copilots )
537+ {
538+ if (!copilot || !copilot->is_connected ())
539+ {
540+ continue ;
541+ }
542+
543+ for (const AnalogStick& other : copilot->m_sticks )
544+ {
545+ if (stick.m_offset == other.m_offset )
546+ {
547+ accumulated_value += normalize (other.m_value );
548+ break ;
549+ }
550+ }
551+ }
552+
553+ value = static_cast <u16 >(std::round (std::clamp (accumulated_value * 127 .0f + 128 .0f , 0 .0f , 255 .0f )));
554+ }
555+
491556 switch (stick.m_offset )
492557 {
493- case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: set_value (pad->m_analog_left_x , stick. m_value ); break ;
494- case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: set_value (pad->m_analog_left_y , stick. m_value ); break ;
495- case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: set_value (pad->m_analog_right_x , stick. m_value ); break ;
496- case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: set_value (pad->m_analog_right_y , stick. m_value ); break ;
558+ case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: set_value (pad->m_analog_left_x , value ); break ;
559+ case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: set_value (pad->m_analog_left_y , value ); break ;
560+ case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: set_value (pad->m_analog_right_x , value ); break ;
561+ case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: set_value (pad->m_analog_right_y , value ); break ;
497562 default : break ;
498563 }
499564 }
@@ -712,7 +777,7 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
712777 const auto & pads = handler->GetPads ();
713778 const auto & pad = pads[port_no];
714779
715- if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !( pad->m_port_status & CELL_PAD_STATUS_CONNECTED ))
780+ if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !pad->is_connected ( ))
716781 return not_an_error (CELL_PAD_ERROR_NO_DEVICE);
717782
718783 pad_get_data (port_no, data.get_ptr ());
@@ -798,7 +863,7 @@ error_code cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
798863 const auto & pads = handler->GetPads ();
799864 const auto & pad = pads[port_no];
800865
801- if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !( pad->m_port_status & CELL_PAD_STATUS_CONNECTED ))
866+ if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !pad->is_connected ( ))
802867 return not_an_error (CELL_PAD_ERROR_NO_DEVICE);
803868
804869 pad_get_data (port_no, &data->cellpad_data , true );
@@ -830,7 +895,7 @@ error_code cellPadGetRawData(u32 port_no, vm::ptr<CellPadData> data)
830895 const auto & pads = handler->GetPads ();
831896 const auto & pad = pads[port_no];
832897
833- if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !( pad->m_port_status & CELL_PAD_STATUS_CONNECTED ))
898+ if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !pad->is_connected ( ))
834899 return not_an_error (CELL_PAD_ERROR_NO_DEVICE);
835900
836901 // ?
@@ -843,7 +908,7 @@ error_code cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<Ce
843908 cellPad.trace (" cellPadGetDataExtra(port_no=%d, device_type=*0x%x, data=*0x%x)" , port_no, device_type, data);
844909
845910 // TODO: This is used just to get data from a BD/CEC remote,
846- // but if the port isnt a remote, device type is set to CELL_PAD_DEV_TYPE_STANDARD and just regular cellPadGetData is returned
911+ // but if the port isn't a remote, device type is set to CELL_PAD_DEV_TYPE_STANDARD and just regular cellPadGetData is returned
847912
848913 if (auto err = cellPadGetData (port_no, data))
849914 {
@@ -894,7 +959,7 @@ error_code cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
894959 const auto & pads = handler->GetPads ();
895960 const auto & pad = pads[port_no];
896961
897- if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !( pad->m_port_status & CELL_PAD_STATUS_CONNECTED ))
962+ if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !pad->is_connected ( ))
898963 return not_an_error (CELL_PAD_ERROR_NO_DEVICE);
899964
900965 // TODO: find out if this is checked here or later or at all
@@ -1021,7 +1086,7 @@ error_code cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellPadCapabilityInfo>
10211086 const auto & pads = handler->GetPads ();
10221087 const auto & pad = pads[port_no];
10231088
1024- if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !( pad->m_port_status & CELL_PAD_STATUS_CONNECTED ))
1089+ if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !pad->is_connected ( ))
10251090 return not_an_error (CELL_PAD_ERROR_NO_DEVICE);
10261091
10271092 // Should return the same as device capability mask, psl1ght has it backwards in pad->h
@@ -1077,7 +1142,7 @@ error_code cellPadInfoPressMode(u32 port_no)
10771142 const auto & pads = handler->GetPads ();
10781143 const auto & pad = pads[port_no];
10791144
1080- if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !( pad->m_port_status & CELL_PAD_STATUS_CONNECTED ))
1145+ if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !pad->is_connected ( ))
10811146 return not_an_error (CELL_PAD_ERROR_NO_DEVICE);
10821147
10831148 return not_an_error ((pad->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) ? 1 : 0 );
@@ -1104,7 +1169,7 @@ error_code cellPadInfoSensorMode(u32 port_no)
11041169 const auto & pads = handler->GetPads ();
11051170 const auto & pad = pads[port_no];
11061171
1107- if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !( pad->m_port_status & CELL_PAD_STATUS_CONNECTED ))
1172+ if (pad->is_fake_pad || !config.is_reportedly_connected (port_no) || !pad->is_connected ( ))
11081173 return not_an_error (CELL_PAD_ERROR_NO_DEVICE);
11091174
11101175 return not_an_error ((pad->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) ? 1 : 0 );
0 commit comments