#include "prx/libSceVideoOut/include/MouseInput.hpp" #include "prx/libSceMouse/include/MouseState.hpp" #include "SDL_mouse.h" #include "SDL_video.h" #include #include 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 = scaled(event.motion.xrel, scaleX, remainderX); input.y = scaled(event.motion.yrel, scaleY, remainderY); 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); } void MouseInput::SetPresentation(std::uint32_t sourceWidth, std::uint32_t sourceHeight, std::uint32_t presentedWidth, std::uint32_t presentedHeight) { if (sourceWidth == 0 || sourceHeight == 0 || presentedWidth == 0 || presentedHeight == 0) return; const double x = static_cast(sourceWidth) / static_cast(presentedWidth); const double y = static_cast(sourceHeight) / static_cast(presentedHeight); if (x != scaleX || y != scaleY) { std::fprintf(stderr, "[mouse] video driver %s: guest %ux%u presented at %ux%u, delta scale %.4f x %.4f\n", SDL_GetCurrentVideoDriver() ? SDL_GetCurrentVideoDriver() : "?", sourceWidth, sourceHeight, presentedWidth, presentedHeight, x, y); scaleX = x; scaleY = y; remainderX = 0.0; remainderY = 0.0; } } std::int32_t MouseInput::scaled(std::int32_t delta, double scale, double& remainder) { const double exact = static_cast(delta) * scale + remainder; const double whole = std::trunc(exact); remainder = exact - whole; return static_cast(whole); } bool MouseInput::CaptureWanted(bool allowed) const { return allowed && focused && MouseIsOpen_nid_postfix(); } void MouseInput::UpdateCapture(bool allowed) { const bool wanted = CaptureWanted(allowed); if (wanted == captured && (SDL_GetRelativeMouseMode() == SDL_TRUE) == wanted) return; if (SDL_SetRelativeMouseMode(wanted ? SDL_TRUE : SDL_FALSE) != 0) { static bool warned = false; if (!warned) { warned = true; std::fprintf(stderr, "[mouse] relative mouse mode unavailable: %s\n", SDL_GetError()); } return; } int ignoredX = 0; int ignoredY = 0; SDL_GetRelativeMouseState(&ignoredX, &ignoredY); remainderX = 0.0; remainderY = 0.0; captured = wanted; }