input: fix horrible pad hacks

This commit is contained in:
Megamouse 2022-07-05 22:49:20 +02:00
parent 4823d4c32a
commit 2bf17f5d3c
3 changed files with 149 additions and 182 deletions

View file

@ -430,11 +430,14 @@ extern bool is_input_allowed();
* \param analog_t Analog value of Move's Trigger. Currently mapped to R2. * \param analog_t Analog value of Move's Trigger. Currently mapped to R2.
* \return true on success, false if port_no controller is invalid * \return true on success, false if port_no controller is invalid
*/ */
static bool ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t) static void ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t)
{ {
digital_buttons = 0;
analog_t = 0;
if (!is_input_allowed()) if (!is_input_allowed())
{ {
return false; return;
} }
std::lock_guard lock(pad::g_pad_mutex); std::lock_guard lock(pad::g_pad_mutex);
@ -443,72 +446,60 @@ static bool ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t
const auto& pad = handler->GetPads().at(port_no); const auto& pad = handler->GetPads().at(port_no);
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return false; {
return;
}
for (const Button& button : pad->m_buttons) for (const Button& button : pad->m_buttons)
{ {
// here we check btns, and set pad accordingly if (!button.m_pressed)
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
{ {
if (button.m_pressed) pad->m_digital_2 |= button.m_outKeyCode; continue;
else pad->m_digital_2 &= ~button.m_outKeyCode; }
// here we check btns, and set pad accordingly
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
{
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_START:
digital_buttons |= CELL_GEM_CTRL_START;
break;
case CELL_PAD_CTRL_SELECT:
digital_buttons |= CELL_GEM_CTRL_SELECT;
break;
default:
break;
}
}
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
{
switch (button.m_outKeyCode) switch (button.m_outKeyCode)
{ {
case CELL_PAD_CTRL_SQUARE: case CELL_PAD_CTRL_SQUARE:
pad->m_press_square = button.m_value; digital_buttons |= CELL_GEM_CTRL_SQUARE;
break; break;
case CELL_PAD_CTRL_CROSS: case CELL_PAD_CTRL_CROSS:
pad->m_press_cross = button.m_value; digital_buttons |= CELL_GEM_CTRL_CROSS;
break; break;
case CELL_PAD_CTRL_CIRCLE: case CELL_PAD_CTRL_CIRCLE:
pad->m_press_circle = button.m_value; digital_buttons |= CELL_GEM_CTRL_CIRCLE;
break; break;
case CELL_PAD_CTRL_TRIANGLE: case CELL_PAD_CTRL_TRIANGLE:
pad->m_press_triangle = button.m_value; digital_buttons |= CELL_GEM_CTRL_TRIANGLE;
break; break;
case CELL_PAD_CTRL_R1: case CELL_PAD_CTRL_R1:
pad->m_press_R1 = button.m_value; digital_buttons |= CELL_GEM_CTRL_MOVE;
break;
case CELL_PAD_CTRL_L1:
pad->m_press_L1 = button.m_value;
break; break;
case CELL_PAD_CTRL_R2: case CELL_PAD_CTRL_R2:
pad->m_press_R2 = button.m_value; digital_buttons |= CELL_GEM_CTRL_T;
analog_t = std::max<u16>(analog_t, button.m_value);
break; break;
case CELL_PAD_CTRL_L2: default:
pad->m_press_L2 = button.m_value;
break; break;
default: break;
} }
} }
} }
digital_buttons = 0;
// map the Move key to R1 and the Trigger to R2
if (pad->m_press_R1)
digital_buttons |= CELL_GEM_CTRL_MOVE;
if (pad->m_press_R2)
digital_buttons |= CELL_GEM_CTRL_T;
if (pad->m_press_cross)
digital_buttons |= CELL_GEM_CTRL_CROSS;
if (pad->m_press_circle)
digital_buttons |= CELL_GEM_CTRL_CIRCLE;
if (pad->m_press_square)
digital_buttons |= CELL_GEM_CTRL_SQUARE;
if (pad->m_press_triangle)
digital_buttons |= CELL_GEM_CTRL_TRIANGLE;
if (pad->m_digital_1)
digital_buttons |= CELL_GEM_CTRL_SELECT;
if (pad->m_digital_2)
digital_buttons |= CELL_GEM_CTRL_START;
analog_t = pad->m_press_R2;
return true;
} }
/** /**
@ -519,11 +510,13 @@ static bool ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t
* \param ext External data to modify * \param ext External data to modify
* \return true on success, false if port_no controller is invalid * \return true on success, false if port_no controller is invalid
*/ */
static bool ds3_input_to_ext(const u32 port_no, const gem_config::gem_controller& controller, CellGemExtPortData& ext) static void ds3_input_to_ext(const u32 port_no, const gem_config::gem_controller& controller, CellGemExtPortData& ext)
{ {
ext = {};
if (!is_input_allowed()) if (!is_input_allowed())
{ {
return false; return;
} }
std::lock_guard lock(pad::g_pad_mutex); std::lock_guard lock(pad::g_pad_mutex);
@ -532,7 +525,9 @@ static bool ds3_input_to_ext(const u32 port_no, const gem_config::gem_controller
const auto& pad = handler->GetPads().at(port_no); const auto& pad = handler->GetPads().at(port_no);
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return false; {
return;
}
ext.status = 0; // CELL_GEM_EXT_CONNECTED | CELL_GEM_EXT_EXT0 | CELL_GEM_EXT_EXT1 ext.status = 0; // CELL_GEM_EXT_CONNECTED | CELL_GEM_EXT_EXT0 | CELL_GEM_EXT_EXT1
ext.analog_left_x = pad->m_analog_left_x; // HACK: these pad members are actually only set in cellPad ext.analog_left_x = pad->m_analog_left_x; // HACK: these pad members are actually only set in cellPad
@ -551,8 +546,6 @@ static bool ds3_input_to_ext(const u32 port_no, const gem_config::gem_controller
// xxxxx010: Firing mode selector is in position 2. // xxxxx010: Firing mode selector is in position 2.
// xxxxx100: Firing mode selector is in position 3. // xxxxx100: Firing mode selector is in position 3.
} }
return true;
} }
/** /**
@ -566,6 +559,9 @@ static bool ds3_input_to_ext(const u32 port_no, const gem_config::gem_controller
*/ */
static bool mouse_input_to_pad(const u32 mouse_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t) static bool mouse_input_to_pad(const u32 mouse_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t)
{ {
digital_buttons = 0;
analog_t = 0;
if (!is_input_allowed()) if (!is_input_allowed())
{ {
return false; return false;
@ -662,20 +658,20 @@ static void mouse_pos_to_gem_image_state(const u32 mouse_no, const gem_config::g
gem_image_state->projectiony = camera_y / controller.distance; gem_image_state->projectiony = camera_y / controller.distance;
} }
static bool mouse_pos_to_gem_state(const u32 mouse_no, const gem_config::gem_controller& controller, vm::ptr<CellGemState>& gem_state) static void mouse_pos_to_gem_state(const u32 mouse_no, const gem_config::gem_controller& controller, vm::ptr<CellGemState>& gem_state)
{ {
if (!is_input_allowed()) if (!gem_state || !is_input_allowed())
{ {
return false; return;
} }
auto& handler = g_fxo->get<MouseHandlerBase>(); auto& handler = g_fxo->get<MouseHandlerBase>();
std::scoped_lock lock(handler.mutex); std::scoped_lock lock(handler.mutex);
if (!gem_state || mouse_no >= handler.GetMice().size()) if (mouse_no >= handler.GetMice().size())
{ {
return false; return;
} }
const auto& mouse = handler.GetMice().at(mouse_no); const auto& mouse = handler.GetMice().at(mouse_no);
@ -716,8 +712,6 @@ static bool mouse_pos_to_gem_state(const u32 mouse_no, const gem_config::gem_con
gem_state->handle_pos[1] = camera_y; gem_state->handle_pos[1] = camera_y;
gem_state->handle_pos[2] = static_cast<f32>(controller.distance + 10); gem_state->handle_pos[2] = static_cast<f32>(controller.distance + 10);
gem_state->handle_pos[3] = 0.f; gem_state->handle_pos[3] = 0.f;
return true;
} }
// ********************* // *********************
@ -1153,7 +1147,7 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
return CELL_GEM_TIME_OUT_OF_RANGE; return CELL_GEM_TIME_OUT_OF_RANGE;
} }
inertial_state = {}; *inertial_state = {};
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse) if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
{ {
@ -1315,6 +1309,8 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
return CELL_GEM_TIME_OUT_OF_RANGE; return CELL_GEM_TIME_OUT_OF_RANGE;
} }
*gem_state = {};
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse) if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
{ {
ds3_input_to_ext(gem_num, gem.controllers[gem_num], gem_state->ext); ds3_input_to_ext(gem_num, gem.controllers[gem_num], gem_state->ext);
@ -1324,7 +1320,6 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
if (gem.controllers[gem_num].enabled_tracking) if (gem.controllers[gem_num].enabled_tracking)
tracking_flags |= CELL_GEM_TRACKING_FLAG_POSITION_TRACKED; tracking_flags |= CELL_GEM_TRACKING_FLAG_POSITION_TRACKED;
*gem_state = {};
gem_state->tracking_flags = tracking_flags; gem_state->tracking_flags = tracking_flags;
gem_state->timestamp = (get_guest_system_time() - gem.start_timestamp); gem_state->timestamp = (get_guest_system_time() - gem.start_timestamp);
gem_state->camera_pitch_angle = 0.f; gem_state->camera_pitch_angle = 0.f;

View file

@ -31,15 +31,15 @@ void usb_device_buzz::control_transfer(u8 bmRequestType, u8 bRequest, u16 wValue
// Control transfers are nearly instant // Control transfers are nearly instant
switch (bmRequestType) switch (bmRequestType)
{ {
case 0x01: case 0x01:
case 0x21: case 0x21:
case 0x80: case 0x80:
buzz_log.error("Unhandled Query Len: 0x%02X", buf_size); buzz_log.error("Unhandled Query Len: 0x%02X", buf_size);
buzz_log.error("Unhandled Query Type: 0x%02X", (buf_size > 0) ? buf[0] : -1); buzz_log.error("Unhandled Query Type: 0x%02X", (buf_size > 0) ? buf[0] : -1);
break; break;
default: default:
usb_device_emulated::control_transfer(bmRequestType, bRequest, wValue, wIndex, wLength, buf_size, buf, transfer); usb_device_emulated::control_transfer(bmRequestType, bRequest, wValue, wIndex, wLength, buf_size, buf, transfer);
break; break;
} }
} }
@ -76,36 +76,38 @@ void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint*/
const auto& pad = pads[first_controller + index]; const auto& pad = pads[first_controller + index];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
{
continue; continue;
}
for (Button& button : pad->m_buttons) for (Button& button : pad->m_buttons)
{ {
if (!button.m_pressed)
{
continue;
}
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2) if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
{ {
switch (button.m_outKeyCode) switch (button.m_outKeyCode)
{ {
case CELL_PAD_CTRL_R1: case CELL_PAD_CTRL_R1:
if (button.m_pressed) buf[2 + (0 + 5 * index) / 8] |= 1 << ((0 + 5 * index) % 8); // Red
buf[2 + (0 + 5 * index) / 8] |= 1 << ((0 + 5 * index) % 8); // Red break;
break; case CELL_PAD_CTRL_TRIANGLE:
case CELL_PAD_CTRL_TRIANGLE: buf[2 + (4 + 5 * index) / 8] |= 1 << ((4 + 5 * index) % 8); // Blue
if (button.m_pressed) break;
buf[2 + (4 + 5 * index) / 8] |= 1 << ((4 + 5 * index) % 8); // Blue case CELL_PAD_CTRL_SQUARE:
break; buf[2 + (3 + 5 * index) / 8] |= 1 << ((3 + 5 * index) % 8); // Orange
case CELL_PAD_CTRL_SQUARE: break;
if (button.m_pressed) case CELL_PAD_CTRL_CIRCLE:
buf[2 + (3 + 5 * index) / 8] |= 1 << ((3 + 5 * index) % 8); // Orange buf[2 + (2 + 5 * index) / 8] |= 1 << ((2 + 5 * index) % 8); // Green
break; break;
case CELL_PAD_CTRL_CIRCLE: case CELL_PAD_CTRL_CROSS:
if (button.m_pressed) buf[2 + (1 + 5 * index) / 8] |= 1 << ((1 + 5 * index) % 8); // Yellow
buf[2 + (2 + 5 * index) / 8] |= 1 << ((2 + 5 * index) % 8); // Green break;
break; default:
case CELL_PAD_CTRL_CROSS: break;
if (button.m_pressed)
buf[2 + (1 + 5 * index) / 8] |= 1 << ((1 + 5 * index) % 8); // Yellow
break;
default:
break;
} }
} }
} }

View file

@ -107,101 +107,73 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint
std::lock_guard lock(pad::g_pad_mutex); std::lock_guard lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler(); const auto handler = pad::get_current_handler();
const auto& pad = handler->GetPads()[m_controller_index]; const auto& pad = handler->GetPads().at(m_controller_index);
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
{ {
return; return;
} }
for (Button& button : pad->m_buttons) for (const Button& button : pad->m_buttons)
{ {
if (!button.m_pressed)
{
continue;
}
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2) if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
{ {
if (button.m_pressed)
pad->m_digital_2 |= button.m_outKeyCode;
else
pad->m_digital_2 &= ~button.m_outKeyCode;
switch (button.m_outKeyCode) switch (button.m_outKeyCode)
{ {
case CELL_PAD_CTRL_SQUARE: case CELL_PAD_CTRL_SQUARE:
pad->m_press_square = button.m_value; buf[0] += 0x01; // W1
if (button.m_pressed) break;
buf[0] += 0x01; // W1 case CELL_PAD_CTRL_CROSS:
break; buf[0] += 0x02; // B1
case CELL_PAD_CTRL_CROSS: break;
pad->m_press_cross = button.m_value; case CELL_PAD_CTRL_CIRCLE:
if (button.m_pressed) buf[0] += 0x04; // B2
buf[0] += 0x02; // B1 break;
break; case CELL_PAD_CTRL_TRIANGLE:
case CELL_PAD_CTRL_CIRCLE: buf[0] += 0x08; // B3
pad->m_press_circle = button.m_value; break;
if (button.m_pressed) case CELL_PAD_CTRL_R1:
buf[0] += 0x04; // B2 buf[0] += 0x20; // W3
break; break;
case CELL_PAD_CTRL_TRIANGLE: case CELL_PAD_CTRL_L1:
pad->m_press_triangle = button.m_value; buf[0] += 0x10; // W2
if (button.m_pressed) break;
buf[0] += 0x08; // B3 default:
break; break;
case CELL_PAD_CTRL_R1:
pad->m_press_R1 = button.m_value;
if (button.m_pressed)
buf[0] += 0x20; // W3
break;
case CELL_PAD_CTRL_L1:
pad->m_press_L1 = button.m_value;
if (button.m_pressed)
buf[0] += 0x10; // W2
break;
default:
break;
} }
} }
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1) else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
{ {
if (button.m_pressed)
pad->m_digital_1 |= button.m_outKeyCode;
else
pad->m_digital_1 &= ~button.m_outKeyCode;
switch (button.m_outKeyCode) switch (button.m_outKeyCode)
{ {
case CELL_PAD_CTRL_DOWN: case CELL_PAD_CTRL_DOWN:
pad->m_press_down = button.m_value; buf[4] = 0xFF; // Strum Down
if (button.m_pressed) break;
buf[4] = 0xFF; // Strum Down case CELL_PAD_CTRL_UP:
break; buf[4] = 0x00; // Strum Up
case CELL_PAD_CTRL_UP: break;
pad->m_press_up = button.m_value; case CELL_PAD_CTRL_LEFT:
if (button.m_pressed) buf[2] = 0x02; // Left D-Pad (Unused)
buf[4] = 0x00; // Strum Up break;
break; case CELL_PAD_CTRL_RIGHT:
case CELL_PAD_CTRL_LEFT: buf[2] = 0x06; // Right D-Pad (Unused)
pad->m_press_down = button.m_value; break;
if (button.m_pressed) case CELL_PAD_CTRL_START:
buf[2] = 0x02; // Left D-Pad (Unused) buf[1] += 0x02; // Pause
break; break;
case CELL_PAD_CTRL_RIGHT: case CELL_PAD_CTRL_SELECT:
pad->m_press_up = button.m_value; buf[1] += 0x01; // Hero Power
if (button.m_pressed) break;
buf[2] = 0x06; // Right D-Pad (Unused) case CELL_PAD_CTRL_L3:
break; buf[1] += 0x04; // GHTV Button
case CELL_PAD_CTRL_START: break;
if (button.m_pressed) default:
buf[1] += 0x02; // Pause break;
break;
case CELL_PAD_CTRL_SELECT:
if (button.m_pressed)
buf[1] += 0x01; // Hero Power
break;
case CELL_PAD_CTRL_L3:
if (button.m_pressed)
buf[1] += 0x04; // GHTV Button
break;
default:
break;
} }
} }
} }
@ -209,20 +181,18 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint
{ {
switch (stick.m_offset) switch (stick.m_offset)
{ {
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
buf[6] = ~(stick.m_value) + 0x01; // Whammy buf[6] = ~(stick.m_value) + 0x01; // Whammy
pad->m_analog_right_x = stick.m_value; break;
break; case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: buf[19] = static_cast<u8>(stick.m_value); // Tilt
buf[19] = static_cast<u8>(stick.m_value); // Tilt if (buf[19] >= 0xF0)
if (buf[19] >= 0xF0) buf[5] = 0xFF;
buf[5] = 0xFF; if (buf[19] <= 0x10)
if (buf[19] <= 0x10) buf[5] = 0x00;
buf[5] = 0x00; break;
pad->m_analog_right_y = stick.m_value; default:
break; break;
default:
break;
} }
} }
} }