Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mouse lib implementation #633

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
src/core/libraries/ngs2/ngs2_impl.cpp
src/core/libraries/ngs2/ngs2_impl.h
src/core/libraries/ajm/ajm_error.h
src/core/libraries/audio3d/audio3d.cpp
src/core/libraries/audio3d/audio3d.cpp
src/core/libraries/audio3d/audio3d.h
src/core/libraries/audio3d/audio3d_error.h
src/core/libraries/audio3d/audio3d_impl.cpp
Expand All @@ -296,6 +296,8 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
src/core/libraries/remote_play/remoteplay.h
src/core/libraries/share_play/shareplay.cpp
src/core/libraries/share_play/shareplay.h
src/core/libraries/mouse/mouse.cpp
src/core/libraries/mouse/mouse.h
)

set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
Expand Down Expand Up @@ -691,6 +693,8 @@ set(IMGUI src/imgui/imgui_config.h

set(INPUT src/input/controller.cpp
src/input/controller.h
src/input/mouse.cpp
src/input/mouse.h
)

set(EMULATOR src/emulator.cpp
Expand Down
1 change: 1 addition & 0 deletions src/common/logging/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, Remoteplay) \
SUB(Lib, SharePlay) \
SUB(Lib, Fiber) \
SUB(Lib, Mouse) \
CLS(Frontend) \
CLS(Render) \
SUB(Render, Vulkan) \
Expand Down
1 change: 1 addition & 0 deletions src/common/logging/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum class Class : u8 {
Lib_Remoteplay, ///< The LibSceRemotePlay implementation
Lib_SharePlay, ///< The LibSceSharePlay implemenation
Lib_Fiber, ///< The LibSceFiber implementation.
Lib_Mouse, ///< The LibSceMouse implementation
Frontend, ///< Emulator UI
Render, ///< Video Core
Render_Vulkan, ///< Vulkan backend
Expand Down
7 changes: 7 additions & 0 deletions src/core/libraries/error_codes.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,13 @@ constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_LENGTH = 0x80920103;
constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_ID = 0x80920104;
constexpr int ORBIS_PAD_ERROR_SEND_AGAIN = 0x80920105;

// Mouse library
constexpr int ORBIS_MOUSE_ERROR_INVALID_ARG = 0x80DF0001;
constexpr int ORBIS_MOUSE_ERROR_INVALID_HANDLE = 0x80DF0003;
constexpr int ORBIS_MOUSE_ERROR_ALREADY_OPENED = 0x80DF0004;
constexpr int ORBIS_MOUSE_ERROR_NOT_INITIALIZED = 0x80DF0005;
constexpr int ORBIS_MOUSE_ERROR_FATAL = 0x80DF00FF;

// UserService library
constexpr int ORBIS_USER_SERVICE_ERROR_INTERNAL = 0x80960001;
constexpr int ORBIS_USER_SERVICE_ERROR_NOT_INITIALIZED = 0x80960002;
Expand Down
2 changes: 2 additions & 0 deletions src/core/libraries/libs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "core/libraries/system/userservice.h"
#include "core/libraries/usbd/usbd.h"
#include "core/libraries/videoout/video_out.h"
#include "src/core/libraries/mouse/mouse.h"

namespace Libraries {

Expand Down Expand Up @@ -85,6 +86,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::GameLiveStreaming::RegisterlibSceGameLiveStreaming(sym);
Libraries::SharePlay::RegisterlibSceSharePlay(sym);
Libraries::Remoteplay::RegisterlibSceRemoteplay(sym);
Libraries::Mouse::RegisterlibSceMouse(sym);
}

} // namespace Libraries
207 changes: 207 additions & 0 deletions src/core/libraries/mouse/mouse.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

// Generated By moduleGenerator
#include <common/singleton.h>
#include <core/libraries/system/msgdialog_ui.h>
#include <input/mouse.h>
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "mouse.h"

namespace Libraries::Mouse {

static bool g_initialized = false;
static bool g_mouse1_open = false;
static bool g_mouse2_open = false;

constexpr auto MOUSE1_HANDLE = 0xF1;
constexpr auto MOUSE2_HANDLE = 0xF2;

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;
}
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");
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;
}
bool merge = 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;
}

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
53 changes: 53 additions & 0 deletions src/core/libraries/mouse/mouse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once
#include "common/types.h"

namespace Core::Loader {
class SymbolsResolver;
}

namespace Libraries::Mouse {

struct OrbisMouseOpenParam {
u8 behaviorFlag;
u8 reserve[7];
};

struct OrbisMouseData {
u64 timestamp;
bool connected;
u32 buttons;
s32 xAxis;
s32 yAxis;
s32 wheel;
s32 tilt;
std::array<u8, 8> reserve{};
};

enum OrbisMouseButtonDataOffset {
ORBIS_MOUSE_BUTTON_PRIMARY = 0x00000001,
ORBIS_MOUSE_BUTTON_SECONDARY = 0x00000002,
ORBIS_MOUSE_BUTTON_OPTIONAL = 0x00000004,
ORBIS_MOUSE_BUTTON_OPTIONAL2 = 0x00000008,
ORBIS_MOUSE_BUTTON_OPTIONAL3 = 0x00000010,
};

int PS4_SYSV_ABI sceMouseClose(s32 handle);
int PS4_SYSV_ABI sceMouseConnectPort();
int PS4_SYSV_ABI sceMouseDebugGetDeviceId();
int PS4_SYSV_ABI sceMouseDeviceOpen();
int PS4_SYSV_ABI sceMouseDisconnectDevice();
int PS4_SYSV_ABI sceMouseDisconnectPort();
int PS4_SYSV_ABI sceMouseGetDeviceInfo();
int PS4_SYSV_ABI sceMouseInit();
int PS4_SYSV_ABI sceMouseMbusInit();
int PS4_SYSV_ABI sceMouseOpen(s32 userId, s32 type, s32 index, OrbisMouseOpenParam* pParam);
int PS4_SYSV_ABI sceMouseRead(s32 handle, OrbisMouseData* pData, s32 num);
int PS4_SYSV_ABI sceMouseSetHandType();
int PS4_SYSV_ABI sceMouseSetPointerSpeed();
int PS4_SYSV_ABI sceMouseSetProcessPrivilege();

void RegisterlibSceMouse(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Mouse
Loading
Loading