cellGem: Implement cellGemSetYaw (well, at least make it work for calibration)

This commit is contained in:
Megamouse
2026-10-03 22:36:20 +02:00
parent 1ce71092c8
commit c673da45f8
3 changed files with 34 additions and 4 deletions
+24 -4
View File
@@ -3993,9 +3993,9 @@ error_code cellGemSetRumble(u32 gem_num, u8 rumble)
return CELL_OK;
}
error_code cellGemSetYaw(u32 gem_num, vm::ptr<f32> z_direction)
error_code cellGemSetYaw(u32 gem_num, f32 z_direction_x, f32 z_direction_y, f32 z_direction_z, f32 z_direction_w)
{
cellGem.todo("cellGemSetYaw(gem_num=%d, z_direction=*0x%x)", gem_num, z_direction);
cellGem.warning("cellGemSetYaw(gem_num=%d, z_direction_x=%f, z_direction_y=%f, z_direction_z=%f, z_direction_w=%f)", gem_num, z_direction_x, z_direction_y, z_direction_z, z_direction_w);
auto& gem = g_fxo->get<gem_config>();
@@ -4006,12 +4006,32 @@ error_code cellGemSetYaw(u32 gem_num, vm::ptr<f32> z_direction)
return CELL_GEM_ERROR_UNINITIALIZED;
}
if (!z_direction || !check_gem_num(gem_num))
if (!check_gem_num(gem_num))
{
return CELL_GEM_ERROR_INVALID_PARAMETER;
}
// TODO
// The game tells us that the motion controller currently points towards the given point in world coordinates (mm).
// So far we've only seen points on the camera axis (e.g. 0,0,1), which means that the controller points at the camera.
// That's our default orientation, so we simply reset the orientation.
if (z_direction_x != 0.0f || z_direction_y != 0.0f)
{
cellGem.warning("cellGemSetYaw: Unexpected direction (x=%f, y=%f, z=%f). Resetting the orientation to face the camera anyway.", z_direction_x, z_direction_y, z_direction_z);
}
if (g_cfg.io.move != move_handler::real)
{
return CELL_OK;
}
std::lock_guard pad_lock(pad::g_pad_mutex);
const auto handler = pad::get_pad_thread();
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot())
{
pad->move_data.orientation_reset_requested = true;
}
return CELL_OK;
}
+8
View File
@@ -960,6 +960,14 @@ void PadHandlerBase::get_orientation(const pad_ensemble& binding) const
return;
}
// The game told us that the controller currently points at the camera (see cellGemSetYaw)
if (std::exchange(pad->move_data.orientation_reset_requested, false))
{
device->reset_orientation();
pad->move_data.quaternion = ps_move_data::default_quaternion;
return;
}
if (!pad->move_data.orientation_enabled || pad->get_orientation_reset_button_active())
{
// This can be called extensively in quick succession, so let's just reset the pointer instead of creating a new object.
+2
View File
@@ -62,6 +62,8 @@ struct ps_move_data
bool calibration_requested = false;
bool calibration_succeeded = false;
bool orientation_reset_requested = false; // Reset the orientation to the default (facing the camera). See cellGemSetYaw.
bool magnetometer_enabled = false;
bool orientation_enabled = false;