summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2017-08-29 11:29:10 -0400
committerGravatar GitHub2017-08-29 11:29:10 -0400
commit75cd28a7cc1c73e1be1fc72d4b86b267cbb79081 (patch)
tree18f3e7e5b864511da54d847e645dd23a69033924 /src
parentMerge pull request #2905 from danzel/fix-2902 (diff)
parentEmuWindow: refactor touch input into a TouchDevice (diff)
downloadyuzu-75cd28a7cc1c73e1be1fc72d4b86b267cbb79081.tar.gz
yuzu-75cd28a7cc1c73e1be1fc72d4b86b267cbb79081.tar.xz
yuzu-75cd28a7cc1c73e1be1fc72d4b86b267cbb79081.zip
Merge pull request #2899 from wwylele/touch-refactor
Refactor touch input into a TouchDevice
Diffstat (limited to 'src')
-rw-r--r--src/citra/config.cpp2
-rw-r--r--src/citra/default_ini.h4
-rw-r--r--src/citra_qt/configuration/config.cpp3
-rw-r--r--src/core/frontend/emu_window.cpp71
-rw-r--r--src/core/frontend/emu_window.h31
-rw-r--r--src/core/frontend/input.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp12
-rw-r--r--src/core/settings.h1
8 files changed, 87 insertions, 43 deletions
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 3869b6b5d..a48ef08c7 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -78,6 +78,8 @@ void Config::ReadValues() {
78 78
79 Settings::values.motion_device = sdl2_config->Get( 79 Settings::values.motion_device = sdl2_config->Get(
80 "Controls", "motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01"); 80 "Controls", "motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01");
81 Settings::values.touch_device =
82 sdl2_config->Get("Controls", "touch_device", "engine:emu_window");
81 83
82 // Core 84 // Core
83 Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); 85 Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true);
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index ea02a788d..4b13a2e1b 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -62,6 +62,10 @@ c_stick=
62# - "sensitivity": the coefficient converting mouse movement to tilting angle (default to 0.01) 62# - "sensitivity": the coefficient converting mouse movement to tilting angle (default to 0.01)
63motion_device= 63motion_device=
64 64
65# for touch input, the following devices are available:
66# - "emu_window" (default) for emulating touch input from mouse input to the emulation window. No parameters required
67touch_device=
68
65[Core] 69[Core]
66# Whether to use the Just-In-Time (JIT) compiler for CPU emulation 70# Whether to use the Just-In-Time (JIT) compiler for CPU emulation
67# 0: Interpreter (slow), 1 (default): JIT (fast) 71# 0: Interpreter (slow), 1 (default): JIT (fast)
diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index e2dceaa4c..ef114aad3 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -61,6 +61,8 @@ void Config::ReadValues() {
61 qt_config->value("motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01") 61 qt_config->value("motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01")
62 .toString() 62 .toString()
63 .toStdString(); 63 .toStdString();
64 Settings::values.touch_device =
65 qt_config->value("touch_device", "engine:emu_window").toString().toStdString();
64 66
65 qt_config->endGroup(); 67 qt_config->endGroup();
66 68
@@ -213,6 +215,7 @@ void Config::SaveValues() {
213 QString::fromStdString(Settings::values.analogs[i])); 215 QString::fromStdString(Settings::values.analogs[i]));
214 } 216 }
215 qt_config->setValue("motion_device", QString::fromStdString(Settings::values.motion_device)); 217 qt_config->setValue("motion_device", QString::fromStdString(Settings::values.motion_device));
218 qt_config->setValue("touch_device", QString::fromStdString(Settings::values.touch_device));
216 qt_config->endGroup(); 219 qt_config->endGroup();
217 220
218 qt_config->beginGroup("Core"); 221 qt_config->beginGroup("Core");
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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
6#include <cmath> 5#include <cmath>
7#include "common/assert.h" 6#include <mutex>
8#include "core/3ds.h"
9#include "core/core.h"
10#include "core/frontend/emu_window.h" 7#include "core/frontend/emu_window.h"
8#include "core/frontend/input.h"
11#include "core/settings.h" 9#include "core/settings.h"
12 10
11class EmuWindow::TouchState : public Input::Factory<Input::TouchDevice>,
12 public std::enable_shared_from_this<TouchState> {
13public:
14 std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage&) override {
15 return std::make_unique<Device>(shared_from_this());
16 }
17
18 std::mutex mutex;
19
20 bool touch_pressed = false; ///< True if touchpad area is currently pressed, otherwise false
21
22 float touch_x = 0.0f; ///< Touchpad X-position
23 float touch_y = 0.0f; ///< Touchpad Y-position
24
25private:
26 class Device : public Input::TouchDevice {
27 public:
28 explicit Device(std::weak_ptr<TouchState>&& touch_state) : touch_state(touch_state) {}
29 std::tuple<float, float, bool> GetStatus() const override {
30 if (auto state = touch_state.lock()) {
31 std::lock_guard<std::mutex> guard(state->mutex);
32 return std::make_tuple(state->touch_x, state->touch_y, state->touch_pressed);
33 }
34 return std::make_tuple(0.0f, 0.0f, false);
35 }
36
37 private:
38 std::weak_ptr<TouchState> touch_state;
39 };
40};
41
42EmuWindow::EmuWindow() {
43 // TODO: Find a better place to set this.
44 config.min_client_area_size = std::make_pair(400u, 480u);
45 active_config = config;
46 touch_state = std::make_shared<TouchState>();
47 Input::RegisterFactory<Input::TouchDevice>("emu_window", touch_state);
48}
49
50EmuWindow::~EmuWindow() {
51 Input::UnregisterFactory<Input::TouchDevice>("emu_window");
52}
53
13/** 54/**
14 * Check if the given x/y coordinates are within the touchpad specified by the framebuffer layout 55 * Check if the given x/y coordinates are within the touchpad specified by the framebuffer layout
15 * @param layout FramebufferLayout object describing the framebuffer size and screen positions 56 * @param layout FramebufferLayout object describing the framebuffer size and screen positions
@@ -38,22 +79,26 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
38 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) 79 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y))
39 return; 80 return;
40 81
41 touch_x = Core::kScreenBottomWidth * (framebuffer_x - framebuffer_layout.bottom_screen.left) / 82 std::lock_guard<std::mutex> guard(touch_state->mutex);
42 (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); 83 touch_state->touch_x =
43 touch_y = Core::kScreenBottomHeight * (framebuffer_y - framebuffer_layout.bottom_screen.top) / 84 static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left) /
44 (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); 85 (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left);
86 touch_state->touch_y =
87 static_cast<float>(framebuffer_y - framebuffer_layout.bottom_screen.top) /
88 (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top);
45 89
46 touch_pressed = true; 90 touch_state->touch_pressed = true;
47} 91}
48 92
49void EmuWindow::TouchReleased() { 93void EmuWindow::TouchReleased() {
50 touch_pressed = false; 94 std::lock_guard<std::mutex> guard(touch_state->mutex);
51 touch_x = 0; 95 touch_state->touch_pressed = false;
52 touch_y = 0; 96 touch_state->touch_x = 0;
97 touch_state->touch_y = 0;
53} 98}
54 99
55void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { 100void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) {
56 if (!touch_pressed) 101 if (!touch_state->touch_pressed)
57 return; 102 return;
58 103
59 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) 104 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <mutex> 7#include <memory>
8#include <tuple> 8#include <tuple>
9#include <utility> 9#include <utility>
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/math_util.h"
12#include "core/frontend/framebuffer_layout.h" 11#include "core/frontend/framebuffer_layout.h"
13 12
14/** 13/**
@@ -69,17 +68,6 @@ public:
69 void TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y); 68 void TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y);
70 69
71 /** 70 /**
72 * Gets the current touch screen state (touch X/Y coordinates and whether or not it is pressed).
73 * @note This should be called by the core emu thread to get a state set by the window thread.
74 * @todo Fix this function to be thread-safe.
75 * @return std::tuple of (x, y, pressed) where `x` and `y` are the touch coordinates and
76 * `pressed` is true if the touch screen is currently being pressed
77 */
78 std::tuple<u16, u16, bool> GetTouchState() const {
79 return std::make_tuple(touch_x, touch_y, touch_pressed);
80 }
81
82 /**
83 * Returns currently active configuration. 71 * Returns currently active configuration.
84 * @note Accesses to the returned object need not be consistent because it may be modified in 72 * @note Accesses to the returned object need not be consistent because it may be modified in
85 * another thread 73 * another thread
@@ -113,15 +101,8 @@ public:
113 void UpdateCurrentFramebufferLayout(unsigned width, unsigned height); 101 void UpdateCurrentFramebufferLayout(unsigned width, unsigned height);
114 102
115protected: 103protected:
116 EmuWindow() { 104 EmuWindow();
117 // TODO: Find a better place to set this. 105 virtual ~EmuWindow();
118 config.min_client_area_size = std::make_pair(400u, 480u);
119 active_config = config;
120 touch_x = 0;
121 touch_y = 0;
122 touch_pressed = false;
123 }
124 virtual ~EmuWindow() {}
125 106
126 /** 107 /**
127 * Processes any pending configuration changes from the last SetConfig call. 108 * Processes any pending configuration changes from the last SetConfig call.
@@ -177,10 +158,8 @@ private:
177 /// ProcessConfigurationChanges) 158 /// ProcessConfigurationChanges)
178 WindowConfig active_config; ///< Internal active configuration 159 WindowConfig active_config; ///< Internal active configuration
179 160
180 bool touch_pressed; ///< True if touchpad area is currently pressed, otherwise false 161 class TouchState;
181 162 std::shared_ptr<TouchState> touch_state;
182 u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320)
183 u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240)
184 163
185 /** 164 /**
186 * Clip the provided coordinates to be inside the touchscreen area. 165 * 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>>;
126 */ 126 */
127using MotionDevice = InputDevice<std::tuple<Math::Vec3<float>, Math::Vec3<float>>>; 127using MotionDevice = InputDevice<std::tuple<Math::Vec3<float>, Math::Vec3<float>>>;
128 128
129/**
130 * A touch device is an input device that returns a tuple of two floats and a bool. The floats are
131 * x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed.
132 */
133using TouchDevice = InputDevice<std::tuple<float, float, bool>>;
134
129} // namespace Input 135} // namespace Input
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 31f34a7ae..aa5d821f9 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -7,9 +7,9 @@
7#include <cmath> 7#include <cmath>
8#include <memory> 8#include <memory>
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/3ds.h"
10#include "core/core.h" 11#include "core/core.h"
11#include "core/core_timing.h" 12#include "core/core_timing.h"
12#include "core/frontend/emu_window.h"
13#include "core/frontend/input.h" 13#include "core/frontend/input.h"
14#include "core/hle/ipc.h" 14#include "core/hle/ipc.h"
15#include "core/hle/kernel/event.h" 15#include "core/hle/kernel/event.h"
@@ -19,7 +19,6 @@
19#include "core/hle/service/hid/hid_spvr.h" 19#include "core/hle/service/hid/hid_spvr.h"
20#include "core/hle/service/hid/hid_user.h" 20#include "core/hle/service/hid/hid_user.h"
21#include "core/hle/service/service.h" 21#include "core/hle/service/service.h"
22#include "video_core/video_core.h"
23 22
24namespace Service { 23namespace Service {
25namespace HID { 24namespace HID {
@@ -59,6 +58,7 @@ static std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::
59 buttons; 58 buttons;
60static std::unique_ptr<Input::AnalogDevice> circle_pad; 59static std::unique_ptr<Input::AnalogDevice> circle_pad;
61static std::unique_ptr<Input::MotionDevice> motion_device; 60static std::unique_ptr<Input::MotionDevice> motion_device;
61static std::unique_ptr<Input::TouchDevice> touch_device;
62 62
63DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y) { 63DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
64 // 30 degree and 60 degree are angular thresholds for directions 64 // 30 degree and 60 degree are angular thresholds for directions
@@ -96,6 +96,7 @@ static void LoadInputDevices() {
96 circle_pad = Input::CreateDevice<Input::AnalogDevice>( 96 circle_pad = Input::CreateDevice<Input::AnalogDevice>(
97 Settings::values.analogs[Settings::NativeAnalog::CirclePad]); 97 Settings::values.analogs[Settings::NativeAnalog::CirclePad]);
98 motion_device = Input::CreateDevice<Input::MotionDevice>(Settings::values.motion_device); 98 motion_device = Input::CreateDevice<Input::MotionDevice>(Settings::values.motion_device);
99 touch_device = Input::CreateDevice<Input::TouchDevice>(Settings::values.touch_device);
99} 100}
100 101
101static void UnloadInputDevices() { 102static void UnloadInputDevices() {
@@ -104,6 +105,7 @@ static void UnloadInputDevices() {
104 } 105 }
105 circle_pad.reset(); 106 circle_pad.reset();
106 motion_device.reset(); 107 motion_device.reset();
108 touch_device.reset();
107} 109}
108 110
109static void UpdatePadCallback(u64 userdata, int cycles_late) { 111static void UpdatePadCallback(u64 userdata, int cycles_late) {
@@ -172,8 +174,10 @@ static void UpdatePadCallback(u64 userdata, int cycles_late) {
172 // Get the current touch entry 174 // Get the current touch entry
173 TouchDataEntry& touch_entry = mem->touch.entries[mem->touch.index]; 175 TouchDataEntry& touch_entry = mem->touch.entries[mem->touch.index];
174 bool pressed = false; 176 bool pressed = false;
175 177 float x, y;
176 std::tie(touch_entry.x, touch_entry.y, pressed) = VideoCore::g_emu_window->GetTouchState(); 178 std::tie(x, y, pressed) = touch_device->GetStatus();
179 touch_entry.x = static_cast<u16>(x * Core::kScreenBottomWidth);
180 touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight);
177 touch_entry.valid.Assign(pressed ? 1 : 0); 181 touch_entry.valid.Assign(pressed ? 1 : 0);
178 182
179 // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which 183 // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
diff --git a/src/core/settings.h b/src/core/settings.h
index bf8014c5a..024f14666 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -81,6 +81,7 @@ struct Values {
81 std::array<std::string, NativeButton::NumButtons> buttons; 81 std::array<std::string, NativeButton::NumButtons> buttons;
82 std::array<std::string, NativeAnalog::NumAnalogs> analogs; 82 std::array<std::string, NativeAnalog::NumAnalogs> analogs;
83 std::string motion_device; 83 std::string motion_device;
84 std::string touch_device;
84 85
85 // Core 86 // Core
86 bool use_cpu_jit; 87 bool use_cpu_jit;