Initial motion controls

This commit is contained in:
kalaposfos13 2024-12-30 20:43:28 +01:00
parent f41829707d
commit d5d13c2708
4 changed files with 82 additions and 26 deletions

View File

@ -285,6 +285,16 @@ int PS4_SYSV_ABI scePadOutputReport() {
return ORBIS_OK; return ORBIS_OK;
} }
OrbisFQuaternion UpdateOrientation(const OrbisFVector3& acceleration) {
OrbisFQuaternion orientation;
orientation.x = acceleration.x / 9.8f; // uhh suggestions on this are welcome
orientation.y = acceleration.y / 9.8f;
orientation.z = acceleration.z / 9.8f;
orientation.w = 0;
return orientation;
}
int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num) { int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num) {
int connected_count = 0; int connected_count = 0;
bool connected = false; bool connected = false;
@ -304,16 +314,13 @@ int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num) {
pData[i].rightStick.y = states[i].axes[static_cast<int>(Input::Axis::RightY)]; pData[i].rightStick.y = states[i].axes[static_cast<int>(Input::Axis::RightY)];
pData[i].analogButtons.l2 = states[i].axes[static_cast<int>(Input::Axis::TriggerLeft)]; pData[i].analogButtons.l2 = states[i].axes[static_cast<int>(Input::Axis::TriggerLeft)];
pData[i].analogButtons.r2 = states[i].axes[static_cast<int>(Input::Axis::TriggerRight)]; pData[i].analogButtons.r2 = states[i].axes[static_cast<int>(Input::Axis::TriggerRight)];
pData[i].orientation.x = 0.0f; pData[i].acceleration.x = states[i].acceleration[0];
pData[i].orientation.y = 0.0f; pData[i].acceleration.y = states[i].acceleration[1];
pData[i].orientation.z = 0.0f; pData[i].acceleration.z = states[i].acceleration[2];
pData[i].orientation.w = 1.0f; pData[i].angularVelocity.x = states[i].angularVelocity[0];
pData[i].acceleration.x = 0.0f; pData[i].angularVelocity.y = states[i].angularVelocity[1];
pData[i].acceleration.y = 0.0f; pData[i].angularVelocity.z = states[i].angularVelocity[2];
pData[i].acceleration.z = 0.0f; pData[i].orientation = UpdateOrientation(pData[i].acceleration);
pData[i].angularVelocity.x = 0.0f;
pData[i].angularVelocity.y = 0.0f;
pData[i].angularVelocity.z = 0.0f;
pData[i].touchData.touchNum = pData[i].touchData.touchNum =
(states[i].touchpad[0].state ? 1 : 0) + (states[i].touchpad[1].state ? 1 : 0); (states[i].touchpad[0].state ? 1 : 0) + (states[i].touchpad[1].state ? 1 : 0);
pData[i].touchData.touch[0].x = states[i].touchpad[0].x; pData[i].touchData.touch[0].x = states[i].touchpad[0].x;
@ -367,16 +374,13 @@ int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) {
pData->rightStick.y = state.axes[static_cast<int>(Input::Axis::RightY)]; pData->rightStick.y = state.axes[static_cast<int>(Input::Axis::RightY)];
pData->analogButtons.l2 = state.axes[static_cast<int>(Input::Axis::TriggerLeft)]; pData->analogButtons.l2 = state.axes[static_cast<int>(Input::Axis::TriggerLeft)];
pData->analogButtons.r2 = state.axes[static_cast<int>(Input::Axis::TriggerRight)]; pData->analogButtons.r2 = state.axes[static_cast<int>(Input::Axis::TriggerRight)];
pData->orientation.x = 0; pData->acceleration.x = state.acceleration[0];
pData->orientation.y = 0; pData->acceleration.y = state.acceleration[1];
pData->orientation.z = 0; pData->acceleration.z = state.acceleration[2];
pData->orientation.w = 1; pData->angularVelocity.x = state.angularVelocity[0];
pData->acceleration.x = 0.0f; pData->angularVelocity.y = state.angularVelocity[1];
pData->acceleration.y = 0.0f; pData->angularVelocity.z = state.angularVelocity[2];
pData->acceleration.z = 0.0f; pData->orientation = UpdateOrientation(pData->acceleration);
pData->angularVelocity.x = 0.0f;
pData->angularVelocity.y = 0.0f;
pData->angularVelocity.z = 0.0f;
pData->touchData.touchNum = pData->touchData.touchNum =
(state.touchpad[0].state ? 1 : 0) + (state.touchpad[1].state ? 1 : 0); (state.touchpad[0].state ? 1 : 0) + (state.touchpad[1].state ? 1 : 0);
pData->touchData.touch[0].x = state.touchpad[0].x; pData->touchData.touch[0].x = state.touchpad[0].x;
@ -460,8 +464,8 @@ int PS4_SYSV_ABI scePadSetForceIntercepted() {
int PS4_SYSV_ABI scePadSetLightBar(s32 handle, const OrbisPadLightBarParam* pParam) { int PS4_SYSV_ABI scePadSetLightBar(s32 handle, const OrbisPadLightBarParam* pParam) {
if (pParam != nullptr) { if (pParam != nullptr) {
LOG_INFO(Lib_Pad, "scePadSetLightBar called handle = {} rgb = {} {} {}", handle, pParam->r, //LOG_INFO(Lib_Pad, "scePadSetLightBar called handle = {} rgb = {} {} {}", handle, pParam->r,
pParam->g, pParam->b); // pParam->g, pParam->b);
if (pParam->r < 0xD && pParam->g < 0xD && pParam->b < 0xD) { if (pParam->r < 0xD && pParam->g < 0xD && pParam->b < 0xD) {
LOG_INFO(Lib_Pad, "Invalid lightbar setting"); LOG_INFO(Lib_Pad, "Invalid lightbar setting");
@ -496,8 +500,8 @@ int PS4_SYSV_ABI scePadSetLoginUserNumber() {
} }
int PS4_SYSV_ABI scePadSetMotionSensorState(s32 handle, bool bEnable) { int PS4_SYSV_ABI scePadSetMotionSensorState(s32 handle, bool bEnable) {
LOG_ERROR(Lib_Pad, "(STUBBED) called"); LOG_ERROR(Lib_Pad, "(DUMMY) called");
return ORBIS_OK; return 1; // true?
} }
int PS4_SYSV_ABI scePadSetProcessFocus() { int PS4_SYSV_ABI scePadSetProcessFocus() {
@ -532,8 +536,8 @@ int PS4_SYSV_ABI scePadSetUserColor() {
int PS4_SYSV_ABI scePadSetVibration(s32 handle, const OrbisPadVibrationParam* pParam) { int PS4_SYSV_ABI scePadSetVibration(s32 handle, const OrbisPadVibrationParam* pParam) {
if (pParam != nullptr) { if (pParam != nullptr) {
LOG_DEBUG(Lib_Pad, "scePadSetVibration called handle = {} data = {} , {}", handle, //LOG_DEBUG(Lib_Pad, "scePadSetVibration called handle = {} data = {} , {}", handle,
pParam->smallMotor, pParam->largeMotor); // pParam->smallMotor, pParam->largeMotor);
auto* controller = Common::Singleton<Input::GameController>::Instance(); auto* controller = Common::Singleton<Input::GameController>::Instance();
controller->SetVibration(pParam->smallMotor, pParam->largeMotor); controller->SetVibration(pParam->smallMotor, pParam->largeMotor);
return ORBIS_OK; return ORBIS_OK;

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include "common/logging/log.h"
#include "core/libraries/kernel/time.h" #include "core/libraries/kernel/time.h"
#include "core/libraries/pad/pad.h" #include "core/libraries/pad/pad.h"
#include "input/controller.h" #include "input/controller.h"
@ -116,6 +117,33 @@ void GameController::Axis(int id, Input::Axis axis, int value) {
AddState(state); AddState(state);
} }
void GameController::Gyro(int id, const float gyro[3]) {
//LOG_DEBUG(Lib_Pad, "Gyro update: {} {} {}", gyro[0], gyro[1], gyro[2]);
std::scoped_lock lock{m_mutex};
auto state = GetLastState();
state.time = Libraries::Kernel::sceKernelGetProcessTime();
// Update the angular velocity (gyro data)
state.angularVelocity[0] = gyro[0]; // X-axis
state.angularVelocity[1] = gyro[1]; // Y-axis
state.angularVelocity[2] = gyro[2]; // Z-axis
AddState(state);
}
void GameController::Acceleration(int id, const float acceleration[3]) {
//LOG_DEBUG(Lib_Pad, "Accel update: {} {} {}", acceleration[0], acceleration[1], acceleration[2]);
std::scoped_lock lock{m_mutex};
auto state = GetLastState();
state.time = Libraries::Kernel::sceKernelGetProcessTime();
// Update the acceleration values
state.acceleration[0] = acceleration[0]; // X-axis
state.acceleration[1] = acceleration[1]; // Y-axis
state.acceleration[2] = acceleration[2]; // Z-axis
AddState(state);
}
void GameController::SetLightBarRGB(u8 r, u8 g, u8 b) { void GameController::SetLightBarRGB(u8 r, u8 g, u8 b) {
if (m_sdl_gamepad != nullptr) { if (m_sdl_gamepad != nullptr) {
SDL_SetGamepadLED(m_sdl_gamepad, r, g, b); SDL_SetGamepadLED(m_sdl_gamepad, r, g, b);
@ -149,6 +177,12 @@ void GameController::TryOpenSDLController() {
int gamepad_count; int gamepad_count;
SDL_JoystickID* gamepads = SDL_GetGamepads(&gamepad_count); SDL_JoystickID* gamepads = SDL_GetGamepads(&gamepad_count);
m_sdl_gamepad = gamepad_count > 0 ? SDL_OpenGamepad(gamepads[0]) : nullptr; m_sdl_gamepad = gamepad_count > 0 ? SDL_OpenGamepad(gamepads[0]) : nullptr;
if (!SDL_SetGamepadSensorEnabled(m_sdl_gamepad, SDL_SENSOR_GYRO, true)) {
LOG_ERROR(Input, "Failed to initialize gyro controls for gamepad");
}
if (!SDL_SetGamepadSensorEnabled(m_sdl_gamepad, SDL_SENSOR_ACCEL, true)) {
LOG_ERROR(Input, "Failed to initialize accel controls for gamepad");
}
SDL_free(gamepads); SDL_free(gamepads);
SetLightBarRGB(0, 0, 255); SetLightBarRGB(0, 0, 255);

View File

@ -33,6 +33,8 @@ struct State {
u64 time = 0; u64 time = 0;
int axes[static_cast<int>(Axis::AxisMax)] = {128, 128, 128, 128, 0, 0}; int axes[static_cast<int>(Axis::AxisMax)] = {128, 128, 128, 128, 0, 0};
TouchpadEntry touchpad[2] = {{false, 0, 0}, {false, 0, 0}}; TouchpadEntry touchpad[2] = {{false, 0, 0}, {false, 0, 0}};
float acceleration[3] = {0.0f, 0.0f, 0.0f};
float angularVelocity[3] = {0.0f, 0.0f, 0.0f};
}; };
inline int GetAxis(int min, int max, int value) { inline int GetAxis(int min, int max, int value) {
@ -53,6 +55,8 @@ public:
void CheckButton(int id, Libraries::Pad::OrbisPadButtonDataOffset button, bool isPressed); void CheckButton(int id, Libraries::Pad::OrbisPadButtonDataOffset button, bool isPressed);
void AddState(const State& state); void AddState(const State& state);
void Axis(int id, Input::Axis axis, int value); void Axis(int id, Input::Axis axis, int value);
void Gyro(int id, const float gyro[3]);
void Acceleration(int id, const float acceleration[3]);
void SetLightBarRGB(u8 r, u8 g, u8 b); void SetLightBarRGB(u8 r, u8 g, u8 b);
bool SetVibration(u8 smallMotor, u8 largeMotor); bool SetVibration(u8 smallMotor, u8 largeMotor);
void SetTouchpadState(int touchIndex, bool touchDown, float x, float y); void SetTouchpadState(int touchIndex, bool touchDown, float x, float y);

View File

@ -161,6 +161,20 @@ void WindowSDL::WaitEvent() {
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
OnGamepadEvent(&event); OnGamepadEvent(&event);
break; break;
// i really would have appreciated ANY KIND OF DOCUMENTATION ON THIS
// AND IT DOESN'T EVEN USE PROPER ENUMS
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
switch ((SDL_SensorType)event.gsensor.sensor) {
case SDL_SENSOR_GYRO:
controller->Gyro(0, event.gsensor.data);
break;
case SDL_SENSOR_ACCEL:
controller->Acceleration(0, event.gsensor.data);
break;
default:
break;
}
break;
case SDL_EVENT_QUIT: case SDL_EVENT_QUIT:
is_open = false; is_open = false;
break; break;