mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-06 09:22:35 +00:00
Initial motion controls
This commit is contained in:
parent
f41829707d
commit
d5d13c2708
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user