diff options
Diffstat (limited to 'src/core/frontend')
-rw-r--r-- | src/core/frontend/emu_window.cpp | 71 | ||||
-rw-r--r-- | src/core/frontend/emu_window.h | 31 | ||||
-rw-r--r-- | src/core/frontend/input.h | 6 |
3 files changed, 69 insertions, 39 deletions
diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index 54fa5c7fa..e67394177 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -2,14 +2,55 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <algorithm> #include <cmath> -#include "common/assert.h" -#include "core/3ds.h" -#include "core/core.h" +#include <mutex> #include "core/frontend/emu_window.h" +#include "core/frontend/input.h" #include "core/settings.h" +class EmuWindow::TouchState : public Input::Factory<Input::TouchDevice>, + public std::enable_shared_from_this<TouchState> { +public: + std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage&) override { + return std::make_unique<Device>(shared_from_this()); + } + + std::mutex mutex; + + bool touch_pressed = false; ///< True if touchpad area is currently pressed, otherwise false + + float touch_x = 0.0f; ///< Touchpad X-position + float touch_y = 0.0f; ///< Touchpad Y-position + +private: + class Device : public Input::TouchDevice { + public: + explicit Device(std::weak_ptr<TouchState>&& touch_state) : touch_state(touch_state) {} + std::tuple<float, float, bool> GetStatus() const override { + if (auto state = touch_state.lock()) { + std::lock_guard<std::mutex> guard(state->mutex); + return std::make_tuple(state->touch_x, state->touch_y, state->touch_pressed); + } + return std::make_tuple(0.0f, 0.0f, false); + } + + private: + std::weak_ptr<TouchState> touch_state; + }; +}; + +EmuWindow::EmuWindow() { + // TODO: Find a better place to set this. + config.min_client_area_size = std::make_pair(400u, 480u); + active_config = config; + touch_state = std::make_shared<TouchState>(); + Input::RegisterFactory<Input::TouchDevice>("emu_window", touch_state); +} + +EmuWindow::~EmuWindow() { + Input::UnregisterFactory<Input::TouchDevice>("emu_window"); +} + /** * Check if the given x/y coordinates are within the touchpad specified by the framebuffer layout * @param layout FramebufferLayout object describing the framebuffer size and screen positions @@ -38,22 +79,26 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) return; - touch_x = Core::kScreenBottomWidth * (framebuffer_x - framebuffer_layout.bottom_screen.left) / - (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); - touch_y = Core::kScreenBottomHeight * (framebuffer_y - framebuffer_layout.bottom_screen.top) / - (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); + std::lock_guard<std::mutex> guard(touch_state->mutex); + touch_state->touch_x = + static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left) / + (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); + touch_state->touch_y = + static_cast<float>(framebuffer_y - framebuffer_layout.bottom_screen.top) / + (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); - touch_pressed = true; + touch_state->touch_pressed = true; } void EmuWindow::TouchReleased() { - touch_pressed = false; - touch_x = 0; - touch_y = 0; + std::lock_guard<std::mutex> guard(touch_state->mutex); + touch_state->touch_pressed = false; + touch_state->touch_x = 0; + touch_state->touch_y = 0; } void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { - if (!touch_pressed) + if (!touch_state->touch_pressed) return; if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 7bdee251c..c10dee51b 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -4,11 +4,10 @@ #pragma once -#include <mutex> +#include <memory> #include <tuple> #include <utility> #include "common/common_types.h" -#include "common/math_util.h" #include "core/frontend/framebuffer_layout.h" /** @@ -69,17 +68,6 @@ public: void TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y); /** - * Gets the current touch screen state (touch X/Y coordinates and whether or not it is pressed). - * @note This should be called by the core emu thread to get a state set by the window thread. - * @todo Fix this function to be thread-safe. - * @return std::tuple of (x, y, pressed) where `x` and `y` are the touch coordinates and - * `pressed` is true if the touch screen is currently being pressed - */ - std::tuple<u16, u16, bool> GetTouchState() const { - return std::make_tuple(touch_x, touch_y, touch_pressed); - } - - /** * Returns currently active configuration. * @note Accesses to the returned object need not be consistent because it may be modified in * another thread @@ -113,15 +101,8 @@ public: void UpdateCurrentFramebufferLayout(unsigned width, unsigned height); protected: - EmuWindow() { - // TODO: Find a better place to set this. - config.min_client_area_size = std::make_pair(400u, 480u); - active_config = config; - touch_x = 0; - touch_y = 0; - touch_pressed = false; - } - virtual ~EmuWindow() {} + EmuWindow(); + virtual ~EmuWindow(); /** * Processes any pending configuration changes from the last SetConfig call. @@ -177,10 +158,8 @@ private: /// ProcessConfigurationChanges) WindowConfig active_config; ///< Internal active configuration - bool touch_pressed; ///< True if touchpad area is currently pressed, otherwise false - - u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320) - u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240) + class TouchState; + std::shared_ptr<TouchState> touch_state; /** * Clip the provided coordinates to be inside the touchscreen area. diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h index 5916a901d..8c256beb5 100644 --- a/src/core/frontend/input.h +++ b/src/core/frontend/input.h @@ -126,4 +126,10 @@ using AnalogDevice = InputDevice<std::tuple<float, float>>; */ using MotionDevice = InputDevice<std::tuple<Math::Vec3<float>, Math::Vec3<float>>>; +/** + * A touch device is an input device that returns a tuple of two floats and a bool. The floats are + * x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed. + */ +using TouchDevice = InputDevice<std::tuple<float, float, bool>>; + } // namespace Input |