mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-25 04:05:32 -06:00
226 lines
6.9 KiB
C++
226 lines
6.9 KiB
C++
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "mouse.h"
|
|
|
|
#include <common/singleton.h>
|
|
#include <core/libraries/system/msgdialog_ui.h>
|
|
#include <input/mouse.h>
|
|
#include "common/elf_info.h"
|
|
#include "common/logging/log.h"
|
|
#include "core/libraries/error_codes.h"
|
|
#include "core/libraries/libs.h"
|
|
|
|
#include <mutex>
|
|
|
|
using Common::ElfInfo;
|
|
|
|
namespace Libraries::Mouse {
|
|
|
|
static std::mutex g_mtx;
|
|
|
|
static bool g_initialized = false;
|
|
static bool g_mouse1_open = false;
|
|
static bool g_mouse2_open = false;
|
|
|
|
constexpr int32_t MOUSE1_HANDLE = 0x72617431; // rat1
|
|
constexpr int32_t MOUSE2_HANDLE = 0x72617432; // rat2
|
|
static_assert(MOUSE1_HANDLE > 0);
|
|
static_assert(MOUSE2_HANDLE > 0);
|
|
|
|
constexpr auto ORBIS_MOUSE_OPEN_PARAM_NORMAL = 0x00;
|
|
constexpr auto ORBIS_MOUSE_OPEN_PARAM_MERGED = 0x01;
|
|
|
|
int PS4_SYSV_ABI sceMouseClose(s32 handle) {
|
|
LOG_INFO(Lib_Mouse, "called");
|
|
if (!g_initialized) {
|
|
return ORBIS_MOUSE_ERROR_NOT_INITIALIZED;
|
|
}
|
|
std::lock_guard lck{g_mtx};
|
|
if (handle == MOUSE1_HANDLE && g_mouse1_open) {
|
|
g_mouse1_open = false;
|
|
return ORBIS_OK;
|
|
}
|
|
if (handle == MOUSE2_HANDLE && g_mouse2_open) {
|
|
g_mouse2_open = false;
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
return ORBIS_MOUSE_ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseConnectPort() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseDebugGetDeviceId() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseDeviceOpen() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseDisconnectDevice() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseDisconnectPort() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseGetDeviceInfo() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseInit() {
|
|
LOG_INFO(Lib_Mouse, "called");
|
|
std::lock_guard lck{g_mtx};
|
|
g_initialized = true;
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseMbusInit() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseOpen(s32 userId, s32 type, s32 index, OrbisMouseOpenParam* pParam) {
|
|
LOG_INFO(Lib_Mouse, "called");
|
|
if (!g_initialized) {
|
|
return ORBIS_MOUSE_ERROR_NOT_INITIALIZED;
|
|
}
|
|
if (type != 0) {
|
|
return ORBIS_MOUSE_ERROR_INVALID_ARG;
|
|
}
|
|
std::lock_guard lck{g_mtx};
|
|
|
|
bool merge = ElfInfo::Instance().FirmwareVer() >= ElfInfo::FW_20 && pParam != nullptr &&
|
|
(pParam->behaviorFlag & ORBIS_MOUSE_OPEN_PARAM_MERGED) != 0;
|
|
|
|
if (merge || index == 0) {
|
|
if (g_mouse1_open) {
|
|
return ORBIS_PAD_ERROR_ALREADY_OPENED;
|
|
}
|
|
g_mouse1_open = true;
|
|
if (!Common::Singleton<Input::GameMouse>::Instance()->m_connected) {
|
|
MsgDialog::ShowMsgDialog(
|
|
MsgDialog::MsgDialogState(MsgDialog::MsgDialogState::UserState{
|
|
.type = MsgDialog::ButtonType::YESNO,
|
|
.msg = "Game wants to use your mouse.\nDo you want to allow it?",
|
|
}),
|
|
false, [](MsgDialog::DialogResult result) {
|
|
if (result.buttonId == MsgDialog::ButtonId::YES) {
|
|
auto* mouse = Common::Singleton<Input::GameMouse>::Instance();
|
|
mouse->m_connected = true;
|
|
}
|
|
});
|
|
}
|
|
return MOUSE1_HANDLE;
|
|
}
|
|
if (index == 1) {
|
|
if (g_mouse2_open) {
|
|
return ORBIS_PAD_ERROR_ALREADY_OPENED;
|
|
}
|
|
g_mouse2_open = true;
|
|
return MOUSE2_HANDLE;
|
|
}
|
|
return ORBIS_MOUSE_ERROR_INVALID_ARG;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseRead(s32 handle, OrbisMouseData* pData, s32 num) {
|
|
LOG_TRACE(Lib_Mouse, "called");
|
|
|
|
if (!g_initialized) {
|
|
return ORBIS_MOUSE_ERROR_NOT_INITIALIZED;
|
|
}
|
|
|
|
if (num < 1 || num > 64 || pData == nullptr) {
|
|
return ORBIS_MOUSE_ERROR_INVALID_ARG;
|
|
}
|
|
|
|
std::lock_guard lck{g_mtx};
|
|
|
|
auto* mouse = Common::Singleton<Input::GameMouse>::Instance();
|
|
|
|
if (handle == MOUSE1_HANDLE) {
|
|
if (!g_mouse1_open) {
|
|
return ORBIS_MOUSE_ERROR_INVALID_HANDLE;
|
|
}
|
|
} else if (handle == MOUSE2_HANDLE) {
|
|
if (!g_mouse2_open) {
|
|
return ORBIS_MOUSE_ERROR_INVALID_HANDLE;
|
|
}
|
|
// Mouse 2 will never be connected
|
|
pData[0] = OrbisMouseData{
|
|
.connected = false,
|
|
};
|
|
return 1;
|
|
} else {
|
|
return ORBIS_MOUSE_ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (!mouse->m_connected) {
|
|
pData[0] = OrbisMouseData{
|
|
.connected = false,
|
|
};
|
|
return 1;
|
|
}
|
|
|
|
Input::MouseState states[64];
|
|
int ret_num = mouse->ReadStates(states, num);
|
|
|
|
for (int i = 0; i < ret_num; i++) {
|
|
const auto& s = states[i];
|
|
pData[i] = OrbisMouseData{
|
|
.timestamp = s.time,
|
|
.connected = true,
|
|
.buttons = s.button_state,
|
|
.xAxis = s.x_axis,
|
|
.yAxis = s.y_axis,
|
|
.wheel = s.wheel,
|
|
.tilt = s.tilt,
|
|
};
|
|
}
|
|
return ret_num;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseSetHandType() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseSetPointerSpeed() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
int PS4_SYSV_ABI sceMouseSetProcessPrivilege() {
|
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
|
return ORBIS_OK;
|
|
}
|
|
|
|
void RegisterlibSceMouse(Core::Loader::SymbolsResolver* sym) {
|
|
LIB_FUNCTION("cAnT0Rw-IwU", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseClose);
|
|
LIB_FUNCTION("Ymyy1HSSJLQ", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseConnectPort);
|
|
LIB_FUNCTION("BRXOoXQtb+k", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseDebugGetDeviceId);
|
|
LIB_FUNCTION("WiGKINCZWkc", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseDeviceOpen);
|
|
LIB_FUNCTION("eDQTFHbgeTU", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseDisconnectDevice);
|
|
LIB_FUNCTION("jJP1vYMEPd4", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseDisconnectPort);
|
|
LIB_FUNCTION("QA9Qupz3Zjw", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseGetDeviceInfo);
|
|
LIB_FUNCTION("Qs0wWulgl7U", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseInit);
|
|
LIB_FUNCTION("1FeceR5YhAo", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseMbusInit);
|
|
LIB_FUNCTION("RaqxZIf6DvE", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseOpen);
|
|
LIB_FUNCTION("x8qnXqh-tiM", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseRead);
|
|
LIB_FUNCTION("crkFfp-cmFo", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseSetHandType);
|
|
LIB_FUNCTION("ghLUU2Z5Lcg", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseSetPointerSpeed);
|
|
LIB_FUNCTION("6aANndpS0Wo", "libSceMouse", 1, "libSceMouse", 1, 1, sceMouseSetProcessPrivilege);
|
|
};
|
|
|
|
} // namespace Libraries::Mouse
|