Merge pull request #73 from julienlgy/feat/lib-sce-mouse
feat(libSceMouse): implement stateful mouse API exports Replace the libSceMouse stubs with an implementation that follows AnyPS5’s existing NID-based library integration. Mouse input comes from the host SDL event loop; this change does not add memory hooks or direct access to console HID devices. Manage the mouse handle, button state, timestamps, and a thread-safe, 64-event history in src/mouse_impl.cpp. Reads are non-blocking. Forward relative motion, supported buttons, vertical scrolling, and horizontal scrolling from libSceVideoOut’s SDL event loop. Release pressed buttons when the window loses focus without reporting a hardware disconnection.
This commit is contained in:
commit
0fe554943a
|
|
@ -0,0 +1,22 @@
|
|||
add_library(libSceMouse SHARED EXCLUDE_FROM_ALL
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Export.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/mouse_impl.cpp
|
||||
)
|
||||
target_include_directories(libSceMouse PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
set_target_properties(libSceMouse PROPERTIES CXX_EXTENSIONS OFF)
|
||||
configure_windows_unwind(libSceMouse)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_executable(mouse_tests
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/Mouse.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../libSceVideoOut/src/MouseInput.cpp
|
||||
)
|
||||
target_include_directories(mouse_tests PRIVATE ${LIBS_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/3rdparty/SDL2/include)
|
||||
target_link_libraries(mouse_tests PRIVATE libSceMouse libkernel libc)
|
||||
configure_windows_unwind(mouse_tests)
|
||||
add_test(NAME mouse_input COMMAND mouse_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(mouse_input PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceMouse>")
|
||||
endif()
|
||||
endif()
|
||||
|
|
@ -1,36 +1,25 @@
|
|||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
#include "prx/libSceMouse/include/MouseState.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceMouseClose(int32_t handle) {
|
||||
(void)handle;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
int APS5_VABI sceMouseInit() {
|
||||
return Mouse::Initialize();
|
||||
}
|
||||
|
||||
int APS5_VABI sceMouseInit(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
int APS5_VABI sceMouseOpen(int userId, std::int32_t type, std::int32_t index, const void* param) {
|
||||
return Mouse::Open(userId, type, index, static_cast<const MouseOpenParam*>(param));
|
||||
}
|
||||
|
||||
int APS5_VABI sceMouseOpen(int user_id, int32_t type, int32_t index, const void* param) {
|
||||
(void)user_id;
|
||||
(void)type;
|
||||
(void)index;
|
||||
(void)param;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
int APS5_VABI sceMouseClose(std::int32_t handle) {
|
||||
return Mouse::Close(handle);
|
||||
}
|
||||
|
||||
int APS5_VABI sceMouseRead(int32_t handle, MouseData* data, int32_t num) {
|
||||
(void)handle;
|
||||
(void)data;
|
||||
(void)num;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
int APS5_VABI sceMouseRead(std::int32_t handle, MouseData* data, std::int32_t num) {
|
||||
return Mouse::Read(handle, data, num);
|
||||
}
|
||||
|
||||
void MousePublishInput_nid_postfix(const MouseInputEvent& event) {
|
||||
Mouse::Publish(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef CORE_LIBS_PRX_LIBSCEMOUSE_MOUSESTATE_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEMOUSE_MOUSESTATE_HPP
|
||||
|
||||
#include "prx/libSceMouse/include/mouse_structs.h"
|
||||
|
||||
struct MouseInputEvent {
|
||||
std::int32_t x = 0;
|
||||
std::int32_t y = 0;
|
||||
std::int32_t wheel = 0;
|
||||
std::int32_t tilt = 0;
|
||||
std::uint32_t button = 0;
|
||||
bool pressed = false;
|
||||
bool resetButtons = false;
|
||||
bool connectionChange = false;
|
||||
bool connected = true;
|
||||
};
|
||||
|
||||
namespace Mouse {
|
||||
int Initialize();
|
||||
int Open(int userId, std::int32_t type, std::int32_t index, const MouseOpenParam* param);
|
||||
int Close(std::int32_t handle);
|
||||
int Read(std::int32_t handle, MouseData* data, std::int32_t num);
|
||||
void Publish(const MouseInputEvent& event);
|
||||
}
|
||||
|
||||
extern "C" void MousePublishInput_nid_postfix(const MouseInputEvent& event);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef CORE_LIBS_PRX_LIBSCEMOUSE_MOUSE_STRUCTS_H
|
||||
#define CORE_LIBS_PRX_LIBSCEMOUSE_MOUSE_STRUCTS_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include "SceTypes.hpp"
|
||||
|
||||
struct MouseOpenParam {
|
||||
std::uint8_t behaviorFlag;
|
||||
std::uint8_t reserved[7];
|
||||
};
|
||||
|
||||
constexpr int MOUSE_OK = 0;
|
||||
constexpr int MOUSE_ERROR_INVALID_ARG = static_cast<int>(0x80df0001u);
|
||||
constexpr int MOUSE_ERROR_INVALID_HANDLE = static_cast<int>(0x80df0003u);
|
||||
constexpr int MOUSE_ERROR_ALREADY_OPENED = static_cast<int>(0x80df0004u);
|
||||
constexpr int MOUSE_ERROR_NOT_INITIALIZED = static_cast<int>(0x80df0005u);
|
||||
constexpr int MOUSE_MAX_DATA_NUM = 64;
|
||||
constexpr int MOUSE_HANDLE = 1;
|
||||
constexpr std::uint8_t MOUSE_OPEN_PARAM_MERGED = 1;
|
||||
|
||||
static_assert(sizeof(MouseOpenParam) == 8);
|
||||
static_assert(sizeof(MouseData) == 40);
|
||||
static_assert(alignof(MouseData) == 8);
|
||||
static_assert(offsetof(MouseData, timestamp) == 0);
|
||||
static_assert(offsetof(MouseData, connected) == 8);
|
||||
static_assert(offsetof(MouseData, buttons) == 12);
|
||||
static_assert(offsetof(MouseData, x_axis) == 16);
|
||||
static_assert(offsetof(MouseData, y_axis) == 20);
|
||||
static_assert(offsetof(MouseData, wheel) == 24);
|
||||
static_assert(offsetof(MouseData, tilt) == 28);
|
||||
static_assert(offsetof(MouseData, reserved) == 32);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
#include "prx/libSceMouse/include/MouseState.hpp"
|
||||
#include "prx/libkernel/Time/include/Time.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
std::mutex mouseMutex;
|
||||
std::array<MouseData, MOUSE_MAX_DATA_NUM> history{};
|
||||
int head = 0;
|
||||
int count = 0;
|
||||
bool initialized = false;
|
||||
bool opened = false;
|
||||
bool connected = true;
|
||||
std::uint32_t buttons = 0;
|
||||
|
||||
void enqueue(const MouseData& data) {
|
||||
if (count == MOUSE_MAX_DATA_NUM) {
|
||||
head = (head + 1) % MOUSE_MAX_DATA_NUM;
|
||||
--count;
|
||||
}
|
||||
history[(head + count) % MOUSE_MAX_DATA_NUM] = data;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Mouse {
|
||||
|
||||
int Initialize() {
|
||||
std::lock_guard lock(mouseMutex);
|
||||
initialized = true;
|
||||
return MOUSE_OK;
|
||||
}
|
||||
|
||||
int Open(int userId, std::int32_t type, std::int32_t index, const MouseOpenParam* param) {
|
||||
std::lock_guard lock(mouseMutex);
|
||||
if (!initialized) return MOUSE_ERROR_NOT_INITIALIZED;
|
||||
if (userId < 0 || type != 0 || index != 0 ||
|
||||
(param != nullptr && (param->behaviorFlag & ~MOUSE_OPEN_PARAM_MERGED) != 0)) {
|
||||
return MOUSE_ERROR_INVALID_ARG;
|
||||
}
|
||||
if (opened) return MOUSE_ERROR_ALREADY_OPENED;
|
||||
opened = true;
|
||||
buttons = 0;
|
||||
head = 0;
|
||||
count = 0;
|
||||
MouseData initial{};
|
||||
initial.timestamp = sceKernelGetProcessTime();
|
||||
initial.connected = connected;
|
||||
enqueue(initial);
|
||||
return MOUSE_HANDLE;
|
||||
}
|
||||
|
||||
int Close(std::int32_t handle) {
|
||||
std::lock_guard lock(mouseMutex);
|
||||
if (!initialized) return MOUSE_ERROR_NOT_INITIALIZED;
|
||||
if (handle != MOUSE_HANDLE || !opened) return MOUSE_ERROR_INVALID_HANDLE;
|
||||
opened = false;
|
||||
buttons = 0;
|
||||
head = 0;
|
||||
count = 0;
|
||||
return MOUSE_OK;
|
||||
}
|
||||
|
||||
int Read(std::int32_t handle, MouseData* data, std::int32_t num) {
|
||||
std::lock_guard lock(mouseMutex);
|
||||
if (!initialized) return MOUSE_ERROR_NOT_INITIALIZED;
|
||||
if (handle != MOUSE_HANDLE || !opened) return MOUSE_ERROR_INVALID_HANDLE;
|
||||
if (data == nullptr || num <= 0 || num > MOUSE_MAX_DATA_NUM) return MOUSE_ERROR_INVALID_ARG;
|
||||
const int available = std::min(count, num);
|
||||
for (int i = 0; i < available; ++i) {
|
||||
data[i] = history[head];
|
||||
head = (head + 1) % MOUSE_MAX_DATA_NUM;
|
||||
}
|
||||
count -= available;
|
||||
return available;
|
||||
}
|
||||
|
||||
void Publish(const MouseInputEvent& event) {
|
||||
std::lock_guard lock(mouseMutex);
|
||||
if (event.connectionChange) {
|
||||
if (connected == event.connected) return;
|
||||
connected = event.connected;
|
||||
if (!connected) buttons = 0;
|
||||
} else if (!connected) {
|
||||
return;
|
||||
}
|
||||
if (!opened) return;
|
||||
if (event.resetButtons) buttons = 0;
|
||||
if (event.button != 0) {
|
||||
if (event.pressed) buttons |= event.button;
|
||||
else buttons &= ~event.button;
|
||||
}
|
||||
MouseData data{};
|
||||
data.timestamp = sceKernelGetProcessTime();
|
||||
data.connected = connected;
|
||||
data.buttons = buttons;
|
||||
data.x_axis = event.x;
|
||||
data.y_axis = event.y;
|
||||
data.wheel = event.wheel;
|
||||
data.tilt = event.tilt;
|
||||
enqueue(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
#include "prx/libSceMouse/include/mouse_structs.h"
|
||||
#include "prx/libSceMouse/include/MouseState.hpp"
|
||||
#include "prx/libSceVideoOut/include/MouseInput.hpp"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_mouse.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI sceMouseInit();
|
||||
int APS5_VABI sceMouseOpen(int, std::int32_t, std::int32_t, const void*);
|
||||
int APS5_VABI sceMouseClose(std::int32_t);
|
||||
int APS5_VABI sceMouseRead(std::int32_t, MouseData*, std::int32_t);
|
||||
}
|
||||
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
|
||||
int main() {
|
||||
MouseData data[64]{};
|
||||
Require(sceMouseOpen(1, 0, 0, nullptr) == MOUSE_ERROR_NOT_INITIALIZED);
|
||||
Require(sceMouseInit() == MOUSE_OK);
|
||||
Require(sceMouseInit() == MOUSE_OK);
|
||||
Require(sceMouseOpen(1, 0, 1, nullptr) == MOUSE_ERROR_INVALID_ARG);
|
||||
MouseOpenParam unsupported{};
|
||||
unsupported.behaviorFlag = 2;
|
||||
Require(sceMouseOpen(1, 0, 0, &unsupported) == MOUSE_ERROR_INVALID_ARG);
|
||||
Require(sceMouseOpen(1, 0, 0, nullptr) == MOUSE_HANDLE);
|
||||
Require(sceMouseOpen(1, 0, 0, nullptr) == MOUSE_ERROR_ALREADY_OPENED);
|
||||
Require(sceMouseRead(42, data, 1) == MOUSE_ERROR_INVALID_HANDLE);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, nullptr, 1) == MOUSE_ERROR_INVALID_ARG);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 65) == MOUSE_ERROR_INVALID_ARG);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 1);
|
||||
Require(data[0].connected && data[0].buttons == 0);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 0);
|
||||
|
||||
MouseInput input;
|
||||
SDL_Event event{};
|
||||
event.type = SDL_MOUSEMOTION;
|
||||
event.motion.windowID = 7;
|
||||
event.motion.xrel = 9;
|
||||
event.motion.yrel = -4;
|
||||
input.HandleEvent(event, 8);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 0);
|
||||
input.HandleEvent(event, 7);
|
||||
|
||||
event = {};
|
||||
event.type = SDL_MOUSEBUTTONDOWN;
|
||||
event.button.windowID = 7;
|
||||
event.button.button = SDL_BUTTON_RIGHT;
|
||||
input.HandleEvent(event, 7);
|
||||
event = {};
|
||||
event.type = SDL_MOUSEWHEEL;
|
||||
event.wheel.windowID = 7;
|
||||
event.wheel.x = 2;
|
||||
event.wheel.y = -3;
|
||||
event.wheel.direction = SDL_MOUSEWHEEL_FLIPPED;
|
||||
input.HandleEvent(event, 7);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 3) == 3);
|
||||
Require(data[0].x_axis == 9 && data[0].y_axis == -4 && data[0].buttons == 0);
|
||||
Require(data[1].buttons == 2);
|
||||
Require(data[2].buttons == 2 && data[2].wheel == 3 && data[2].tilt == -2);
|
||||
Require(data[0].timestamp <= data[2].timestamp);
|
||||
event = {};
|
||||
event.type = SDL_MOUSEBUTTONDOWN;
|
||||
event.button.windowID = 7;
|
||||
event.button.button = SDL_BUTTON_X1;
|
||||
input.HandleEvent(event, 7);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 0);
|
||||
|
||||
event = {};
|
||||
event.type = SDL_WINDOWEVENT;
|
||||
event.window.windowID = 7;
|
||||
event.window.event = SDL_WINDOWEVENT_FOCUS_LOST;
|
||||
input.HandleEvent(event, 7);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 1);
|
||||
Require(data[0].connected && data[0].buttons == 0);
|
||||
event.type = SDL_MOUSEMOTION;
|
||||
event.motion.xrel = 5;
|
||||
input.HandleEvent(event, 7);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 0);
|
||||
event.type = SDL_WINDOWEVENT;
|
||||
event.window.event = SDL_WINDOWEVENT_FOCUS_GAINED;
|
||||
input.HandleEvent(event, 7);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 0);
|
||||
event.window.event = SDL_WINDOWEVENT_CLOSE;
|
||||
input.HandleEvent(event, 7);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 1 && !data[0].connected);
|
||||
event.window.event = SDL_WINDOWEVENT_FOCUS_GAINED;
|
||||
input.HandleEvent(event, 7);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 1 && data[0].connected);
|
||||
|
||||
for (int i = 0; i < 70; ++i) {
|
||||
MouseInputEvent motion{};
|
||||
motion.x = i;
|
||||
MousePublishInput_nid_postfix(motion);
|
||||
}
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 64) == 64);
|
||||
Require(data[0].x_axis == 6 && data[63].x_axis == 69);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 0);
|
||||
Require(sceMouseClose(MOUSE_HANDLE) == MOUSE_OK);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == MOUSE_ERROR_INVALID_HANDLE);
|
||||
Require(sceMouseClose(MOUSE_HANDLE) == MOUSE_ERROR_INVALID_HANDLE);
|
||||
MouseOpenParam merged{};
|
||||
merged.behaviorFlag = MOUSE_OPEN_PARAM_MERGED;
|
||||
Require(sceMouseOpen(1, 0, 0, &merged) == MOUSE_HANDLE);
|
||||
Require(sceMouseRead(MOUSE_HANDLE, data, 1) == 1 && data[0].buttons == 0);
|
||||
Require(sceMouseClose(MOUSE_HANDLE) == MOUSE_OK);
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ add_library(libSceVideoOut SHARED EXCLUDE_FROM_ALL
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/VideoOutDriver.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/DisplayWindow.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/PadInput.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/MouseInput.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputMapping.cpp
|
||||
)
|
||||
|
||||
|
|
@ -14,7 +15,7 @@ target_include_directories(libSceVideoOut PRIVATE
|
|||
${CMAKE_SOURCE_DIR}/3rdparty/SDL2/include
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/Vulkan-Headers/include
|
||||
)
|
||||
target_link_libraries(libSceVideoOut PRIVATE libSceAgcDriver libScePad libc libkernel SDL2-static)
|
||||
target_link_libraries(libSceVideoOut PRIVATE libSceAgcDriver libScePad libSceMouse libc libkernel SDL2-static)
|
||||
if(WIN32)
|
||||
target_link_libraries(libSceVideoOut PRIVATE comctl32)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef CORE_LIBS_PRX_LIBSCEVIDEOOUT_MOUSEINPUT_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEVIDEOOUT_MOUSEINPUT_HPP
|
||||
|
||||
#include "SDL_events.h"
|
||||
|
||||
class MouseInput {
|
||||
public:
|
||||
void HandleEvent(const SDL_Event& event, unsigned windowId);
|
||||
|
||||
private:
|
||||
bool focused = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#include "prx/libSceVideoOut/include/MouseInput.hpp"
|
||||
#include "prx/libSceMouse/include/MouseState.hpp"
|
||||
|
||||
#include "SDL_mouse.h"
|
||||
|
||||
void MouseInput::HandleEvent(const SDL_Event& event, unsigned windowId) {
|
||||
MouseInputEvent input{};
|
||||
switch (event.type) {
|
||||
case SDL_MOUSEMOTION:
|
||||
if (event.motion.windowID != windowId || !focused) return;
|
||||
input.x = event.motion.xrel;
|
||||
input.y = event.motion.yrel;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (event.button.windowID != windowId || !focused) return;
|
||||
switch (event.button.button) {
|
||||
case SDL_BUTTON_LEFT: input.button = 1; break;
|
||||
case SDL_BUTTON_RIGHT: input.button = 2; break;
|
||||
case SDL_BUTTON_MIDDLE: input.button = 4; break;
|
||||
default: return;
|
||||
}
|
||||
input.pressed = event.type == SDL_MOUSEBUTTONDOWN;
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (event.wheel.windowID != windowId || !focused) return;
|
||||
input.wheel = event.wheel.y;
|
||||
input.tilt = event.wheel.x;
|
||||
if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
|
||||
input.wheel = -input.wheel;
|
||||
input.tilt = -input.tilt;
|
||||
}
|
||||
if (input.wheel == 0 && input.tilt == 0) return;
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
if (event.window.windowID != windowId) return;
|
||||
if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
||||
focused = false;
|
||||
input.resetButtons = true;
|
||||
} else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
|
||||
focused = true;
|
||||
input.connectionChange = true;
|
||||
} else if (event.window.event == SDL_WINDOWEVENT_CLOSE) {
|
||||
focused = false;
|
||||
input.connectionChange = true;
|
||||
input.connected = false;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
MousePublishInput_nid_postfix(input);
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
#include "SDL.h"
|
||||
#include "SDL_vulkan.h"
|
||||
#include "prx/libSceVideoOut/include/PadInput.hpp"
|
||||
#include "prx/libSceVideoOut/include/MouseInput.hpp"
|
||||
#include "prx/libScePad/include/PadState.hpp"
|
||||
#include "prx/libkernel/Equeue/Equeue.hpp"
|
||||
#include "prx/libkernel/Time/include/Time.hpp"
|
||||
|
|
@ -466,6 +467,7 @@ void VideoOutDriver::presentLoop(std::stop_token token) {
|
|||
std::shared_ptr<FlipRequest> current;
|
||||
try {
|
||||
PadInput padInput;
|
||||
MouseInput mouseInput;
|
||||
while (!token.stop_requested()) {
|
||||
{
|
||||
std::unique_lock lock(flipQueue->mutex);
|
||||
|
|
@ -481,6 +483,7 @@ void VideoOutDriver::presentLoop(std::stop_token token) {
|
|||
while (SDL_PollEvent(&event)) {
|
||||
require(event.type != SDL_QUIT, "window was closed");
|
||||
padInput.HandleEvent(event, window);
|
||||
if (window.Handle() != nullptr) mouseInput.HandleEvent(event, SDL_GetWindowID(window.Handle()));
|
||||
}
|
||||
padInput.Update();
|
||||
if (current) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue