Skip to content

Commit

Permalink
Fixup cellPadPeriphGetInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Aug 19, 2023
1 parent ea50f64 commit 3711780
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 57 deletions.
131 changes: 76 additions & 55 deletions rpcs3/Emu/Cell/Modules/cellPad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,58 @@ void cellPad_NotifyStateChange(u32 index, u32 state)
return;
}

const u32 old = info->reported_statuses[index];
const auto handler = pad::get_current_handler();

const auto& pads = handler->GetPads();

const u32 old = info->reported_statuses[index].port_setting;

if (~(old ^ state) & CELL_PAD_STATUS_CONNECTED)
{
return;
}

info->reported_statuses[index] = (state & CELL_PAD_STATUS_CONNECTED) | CELL_PAD_STATUS_ASSIGN_CHANGES;
info->reported_statuses[index].port_status = (state & CELL_PAD_STATUS_CONNECTED) | CELL_PAD_STATUS_ASSIGN_CHANGES;
info->reported_statuses[index].device_capability = pad[i]->m_device_capability;
info->reported_statuses[index].device_type = pad[i]->m_device_type;
info->reported_statuses[index].pclass_type = pads[i]->m_class_profile;
info->reported_statuses[index].pclass_profile = pads[i]->m_class_type;

if (pads[i]->m_vendor_id == 0 || pads[i]->m_product_id == 0)
{
// Fallback to defaults

input::product_info product;

switch (pads[i]->m_class_type)
{
case CELL_PAD_PCLASS_TYPE_GUITAR:
product = input::get_product_info(input::product_type::red_octane_gh_guitar);
break;
case CELL_PAD_PCLASS_TYPE_DRUM:
product = input::get_product_info(input::product_type::red_octane_gh_drum_kit);
break;
case CELL_PAD_PCLASS_TYPE_DJ:
product = input::get_product_info(input::product_type::dj_hero_turntable);
break;
case CELL_PAD_PCLASS_TYPE_DANCEMAT:
product = input::get_product_info(input::product_type::dance_dance_revolution_mat);
break;
case CELL_PAD_PCLASS_TYPE_NAVIGATION:
case CELL_PAD_PCLASS_TYPE_STANDARD:
default:
product = input::get_product_info(input::product_type::playstation_3_controller);
break;
}

info->reported_statuses[i].vendor_id = product.vendor_id;
info->reported_statuses[i].product_id = product.product_id;
}
else
{
info->reported_statuses[i].vendor_id = pads[i]->m_vendor_id;
info->reported_statuses[i].product_id = pads[i]->m_product_id;
}
}

extern void pad_state_notify_state_change(u32 index, u32 state)
Expand Down Expand Up @@ -459,25 +503,36 @@ error_code cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
std::memset(info.get_ptr(), 0, sizeof(CellPadPeriphInfo));

info->max_connect = config.max_connect;
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;

const auto& pads = handler->GetPads();

u32 now_connect = 0;

for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
{
if (i >= config.get_max_connect())
break;

info->port_status[i] = pads[i]->m_port_status;
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_status[i] = config.reported_statuses[i];
config.reported_statuses[i] &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = config.port_setting[i];
info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;
info->pclass_type[i] = pads[i]->m_class_type;
info->pclass_profile[i] = pads[i]->m_class_profile;

if (~config.reported_statuses[i] & CELL_PAD_STATUS_CONNECTED)
{
continue;
}

info->device_capability[i] = config.reported_statuses[i].device_capability;
info->device_type[i] = config.reported_statuses[i].device_type;
info->pclass_type[i] = config.reported_statuses[i].class_type;
info->pclass_profile[i] = config.reported_statuses[i].m_class_profile;

now_connect++;
}

info->now_connect = now_connect;

return CELL_OK;
}

Expand Down Expand Up @@ -649,52 +704,18 @@ error_code cellPadGetInfo(vm::ptr<CellPadInfo> info)
if (i >= config.get_max_connect())
break;

if (!config.is_reportedly_connected(i))
continue;

config.reported_statuses[i] &= ~CELL_PAD_STATUS_ASSIGN_CHANGES; // TODO: should ASSIGN flags be cleared here?
info->status[i] = config.reported_statuses[i];

if (config.reported_statuses[i] & CELL_PAD_STATUS_CONNECTED)
if (~config.reported_statuses[i] & CELL_PAD_STATUS_CONNECTED)
{
now_connect++;
continue;
}

if (pads[i]->m_vendor_id == 0 || pads[i]->m_product_id == 0)
{
// Fallback to defaults

input::product_info product;

switch (pads[i]->m_class_type)
{
case CELL_PAD_PCLASS_TYPE_GUITAR:
product = input::get_product_info(input::product_type::red_octane_gh_guitar);
break;
case CELL_PAD_PCLASS_TYPE_DRUM:
product = input::get_product_info(input::product_type::red_octane_gh_drum_kit);
break;
case CELL_PAD_PCLASS_TYPE_DJ:
product = input::get_product_info(input::product_type::dj_hero_turntable);
break;
case CELL_PAD_PCLASS_TYPE_DANCEMAT:
product = input::get_product_info(input::product_type::dance_dance_revolution_mat);
break;
case CELL_PAD_PCLASS_TYPE_NAVIGATION:
case CELL_PAD_PCLASS_TYPE_STANDARD:
default:
product = input::get_product_info(input::product_type::playstation_3_controller);
break;
}
info->vendor_id[i] = config.reported_statuses[i].vendor_id;
info->product_id[i] = config.reported_statuses[i].product_id;

info->vendor_id[i] = product.vendor_id;
info->product_id[i] = product.product_id;
}
else
{
info->vendor_id[i] = pads[i]->m_vendor_id;
info->product_id[i] = pads[i]->m_product_id;
}
now_connect++;
}

info->now_connect = now_connect;
Expand Down Expand Up @@ -732,19 +753,19 @@ error_code cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
if (i >= config.get_max_connect())
break;

if (!config.is_reportedly_connected(i))
continue;

info->port_status[i] = config.reported_statuses[i];
config.reported_statuses[i] &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = config.port_setting[i];
info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;

if (config.reported_statuses[i] & CELL_PAD_STATUS_CONNECTED)
if (~config.reported_statuses[i] & CELL_PAD_STATUS_CONNECTED)
{
now_connect++;
continue;
}

info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;

now_connect++;
}

info->now_connect = now_connect;
Expand Down
15 changes: 13 additions & 2 deletions rpcs3/Emu/Cell/Modules/cellPad.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ enum
CELL_PADFILTER_IIR_CUTOFF_2ND_LPF_BT_010 = 2, // 10% Nyquist frequency
};

struct pad_data_internal
{
u16 vendor_id;
u16 product_id;
u32 port_status;
u32 device_capability;
u32 device_type;
u32 pclass_type;
u32 pclass_profile;
};

struct CellPadInfo
{
be_t<u32> max_connect;
Expand Down Expand Up @@ -192,7 +203,7 @@ struct pad_info
{
atomic_t<u32> max_connect = 0;
std::array<u32, CELL_PAD_MAX_PORT_NUM> port_setting{ 0 };
std::array<u32, CELL_PAD_MAX_PORT_NUM> reported_statuses{};
std::array<pad_data_internal, CELL_PAD_MAX_PORT_NUM> reported_statuses{};

SAVESTATE_INIT_POS(11);

Expand All @@ -209,7 +220,7 @@ struct pad_info
// This result relies on data updates from config events on a dedicated thread to receive them
bool is_reportedly_connected(u32 port_no) const
{
return port_no < get_max_connect() && !!(reported_statuses[port_no] & CELL_PAD_STATUS_CONNECTED);
return port_no < get_max_connect() && !!(reported_statuses[port_no].port_status & CELL_PAD_STATUS_CONNECTED);
}
};

Expand Down

0 comments on commit 3711780

Please sign in to comment.