Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
georgemoralis | ddd352f527 | |
georgemoralis | da6fa8cc6c | |
georgemoralis | 4f9caa1e73 |
|
@ -231,6 +231,8 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
||||||
src/core/libraries/ngs2/ngs2_impl.cpp
|
src/core/libraries/ngs2/ngs2_impl.cpp
|
||||||
src/core/libraries/ngs2/ngs2_impl.h
|
src/core/libraries/ngs2/ngs2_impl.h
|
||||||
src/core/libraries/ajm/ajm_error.h
|
src/core/libraries/ajm/ajm_error.h
|
||||||
|
src/core/libraries/mouse/mouse.cpp
|
||||||
|
src/core/libraries/mouse/mouse.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
||||||
|
@ -547,6 +549,8 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
||||||
|
|
||||||
set(INPUT src/input/controller.cpp
|
set(INPUT src/input/controller.cpp
|
||||||
src/input/controller.h
|
src/input/controller.h
|
||||||
|
src/input/mouse.cpp
|
||||||
|
src/input/mouse.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(EMULATOR src/emulator.cpp
|
set(EMULATOR src/emulator.cpp
|
||||||
|
|
|
@ -113,6 +113,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||||
SUB(Lib, ImeDialog) \
|
SUB(Lib, ImeDialog) \
|
||||||
SUB(Lib, AvPlayer) \
|
SUB(Lib, AvPlayer) \
|
||||||
SUB(Lib, Ngs2) \
|
SUB(Lib, Ngs2) \
|
||||||
|
SUB(Lib, Mouse) \
|
||||||
CLS(Frontend) \
|
CLS(Frontend) \
|
||||||
CLS(Render) \
|
CLS(Render) \
|
||||||
SUB(Render, Vulkan) \
|
SUB(Render, Vulkan) \
|
||||||
|
|
|
@ -80,6 +80,7 @@ enum class Class : u8 {
|
||||||
Lib_ImeDialog, ///< The LibSceImeDialog implementation.
|
Lib_ImeDialog, ///< The LibSceImeDialog implementation.
|
||||||
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
||||||
Lib_Ngs2, ///< The LibSceNgs2 implementation.
|
Lib_Ngs2, ///< The LibSceNgs2 implementation.
|
||||||
|
Lib_Mouse, ///< The LibSceMouse implementation
|
||||||
Frontend, ///< Emulator UI
|
Frontend, ///< Emulator UI
|
||||||
Render, ///< Video Core
|
Render, ///< Video Core
|
||||||
Render_Vulkan, ///< Vulkan backend
|
Render_Vulkan, ///< Vulkan backend
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "src/core/libraries/dialogs/error_dialog.h"
|
#include "src/core/libraries/dialogs/error_dialog.h"
|
||||||
#include "src/core/libraries/dialogs/ime_dialog.h"
|
#include "src/core/libraries/dialogs/ime_dialog.h"
|
||||||
#include "src/core/libraries/libpng/pngdec.h"
|
#include "src/core/libraries/libpng/pngdec.h"
|
||||||
|
#include "src/core/libraries/mouse/mouse.h"
|
||||||
|
|
||||||
namespace Libraries {
|
namespace Libraries {
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
||||||
Libraries::ErrorDialog::RegisterlibSceErrorDialog(sym);
|
Libraries::ErrorDialog::RegisterlibSceErrorDialog(sym);
|
||||||
Libraries::ImeDialog::RegisterlibSceImeDialog(sym);
|
Libraries::ImeDialog::RegisterlibSceImeDialog(sym);
|
||||||
Libraries::AvPlayer::RegisterlibSceAvPlayer(sym);
|
Libraries::AvPlayer::RegisterlibSceAvPlayer(sym);
|
||||||
|
Libraries::Mouse::RegisterlibSceMouse(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries
|
} // namespace Libraries
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
// Generated By moduleGenerator
|
||||||
|
#include <common/singleton.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 {
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceMouseClose() {
|
||||||
|
LOG_ERROR(Lib_Mouse, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
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, "(DUMMY) called");
|
||||||
|
return 2; // dummy
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceMouseRead(s32 handle, OrbisMouseData* pData, s32 num) {
|
||||||
|
bool connected = false;
|
||||||
|
Input::MouseState states[64];
|
||||||
|
auto* mouse = Common::Singleton<Input::GameMouse>::Instance();
|
||||||
|
int ret_num = mouse->ReadStates(states, num, &connected);
|
||||||
|
|
||||||
|
if (!connected) {
|
||||||
|
ret_num = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ret_num; i++) {
|
||||||
|
pData[i].buttons = states[i].buttonsState;
|
||||||
|
pData[i].connected = connected;
|
||||||
|
pData[i].timestamp = states[i].time;
|
||||||
|
pData[i].xAxis = 0;
|
||||||
|
pData[i].yAxis = 0;
|
||||||
|
pData[i].wheel = 0;
|
||||||
|
pData[i].tilt = 0;
|
||||||
|
}
|
||||||
|
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
|
|
@ -0,0 +1,50 @@
|
||||||
|
// 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;
|
||||||
|
u8 reserve[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OrbisMouseButtonDataOffset {
|
||||||
|
ORBIS_MOUSE_BUTTON_PRIMARY = 0x00000001,
|
||||||
|
ORBIS_MOUSE_BUTTON_SECONDARY = 0x00000002
|
||||||
|
};
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceMouseClose();
|
||||||
|
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
|
|
@ -0,0 +1,80 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/libraries/kernel/time_management.h"
|
||||||
|
#include "input/mouse.h"
|
||||||
|
|
||||||
|
namespace Input {
|
||||||
|
|
||||||
|
GameMouse::GameMouse() {
|
||||||
|
m_states_num = 0;
|
||||||
|
m_last_state = MouseState();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameMouse::ReadStates(MouseState* states, int states_num, bool* isConnected) {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
|
||||||
|
*isConnected = m_connected;
|
||||||
|
|
||||||
|
int ret_num = 0;
|
||||||
|
|
||||||
|
if (m_connected) {
|
||||||
|
if (m_states_num == 0) {
|
||||||
|
ret_num = 1;
|
||||||
|
states[0] = m_last_state;
|
||||||
|
} else {
|
||||||
|
for (uint32_t i = 0; i < m_states_num; i++) {
|
||||||
|
if (ret_num >= states_num) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto index = (m_first_state + i) % MAX_MOUSE_STATES;
|
||||||
|
if (!m_private[index].obtained) {
|
||||||
|
m_private[index].obtained = true;
|
||||||
|
|
||||||
|
states[ret_num++] = m_states[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseState GameMouse::GetLastState() const {
|
||||||
|
if (m_states_num == 0) {
|
||||||
|
return m_last_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto last = (m_first_state + m_states_num - 1) % MAX_MOUSE_STATES;
|
||||||
|
|
||||||
|
return m_states[last];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameMouse::AddState(const MouseState& state) {
|
||||||
|
if (m_states_num >= MAX_MOUSE_STATES) {
|
||||||
|
m_states_num = MAX_MOUSE_STATES - 1;
|
||||||
|
m_first_state = (m_first_state + 1) % MAX_MOUSE_STATES;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto index = (m_first_state + m_states_num) % MAX_MOUSE_STATES;
|
||||||
|
|
||||||
|
m_states[index] = state;
|
||||||
|
m_last_state = state;
|
||||||
|
m_private[index].obtained = false;
|
||||||
|
m_states_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameMouse::CheckButton(int id, u32 button, bool isPressed) {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
auto state = GetLastState();
|
||||||
|
state.time = Libraries::Kernel::sceKernelGetProcessTime();
|
||||||
|
if (isPressed) {
|
||||||
|
state.buttonsState |= button;
|
||||||
|
} else {
|
||||||
|
state.buttonsState &= ~button;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace Input
|
|
@ -0,0 +1,43 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <mutex>
|
||||||
|
#include "common/types.h"
|
||||||
|
|
||||||
|
namespace Input {
|
||||||
|
|
||||||
|
struct MouseState {
|
||||||
|
u32 buttonsState = 0;
|
||||||
|
u64 time = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr u32 MAX_MOUSE_STATES = 64;
|
||||||
|
|
||||||
|
class GameMouse {
|
||||||
|
public:
|
||||||
|
GameMouse();
|
||||||
|
virtual ~GameMouse() = default;
|
||||||
|
|
||||||
|
int ReadStates(MouseState* states, int states_num, bool* isConnected);
|
||||||
|
MouseState GetLastState() const;
|
||||||
|
void CheckButton(int id, u32 button, bool isPressed);
|
||||||
|
void AddState(const MouseState& state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct StateInternal {
|
||||||
|
bool obtained = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
bool m_connected = true;
|
||||||
|
MouseState m_last_state;
|
||||||
|
int m_connected_count = 0;
|
||||||
|
u32 m_states_num = 0;
|
||||||
|
u32 m_first_state = 0;
|
||||||
|
std::array<MouseState, MAX_MOUSE_STATES> m_states;
|
||||||
|
std::array<StateInternal, MAX_MOUSE_STATES> m_private;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Input
|
|
@ -16,6 +16,9 @@
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <SDL3/SDL_metal.h>
|
#include <SDL3/SDL_metal.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <common/singleton.h>
|
||||||
|
#include <core/libraries/mouse/mouse.h>
|
||||||
|
#include <input/mouse.h>
|
||||||
|
|
||||||
namespace Frontend {
|
namespace Frontend {
|
||||||
|
|
||||||
|
@ -108,11 +111,31 @@ void WindowSDL::waitEvent() {
|
||||||
case SDL_EVENT_QUIT:
|
case SDL_EVENT_QUIT:
|
||||||
is_open = false;
|
is_open = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||||
|
onMouseAction(&event);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void WindowSDL::onMouseAction(const SDL_Event* event) {
|
||||||
|
auto* mouse = Common::Singleton<Input::GameMouse>::Instance();
|
||||||
|
using Libraries::Mouse::OrbisMouseButtonDataOffset;
|
||||||
|
u32 button = 0;
|
||||||
|
switch (event->button.button) {
|
||||||
|
case SDL_BUTTON_LEFT:
|
||||||
|
button = OrbisMouseButtonDataOffset::ORBIS_MOUSE_BUTTON_PRIMARY;
|
||||||
|
break;
|
||||||
|
case SDL_BUTTON_RIGHT:
|
||||||
|
button = OrbisMouseButtonDataOffset::ORBIS_MOUSE_BUTTON_SECONDARY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (button != 0) {
|
||||||
|
mouse->CheckButton(0, button, event->type == SDL_EVENT_MOUSE_BUTTON_DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
void WindowSDL::onResize() {
|
void WindowSDL::onResize() {
|
||||||
SDL_GetWindowSizeInPixels(window, &width, &height);
|
SDL_GetWindowSizeInPixels(window, &width, &height);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ private:
|
||||||
void onResize();
|
void onResize();
|
||||||
void onKeyPress(const SDL_Event* event);
|
void onKeyPress(const SDL_Event* event);
|
||||||
void onGamepadEvent(const SDL_Event* event);
|
void onGamepadEvent(const SDL_Event* event);
|
||||||
|
void onMouseAction(const SDL_Event* event);
|
||||||
int sdlGamepadToOrbisButton(u8 button);
|
int sdlGamepadToOrbisButton(u8 button);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue