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 1a6e11b commit cf5eb2b
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 61 deletions.
142 changes: 83 additions & 59 deletions rpcs3/Emu/Cell/Modules/cellPad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,61 @@ 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_info[index].port_status;

// Ignore sent status for now, use the latest instead
state = (pads[index].m_port_status & CELL_PAD_STATUS_CONNECTED);

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

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

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

input::product_info product;

switch (pads[index]->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_info[index].vendor_id = product.vendor_id;
info->reported_info[index].product_id = product.product_id;
}
else
{
info->reported_info[index].vendor_id = pads[index]->m_vendor_id;
info->reported_info[index].product_id = pads[index]->m_product_id;
}
}

extern void pad_state_notify_state_change(u32 index, u32 state)
Expand All @@ -115,7 +162,7 @@ error_code cellPadInit(ppu_thread& ppu, u32 max_connect)

config.max_connect = max_connect;
config.port_setting.fill(CELL_PAD_SETTING_PRESS_OFF | CELL_PAD_SETTING_SENSOR_OFF);
config.reported_statuses = {};
config.reported_info = {};

std::array<s32, CELL_MAX_PADS> statuses{};

Expand Down Expand Up @@ -459,25 +506,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_info[i].port_status;
config.reported_info[i].port_status &= ~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_info[i] & CELL_PAD_STATUS_CONNECTED)
{
continue;
}

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

now_connect++;
}

info->now_connect = now_connect;

return CELL_OK;
}

Expand Down Expand Up @@ -649,52 +707,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];
config.reported_info[i].port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES; // TODO: should ASSIGN flags be cleared here?
info->status[i] = config.reported_info[i].port_status;

if (config.reported_statuses[i] & CELL_PAD_STATUS_CONNECTED)
if (~config.reported_info[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_info[i].vendor_id;
info->product_id[i] = config.reported_info[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 +756,19 @@ error_code cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
if (i >= config.get_max_connect())
break;

if (!config.is_reportedly_connected(i))
info->port_status[i] = config.reported_info[i].port_status;
config.reported_info[i].port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = config.port_setting[i];

if (~config.reported_info[i] & CELL_PAD_STATUS_CONNECTED)
{
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)
{
now_connect++;
}
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_info{};

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_info[port_no].port_status & CELL_PAD_STATUS_CONNECTED);
}
};

Expand Down

0 comments on commit cf5eb2b

Please sign in to comment.