mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-03 03:18:09 -06:00
185 lines
6.5 KiB
C++
185 lines
6.5 KiB
C++
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include <common/singleton.h>
|
|
#include "common/logging/log.h"
|
|
#include "core/libraries/error_codes.h"
|
|
#include "core/libraries/libs.h"
|
|
#include "core/libraries/move/move.h"
|
|
#include "core/libraries/move/move_error.h"
|
|
#include "input/controller.h"
|
|
#include "move.h"
|
|
|
|
auto controllers = *Common::Singleton<Input::GameControllers>::Instance();
|
|
|
|
namespace Libraries::Move {
|
|
|
|
static bool g_library_initialized = false;
|
|
|
|
s32 PS4_SYSV_ABI sceMoveInit() {
|
|
if (g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_ALREADY_INIT;
|
|
}
|
|
LOG_WARNING(Lib_Move, "Move controllers are not supported yet");
|
|
g_library_initialized = true;
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveOpen(Libraries::UserService::OrbisUserServiceUserId user_id, s32 type,
|
|
s32 index) {
|
|
LOG_DEBUG(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
// Even when no controllers are connected, this returns a proper handle.
|
|
// Internal libSceVrTracker logic requires this handle to be different from other devices.
|
|
static s32 handle = 0x30b0000;
|
|
return handle += 0x100;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveGetDeviceInfo(s32 handle, OrbisMoveDeviceInfo* info) {
|
|
LOG_TRACE(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
if (info == nullptr) {
|
|
return ORBIS_MOVE_ERROR_INVALID_ARG;
|
|
}
|
|
return ORBIS_MOVE_ERROR_NO_CONTROLLER_CONNECTED;
|
|
}
|
|
|
|
static OrbisMoveButtonDataOffset PadToMoveOffset(Libraries::Pad::OrbisPadButtonDataOffset p) {
|
|
OrbisMoveButtonDataOffset m{};
|
|
using OPBDO = Libraries::Pad::OrbisPadButtonDataOffset;
|
|
using OMBDO = OrbisMoveButtonDataOffset;
|
|
#define CONVERT(_pad, _move) \
|
|
do { \
|
|
if (True(p & OPBDO::_pad)) \
|
|
m |= OMBDO::_move; \
|
|
} while (0)
|
|
CONVERT(Circle, Circle);
|
|
CONVERT(Cross, Cross);
|
|
CONVERT(Square, Square);
|
|
CONVERT(Triangle, Triangle);
|
|
CONVERT(Options, Start);
|
|
CONVERT(L2, T);
|
|
CONVERT(L1, Move);
|
|
#undef CONVERT
|
|
return m;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveReadStateLatest(s32 handle, OrbisMoveData* data) {
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
if (data == nullptr) {
|
|
return ORBIS_MOVE_ERROR_INVALID_ARG;
|
|
}
|
|
if (!controllers.moves(0)->m_sdl_gamepad) {
|
|
return ORBIS_MOVE_ERROR_NO_CONTROLLER_CONNECTED;
|
|
}
|
|
LOG_DEBUG(Lib_Move, "called");
|
|
auto m = controllers.moves(0);
|
|
Input::State s{};
|
|
bool connected;
|
|
int connected_count;
|
|
m->ReadState(&s, &connected, &connected_count);
|
|
data->button_data.trigger_data = u16(s.axes[std::to_underlying(Input::Axis::TriggerRight)]);
|
|
data->button_data.button_data = std::to_underlying(PadToMoveOffset(s.buttonsState));
|
|
data->accelerometer[0] = s.acceleration.x;
|
|
data->accelerometer[1] = s.acceleration.y;
|
|
data->accelerometer[2] = s.acceleration.z;
|
|
data->gyro[0] = s.angularVelocity.x;
|
|
data->gyro[1] = s.angularVelocity.y;
|
|
data->gyro[2] = s.angularVelocity.z;
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveReadStateRecent(s32 handle, s64 timestamp, OrbisMoveData* data,
|
|
s32* out_count) {
|
|
LOG_TRACE(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
if (timestamp < 0 || data == nullptr || out_count == nullptr) {
|
|
return ORBIS_MOVE_ERROR_INVALID_ARG;
|
|
}
|
|
return ORBIS_MOVE_ERROR_NO_CONTROLLER_CONNECTED;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveGetExtensionPortInfo(s32 handle, void* data) {
|
|
LOG_TRACE(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
if (data == nullptr) {
|
|
return ORBIS_MOVE_ERROR_INVALID_ARG;
|
|
}
|
|
return ORBIS_MOVE_ERROR_NO_CONTROLLER_CONNECTED;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveSetVibration(s32 handle, u8 intensity) {
|
|
LOG_TRACE(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
if (!controllers.moves(0)->m_sdl_gamepad) {
|
|
return ORBIS_MOVE_ERROR_NO_CONTROLLER_CONNECTED;
|
|
}
|
|
controllers.moves(0)->SetVibration(0, intensity);
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveSetLightSphere(s32 handle, u8 red, u8 green, u8 blue) {
|
|
LOG_DEBUG(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
if (!controllers.moves(0)->m_sdl_gamepad) {
|
|
return ORBIS_MOVE_ERROR_NO_CONTROLLER_CONNECTED;
|
|
}
|
|
controllers.moves(0)->SetLightBarRGB(red, green, blue);
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveResetLightSphere(s32 handle) {
|
|
LOG_TRACE(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
// Returns success, even if no controllers are connected.
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveClose(s32 handle) {
|
|
LOG_DEBUG(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
s32 PS4_SYSV_ABI sceMoveTerm() {
|
|
LOG_DEBUG(Lib_Move, "called");
|
|
if (!g_library_initialized) {
|
|
return ORBIS_MOVE_ERROR_NOT_INIT;
|
|
}
|
|
g_library_initialized = false;
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
|
LIB_FUNCTION("j1ITE-EoJmE", "libSceMove", 1, "libSceMove", sceMoveInit);
|
|
LIB_FUNCTION("HzC60MfjJxU", "libSceMove", 1, "libSceMove", sceMoveOpen);
|
|
LIB_FUNCTION("GWXTyxs4QbE", "libSceMove", 1, "libSceMove", sceMoveGetDeviceInfo);
|
|
LIB_FUNCTION("ttU+JOhShl4", "libSceMove", 1, "libSceMove", sceMoveReadStateLatest);
|
|
LIB_FUNCTION("f2bcpK6kJfg", "libSceMove", 1, "libSceMove", sceMoveReadStateRecent);
|
|
LIB_FUNCTION("y5h7f8H1Jnk", "libSceMove", 1, "libSceMove", sceMoveGetExtensionPortInfo);
|
|
LIB_FUNCTION("IFQwtT2CeY0", "libSceMove", 1, "libSceMove", sceMoveSetVibration);
|
|
LIB_FUNCTION("T8KYHPs1JE8", "libSceMove", 1, "libSceMove", sceMoveSetLightSphere);
|
|
LIB_FUNCTION("zuxWAg3HAac", "libSceMove", 1, "libSceMove", sceMoveResetLightSphere);
|
|
LIB_FUNCTION("XX6wlxpHyeo", "libSceMove", 1, "libSceMove", sceMoveClose);
|
|
LIB_FUNCTION("tsZi60H4ypY", "libSceMove", 1, "libSceMove", sceMoveTerm);
|
|
};
|
|
|
|
} // namespace Libraries::Move
|