summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/emu_window.cpp22
-rw-r--r--src/common/emu_window.h5
-rw-r--r--src/common/thread.h81
3 files changed, 37 insertions, 71 deletions
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
index 6516fc633..f5b6c7301 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -28,6 +28,17 @@ static bool IsWithinTouchscreen(const EmuWindow::FramebufferLayout& layout, unsi
28 framebuffer_x < layout.bottom_screen.right); 28 framebuffer_x < layout.bottom_screen.right);
29} 29}
30 30
31std::tuple<unsigned,unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) {
32
33 new_x = std::max(new_x, framebuffer_layout.bottom_screen.left);
34 new_x = std::min(new_x, framebuffer_layout.bottom_screen.right-1);
35
36 new_y = std::max(new_y, framebuffer_layout.bottom_screen.top);
37 new_y = std::min(new_y, framebuffer_layout.bottom_screen.bottom-1);
38
39 return std::make_tuple(new_x, new_y);
40}
41
31void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { 42void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
32 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) 43 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y))
33 return; 44 return;
@@ -52,14 +63,13 @@ void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) {
52 if (!touch_pressed) 63 if (!touch_pressed)
53 return; 64 return;
54 65
55 if (IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) 66 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y))
56 TouchPressed(framebuffer_x, framebuffer_y); 67 std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y);
57 else 68
58 TouchReleased(); 69 TouchPressed(framebuffer_x, framebuffer_y);
59} 70}
60 71
61EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width, 72EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width, unsigned height) {
62 unsigned height) {
63 73
64 ASSERT(width > 0); 74 ASSERT(width > 0);
65 ASSERT(height > 0); 75 ASSERT(height > 0);
diff --git a/src/common/emu_window.h b/src/common/emu_window.h
index c8e2de04a..e0fc12a48 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -206,5 +206,10 @@ private:
206 u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320) 206 u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320)
207 u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240) 207 u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240)
208 208
209 /**
210 * Clip the provided coordinates to be inside the touchscreen area.
211 */
212 std::tuple<unsigned,unsigned> ClipToTouchScreen(unsigned new_x, unsigned new_y);
213
209 Service::HID::PadState pad_state; 214 Service::HID::PadState pad_state;
210}; 215};
diff --git a/src/common/thread.h b/src/common/thread.h
index a45728e1e..5fdb6baeb 100644
--- a/src/common/thread.h
+++ b/src/common/thread.h
@@ -51,109 +51,60 @@ int CurrentThreadId();
51void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask); 51void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask);
52void SetCurrentThreadAffinity(u32 mask); 52void SetCurrentThreadAffinity(u32 mask);
53 53
54class Event 54class Event {
55{
56public: 55public:
57 Event() 56 Event() : is_set(false) {}
58 : is_set(false)
59 {}
60 57
61 void Set() 58 void Set() {
62 {
63 std::lock_guard<std::mutex> lk(m_mutex); 59 std::lock_guard<std::mutex> lk(m_mutex);
64 if (!is_set) 60 if (!is_set) {
65 {
66 is_set = true; 61 is_set = true;
67 m_condvar.notify_one(); 62 m_condvar.notify_one();
68 } 63 }
69 } 64 }
70 65
71 void Wait() 66 void Wait() {
72 {
73 std::unique_lock<std::mutex> lk(m_mutex); 67 std::unique_lock<std::mutex> lk(m_mutex);
74 m_condvar.wait(lk, IsSet(this)); 68 m_condvar.wait(lk, [&]{ return is_set; });
75 is_set = false; 69 is_set = false;
76 } 70 }
77 71
78 void Reset() 72 void Reset() {
79 {
80 std::unique_lock<std::mutex> lk(m_mutex); 73 std::unique_lock<std::mutex> lk(m_mutex);
81 // no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration 74 // no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration
82 is_set = false; 75 is_set = false;
83 } 76 }
84 77
85private: 78private:
86 class IsSet 79 bool is_set;
87 {
88 public:
89 IsSet(const Event* ev)
90 : m_event(ev)
91 {}
92
93 bool operator()()
94 {
95 return m_event->is_set;
96 }
97
98 private:
99 const Event* const m_event;
100 };
101
102 volatile bool is_set;
103 std::condition_variable m_condvar; 80 std::condition_variable m_condvar;
104 std::mutex m_mutex; 81 std::mutex m_mutex;
105}; 82};
106 83
107// TODO: doesn't work on windows with (count > 2) 84class Barrier {
108class Barrier
109{
110public: 85public:
111 Barrier(size_t count) 86 Barrier(size_t count) : m_count(count), m_waiting(0) {}
112 : m_count(count), m_waiting(0)
113 {}
114 87
115 // block until "count" threads call Sync() 88 /// Blocks until all "count" threads have called Sync()
116 bool Sync() 89 void Sync() {
117 {
118 std::unique_lock<std::mutex> lk(m_mutex); 90 std::unique_lock<std::mutex> lk(m_mutex);
119 91
120 // TODO: broken when next round of Sync()s 92 // TODO: broken when next round of Sync()s
121 // is entered before all waiting threads return from the notify_all 93 // is entered before all waiting threads return from the notify_all
122 94
123 if (m_count == ++m_waiting) 95 if (++m_waiting == m_count) {
124 {
125 m_waiting = 0; 96 m_waiting = 0;
126 m_condvar.notify_all(); 97 m_condvar.notify_all();
127 return true; 98 } else {
128 } 99 m_condvar.wait(lk, [&]{ return m_waiting == 0; });
129 else
130 {
131 m_condvar.wait(lk, IsDoneWating(this));
132 return false;
133 } 100 }
134 } 101 }
135 102
136private: 103private:
137 class IsDoneWating
138 {
139 public:
140 IsDoneWating(const Barrier* bar)
141 : m_bar(bar)
142 {}
143
144 bool operator()()
145 {
146 return (0 == m_bar->m_waiting);
147 }
148
149 private:
150 const Barrier* const m_bar;
151 };
152
153 std::condition_variable m_condvar; 104 std::condition_variable m_condvar;
154 std::mutex m_mutex; 105 std::mutex m_mutex;
155 const size_t m_count; 106 const size_t m_count;
156 volatile size_t m_waiting; 107 size_t m_waiting;
157}; 108};
158 109
159void SleepCurrentThread(int ms); 110void SleepCurrentThread(int ms);