From 83a66dd701789761c118c7e105327a1b6166ed13 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 00:12:47 -0500
Subject: [PATCH 01/14] HID: Refactored shared memory decoding for touchpad
 support.

---
 src/core/hle/service/hid/hid.cpp | 51 +++++++++++++++++++-------------
 src/core/hle/service/hid/hid.h   | 46 ++++++++++++++++++++--------
 2 files changed, 64 insertions(+), 33 deletions(-)

diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index e0689be2e..c21799db6 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -25,17 +25,17 @@ Kernel::SharedPtr<Kernel::Event> g_event_debug_pad;
 
 // Next Pad state update information
 static PadState next_state = {{0}};
-static u32 next_index = 0;
-static s16 next_circle_x = 0;
-static s16 next_circle_y = 0;
+static u32 next_pad_index = 0;
+static s16 next_pad_circle_x = 0;
+static s16 next_pad_circle_y = 0;
 
 /**
  * Gets a pointer to the PadData structure inside HID shared memory
  */
-static inline PadData* GetPadData() {
+static inline SharedMem* GetPadData() {
     if (g_shared_mem == nullptr)
         return nullptr;
-    return reinterpret_cast<PadData*>(g_shared_mem->GetPointer().ValueOr(nullptr));
+    return reinterpret_cast<SharedMem*>(g_shared_mem->GetPointer().ValueOr(nullptr));
 }
 
 // TODO(peachum):
@@ -60,10 +60,10 @@ static inline PadData* GetPadData() {
  */
 static void UpdateNextCirclePadState() {
     static const s16 max_value = 0x9C;
-    next_circle_x = next_state.circle_left ? -max_value : 0x0;
-    next_circle_x += next_state.circle_right ? max_value : 0x0;
-    next_circle_y = next_state.circle_down ? -max_value : 0x0;
-    next_circle_y += next_state.circle_up ? max_value : 0x0;
+    next_pad_circle_x = next_state.circle_left ? -max_value : 0x0;
+    next_pad_circle_x += next_state.circle_right ? max_value : 0x0;
+    next_pad_circle_y = next_state.circle_down ? -max_value : 0x0;
+    next_pad_circle_y += next_state.circle_up ? max_value : 0x0;
 }
 
 /**
@@ -87,20 +87,18 @@ void PadButtonRelease(const PadState& pad_state) {
  * including both Pad key changes and analog circle Pad changes.
  */
 void PadUpdateComplete() {
-    PadData* pad_data = GetPadData();
+    SharedMem* shared_mem = GetPadData();
 
-    if (pad_data == nullptr) {
+    if (shared_mem == nullptr)
         return;
-    }
 
-    // Update PadData struct
-    pad_data->current_state.hex = next_state.hex;
-    pad_data->index = next_index;
-    next_index = (next_index + 1) % pad_data->entries.size();
+    shared_mem->pad.current_state.hex = next_state.hex;
+    shared_mem->pad.index = next_pad_index;
+    next_pad_index = (next_pad_index + 1) % shared_mem->pad.entries.size();
 
     // Get the previous Pad state
-    u32 last_entry_index = (pad_data->index - 1) % pad_data->entries.size();
-    PadState old_state = pad_data->entries[last_entry_index].current_state;
+    u32 last_entry_index = (shared_mem->pad.index - 1) % shared_mem->pad.entries.size();
+    PadState old_state = shared_mem->pad.entries[last_entry_index].current_state;
 
     // Compute bitmask with 1s for bits different from the old state
     PadState changed;
@@ -115,7 +113,7 @@ void PadUpdateComplete() {
     removals.hex = changed.hex & old_state.hex;
 
     // Get the current Pad entry
-    PadDataEntry* current_pad_entry = &pad_data->entries[pad_data->index];
+    PadDataEntry* current_pad_entry = &shared_mem->pad.entries[shared_mem->pad.index];
 
     // Update entry properties
     current_pad_entry->current_state.hex = next_state.hex;
@@ -123,8 +121,19 @@ void PadUpdateComplete() {
     current_pad_entry->delta_removals.hex = removals.hex;
 
     // Set circle Pad
-    current_pad_entry->circle_pad_x = next_circle_x;
-    current_pad_entry->circle_pad_y = next_circle_y;
+    current_pad_entry->circle_pad_x = next_pad_circle_x;
+    current_pad_entry->circle_pad_y = next_pad_circle_y;
+
+    // If we just updated index 0, provide a new timestamp
+    if (shared_mem->pad.index == 0) {
+        shared_mem->pad.index_reset_ticks_previous = shared_mem->pad.index_reset_ticks;
+        shared_mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks();
+    }
+
+    // Signal both handles when there's an update to Pad or touch
+    g_event_pad_or_touch_1->Signal();
+    g_event_pad_or_touch_2->Signal();
+}
 
     // If we just updated index 0, provide a new timestamp
     if (pad_data->index == 0) {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 9c6e86f77..6318d1d53 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -65,7 +65,7 @@ struct PadState {
 };
 
 /**
- * Structure of a single entry in the PadData's Pad state history array.
+ * Structure of a single entry of Pad state history within HID shared memory
  */
 struct PadDataEntry {
     PadState current_state;
@@ -77,22 +77,44 @@ struct PadDataEntry {
 };
 
 /**
- * Structure of all data related to the 3DS Pad.
+ * Structure of a single entry of touch state history within HID shared memory
  */
-struct PadData {
-    s64 index_reset_ticks;
-    s64 index_reset_ticks_previous;
-    u32 index; // the index of the last updated Pad state history element
+struct TouchDataEntry {
+    u16 x;
+    u16 y;
+    u32 data_valid;
+};
 
-    u32 pad1;
-    u32 pad2;
+/**
+ * Structure of data stored in HID shared memory
+ */
+struct SharedMem {
+    // Offset 0x0 : "PAD" data, this is used for buttons and the circle pad
+    struct {
+        s64 index_reset_ticks;
+        s64 index_reset_ticks_previous;
+        u32 index; // Index of the last updated pad state history element
 
-    PadState current_state; // same as entries[index].current_state
-    u32 raw_circle_pad_data;
+        INSERT_PADDING_BYTES(0x8);
 
-    u32 pad3;
+        PadState current_state; // Same as entries[index].current_state
+        u32 raw_circle_pad_data;
 
-    std::array<PadDataEntry, 8> entries; // Pad state history
+        INSERT_PADDING_BYTES(0x4);
+
+        std::array<PadDataEntry, 8> entries; // Pad state history
+    } pad;
+
+    // Offset 0xA8 : Touchpad data, this is used for touchpad input
+    struct {
+        s64 index_reset_ticks;
+        s64 index_reset_ticks_previous;
+        u32 index; // Index of the last updated touch state history element
+
+        INSERT_PADDING_BYTES(0xC);
+
+        std::array<TouchDataEntry, 8> entries;
+    } touch;
 };
 
 // Pre-defined PadStates for single button presses

From 3229b048d9b4f16433fb1c5d623e6b79bc1a2d93 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 00:13:49 -0500
Subject: [PATCH 02/14] HID: Moved some docstrings to the header.

---
 src/core/hle/service/hid/hid.cpp | 25 ++-----------------------
 src/core/hle/service/hid/hid.h   | 15 ++++++++++++++-
 2 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index c21799db6..5812724d2 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -32,7 +32,7 @@ static s16 next_pad_circle_y = 0;
 /**
  * Gets a pointer to the PadData structure inside HID shared memory
  */
-static inline SharedMem* GetPadData() {
+static inline SharedMem* GetSharedMem() {
     if (g_shared_mem == nullptr)
         return nullptr;
     return reinterpret_cast<SharedMem*>(g_shared_mem->GetPointer().ValueOr(nullptr));
@@ -66,28 +66,18 @@ static void UpdateNextCirclePadState() {
     next_pad_circle_y += next_state.circle_up ? max_value : 0x0;
 }
 
-/**
- * Sets a Pad state (button or button combo) as pressed
- */
 void PadButtonPress(const PadState& pad_state) {
     next_state.hex |= pad_state.hex;
     UpdateNextCirclePadState();
 }
 
-/**
- * Sets a Pad state (button or button combo) as released
- */
 void PadButtonRelease(const PadState& pad_state) {
     next_state.hex &= ~pad_state.hex;
     UpdateNextCirclePadState();
 }
 
-/**
- * Called after all Pad changes to be included in this update have been made,
- * including both Pad key changes and analog circle Pad changes.
- */
 void PadUpdateComplete() {
-    SharedMem* shared_mem = GetPadData();
+    SharedMem* shared_mem = GetSharedMem();
 
     if (shared_mem == nullptr)
         return;
@@ -135,17 +125,6 @@ void PadUpdateComplete() {
     g_event_pad_or_touch_2->Signal();
 }
 
-    // If we just updated index 0, provide a new timestamp
-    if (pad_data->index == 0) {
-        pad_data->index_reset_ticks_previous = pad_data->index_reset_ticks;
-        pad_data->index_reset_ticks = (s64)Core::g_app_core->GetTicks();
-    }
-    
-    // Signal both handles when there's an update to Pad or touch
-    g_event_pad_or_touch_1->Signal();
-    g_event_pad_or_touch_2->Signal();
-}
-
 void GetIPCHandles(Service::Interface* self) {
     u32* cmd_buff = Kernel::GetCommandBuffer();
 
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 6318d1d53..cd6263243 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -162,9 +162,22 @@ const PadState PAD_CIRCLE_DOWN  = {{1u << 31}};
  */
 void GetIPCHandles(Interface* self);
 
-// Methods for updating the HID module's state
+/**
+ * Sets a Pad state (button or button combo) as pressed
+ * @param pad_state PadState data indicating which buttons have been pressed
+ */
 void PadButtonPress(const PadState& pad_state);
+
+/**
+ * Sets a Pad state (button or button combo) as released
+ * @param pad_state PadState data indicating which buttons have been released
+ */
 void PadButtonRelease(const PadState& pad_state);
+
+/**
+ * Called after all Pad changes to be included in this update have been made, including both Pad
+ * key changes and analog circle Pad changes.
+ */
 void PadUpdateComplete();
 
 void HIDInit();

From 1a904ded40c87c41c404cfe5e74722c0a6554926 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 03:05:56 -0400
Subject: [PATCH 03/14] HID: Added functions to emulate the touchpad.

---
 src/core/hle/service/hid/hid.cpp | 48 ++++++++++++++++++++++++++++++++
 src/core/hle/service/hid/hid.h   | 13 +++++++++
 2 files changed, 61 insertions(+)

diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 5812724d2..29213e0fe 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -29,6 +29,10 @@ static u32 next_pad_index = 0;
 static s16 next_pad_circle_x = 0;
 static s16 next_pad_circle_y = 0;
 
+static u32 next_touch_index = 0;
+static u16 next_touch_x = 0;
+static u16 next_touch_y = 0;
+
 /**
  * Gets a pointer to the PadData structure inside HID shared memory
  */
@@ -125,6 +129,50 @@ void PadUpdateComplete() {
     g_event_pad_or_touch_2->Signal();
 }
 
+void TouchPress(u16 x, u16 y) {
+    next_touch_x = x;
+    next_touch_y = y;
+}
+
+void TouchRelease() {
+    next_touch_x = 0;
+    next_touch_y = 0;
+}
+
+void TouchUpdateComplete() {
+    SharedMem* shared_mem = GetSharedMem();
+
+    if (shared_mem == nullptr)
+        return;
+
+    shared_mem->touch.index = next_touch_index;
+    next_touch_index = (next_touch_index + 1) % shared_mem->touch.entries.size();
+
+    // Get the current touch entry
+    TouchDataEntry* current_touch_entry = &shared_mem->touch.entries[shared_mem->touch.index];
+
+    // Set touchpad position
+    current_touch_entry->x = next_touch_x;
+    current_touch_entry->y = next_touch_y;
+
+    // TODO(bunnei): Verify this behavior on real hardware
+    current_touch_entry->data_valid = (next_touch_x || next_touch_y) ? 1 : 0;
+
+    // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
+    // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
+    // converted to pixel coordinates." (http://3dbrew.org/wiki/HID_Shared_Memory#Offset_0xA8).
+
+    // If we just updated index 0, provide a new timestamp
+    if (shared_mem->touch.index == 0) {
+        shared_mem->touch.index_reset_ticks_previous = shared_mem->touch.index_reset_ticks;
+        shared_mem->touch.index_reset_ticks = (s64)Core::g_app_core->GetTicks();
+    }
+    
+    // Signal both handles when there's an update to Pad or touch
+    g_event_pad_or_touch_1->Signal();
+    g_event_pad_or_touch_2->Signal();
+}
+
 void GetIPCHandles(Service::Interface* self) {
     u32* cmd_buff = Kernel::GetCommandBuffer();
 
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index cd6263243..f2affb5c5 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -180,6 +180,19 @@ void PadButtonRelease(const PadState& pad_state);
  */
 void PadUpdateComplete();
 
+/**
+ * Signal that the touchpad has been pressed
+ * @param x Touchpad x-coordinate in bottom screen pixels (between 0 and 320)
+ * @param y Touchpad y-coordinate in bottom screen pixels (between 0 and 240)
+ */
+void TouchPress(u16 x, u16 y);
+
+/// Signal that touchpad has been released
+void TouchRelease();
+
+/// Signal that touchpad updates have been completed
+void TouchUpdateComplete();
+
 void HIDInit();
 void HIDShutdown();
 

From 543232436fae8d1d0f9fdd94baf0ca88d4eea067 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 03:13:26 -0400
Subject: [PATCH 04/14] EmuWindow: Added infrastructure code to enable touchpad
 support.

---
 src/common/emu_window.cpp | 65 ++++++++++++++++++++++++++++++++++++++-
 src/common/emu_window.h   | 29 +++++++++++++++++
 2 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
index 6459d2f32..11e6ad76b 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -5,6 +5,8 @@
 #include "emu_window.h"
 #include "video_core/video_core.h"
 
+bool EmuWindow::touch_pressed = false;
+
 void EmuWindow::KeyPressed(KeyMap::HostDeviceKey key) {
     Service::HID::PadState mapped_key = KeyMap::GetPadKey(key);
 
@@ -17,7 +19,68 @@ void EmuWindow::KeyReleased(KeyMap::HostDeviceKey key) {
     Service::HID::PadButtonRelease(mapped_key);
 }
 
-EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width, unsigned height) {
+/**
+ * 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
+ * @param framebuffer_x Framebuffer x-coordinate to check
+ * @param framebuffer_y Framebuffer y-coordinate to check
+ * @return True if the coordinates are within the touchpad, otherwise false
+ */
+static bool IsWithinTouchscreen(const EmuWindow::FramebufferLayout& layout, unsigned framebuffer_x,
+    unsigned framebuffer_y) {
+
+    return (framebuffer_y >= layout.bottom_screen.top &&
+        framebuffer_y < layout.bottom_screen.bottom &&
+        framebuffer_x >= layout.bottom_screen.left &&
+        framebuffer_x < layout.bottom_screen.right);
+}
+
+void EmuWindow::TouchPressed(const FramebufferLayout& layout, unsigned framebuffer_x,
+    unsigned framebuffer_y) {
+
+    if (IsWithinTouchscreen(layout, framebuffer_x, framebuffer_y)) {
+        u16 touch_x = VideoCore::kScreenBottomWidth * (framebuffer_x - layout.bottom_screen.left) /
+            (layout.bottom_screen.right - layout.bottom_screen.left);
+        u16 touch_y = VideoCore::kScreenBottomHeight * (framebuffer_y - layout.bottom_screen.top) /
+            (layout.bottom_screen.bottom - layout.bottom_screen.top);
+
+        Service::HID::TouchPress(touch_x, touch_y);
+        Service::HID::TouchUpdateComplete();
+
+        touch_pressed = true;
+    }
+}
+
+void EmuWindow::TouchReleased(const FramebufferLayout& layout, unsigned framebuffer_x,
+    unsigned framebuffer_y) {
+
+    if (IsWithinTouchscreen(layout, framebuffer_x, framebuffer_y)) {
+
+        Service::HID::TouchRelease();
+        Service::HID::TouchUpdateComplete();
+
+        touch_pressed = false;
+    }
+}
+
+void EmuWindow::TouchMoved(const FramebufferLayout& layout, unsigned framebuffer_x,
+    unsigned framebuffer_y) {
+
+    if (touch_pressed) {
+        if (IsWithinTouchscreen(layout, framebuffer_x, framebuffer_y)) {
+            EmuWindow::TouchPressed(layout, framebuffer_x, framebuffer_y);
+        } else {
+            Service::HID::TouchRelease();
+            Service::HID::TouchUpdateComplete();
+
+            touch_pressed = false;
+        }
+    }
+}
+
+EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width,
+    unsigned height) {
+
     ASSERT(width > 0);
     ASSERT(height > 0);
 
diff --git a/src/common/emu_window.h b/src/common/emu_window.h
index f6099fdb6..df81e9e0f 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -76,6 +76,33 @@ public:
     /// Signals a key release action to the HID module
     static void KeyReleased(KeyMap::HostDeviceKey key);
 
+    /**
+     * Signal that a touch pressed event has occurred (e.g. mouse click pressed)
+     * @param layout FramebufferLayout object describing the framebuffer size and screen positions
+     * @param framebuffer_x Framebuffer x-coordinate that was pressed
+     * @param framebuffer_y Framebuffer y-coordinate that was pressed
+     */
+    static void TouchPressed(const FramebufferLayout& layout, unsigned framebuffer_x,
+        unsigned framebuffer_y);
+
+    /**
+     * Signal that a touch released event has occurred (e.g. mouse click released)
+     * @param layout FramebufferLayout object describing the framebuffer size and screen positions
+     * @param framebuffer_x Framebuffer x-coordinate that was released
+     * @param framebuffer_y Framebuffer y-coordinate that was released
+     */
+    static void TouchReleased(const FramebufferLayout& layout, unsigned framebuffer_x,
+        unsigned framebuffer_y);
+
+    /**
+     * Signal that a touch movement event has occurred (e.g. mouse was moved over the emu window)
+     * @param layout FramebufferLayout object describing the framebuffer size and screen positions
+     * @param framebuffer_x Framebuffer x-coordinate
+     * @param framebuffer_y Framebuffer y-coordinate
+     */
+    static void TouchMoved(const FramebufferLayout& layout, unsigned framebuffer_x,
+        unsigned framebuffer_y);
+
     /**
      * Returns currently active configuration.
      * @note Accesses to the returned object need not be consistent because it may be modified in another thread
@@ -168,4 +195,6 @@ private:
 
     WindowConfig config;         ///< Internal configuration (changes pending for being applied in ProcessConfigurationChanges)
     WindowConfig active_config;  ///< Internal active configuration
+
+    static bool touch_pressed;   ///< True if touchpad area is currently pressed, otherwise false
 };

From dd73217ae388a74f0c4d000ef52edd0f2b7fa64c Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 03:19:33 -0400
Subject: [PATCH 05/14] GLFW: Implemented EmuWindow touchpad support.

---
 src/citra/emu_window/emu_window_glfw.cpp | 22 ++++++++++++++++++++++
 src/citra/emu_window/emu_window_glfw.h   |  4 ++++
 2 files changed, 26 insertions(+)

diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
index 81231e1e5..8a0cd9b5a 100644
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ b/src/citra/emu_window/emu_window_glfw.cpp
@@ -16,6 +16,26 @@ EmuWindow_GLFW* EmuWindow_GLFW::GetEmuWindow(GLFWwindow* win) {
     return static_cast<EmuWindow_GLFW*>(glfwGetWindowUserPointer(win));
 }
 
+void EmuWindow_GLFW::OnMouseButtonEvent(GLFWwindow* window, int button, int action, int mods) {
+    if (button == GLFW_MOUSE_BUTTON_LEFT) {
+        auto layout = GetEmuWindow(window)->GetFramebufferLayout();
+        double x, y;
+        glfwGetCursorPos(window, &x, &y);
+
+        if (action == GLFW_PRESS) {
+            EmuWindow::TouchPressed(layout, static_cast<u16>(x), static_cast<u16>(y));
+        } else if (action == GLFW_RELEASE) {
+            EmuWindow::TouchReleased(layout, static_cast<u16>(x), static_cast<u16>(y));
+        }
+    }
+}
+
+void EmuWindow_GLFW::OnCursorPosEvent(GLFWwindow* window, double x, double y) {
+
+    auto layout = GetEmuWindow(window)->GetFramebufferLayout();
+    EmuWindow::TouchMoved(layout, static_cast<u16>(x), static_cast<u16>(y));
+}
+
 /// Called by GLFW when a key event occurs
 void EmuWindow_GLFW::OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods) {
 
@@ -88,6 +108,8 @@ EmuWindow_GLFW::EmuWindow_GLFW() {
 
     // Setup callbacks
     glfwSetKeyCallback(m_render_window, OnKeyEvent);
+    glfwSetMouseButtonCallback(m_render_window, OnMouseButtonEvent);
+    glfwSetCursorPosCallback(m_render_window, OnCursorPosEvent);
     glfwSetFramebufferSizeCallback(m_render_window, OnFramebufferResizeEvent);
     glfwSetWindowSizeCallback(m_render_window, OnClientAreaResizeEvent);
 
diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h
index 5252fccc8..16c109b79 100644
--- a/src/citra/emu_window/emu_window_glfw.h
+++ b/src/citra/emu_window/emu_window_glfw.h
@@ -27,6 +27,10 @@ public:
 
     static void OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods);
 
+    static void OnMouseButtonEvent(GLFWwindow* window, int button, int action, int mods);
+
+    static void OnCursorPosEvent(GLFWwindow* window, double x, double y);
+
     /// Whether the window is still open, and a close request hasn't yet been sent
     const bool IsOpen();
 

From f213000cc421a0d00af35e160d9dff9eea617cf6 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 03:42:40 -0400
Subject: [PATCH 06/14] Qt: Implemented EmuWindow touchpad support.

---
 src/citra_qt/bootmanager.cpp | 25 +++++++++++++++++++++++++
 src/citra_qt/bootmanager.h   |  4 ++++
 2 files changed, 29 insertions(+)

diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index a040e75c1..cf07e65cc 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -278,6 +278,31 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event)
     Service::HID::PadUpdateComplete();
 }
 
+void GRenderWindow::mousePressEvent(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton)  {
+        auto pos = event->pos();
+        EmuWindow::TouchPressed(GetFramebufferLayout(), static_cast<u16>(pos.x()),
+            static_cast<u16>(pos.y()));
+    }
+}
+
+void GRenderWindow::mouseMoveEvent(QMouseEvent *event)
+{
+    auto pos = event->pos();
+    EmuWindow::TouchMoved(GetFramebufferLayout(), static_cast<u16>(pos.x()),
+        static_cast<u16>(pos.y()));
+}
+
+void GRenderWindow::mouseReleaseEvent(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton)  {
+        auto pos = event->pos();
+        EmuWindow::TouchReleased(GetFramebufferLayout(), static_cast<u16>(pos.x()),
+            static_cast<u16>(pos.y()));
+    }
+}
+
 void GRenderWindow::ReloadSetKeymaps()
 {
     KeyMap::SetKeyMapping({Settings::values.pad_a_key,      keyboard_id}, Service::HID::PAD_A);
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h
index a55db682a..288da45a1 100644
--- a/src/citra_qt/bootmanager.h
+++ b/src/citra_qt/bootmanager.h
@@ -121,6 +121,10 @@ public:
     void keyPressEvent(QKeyEvent* event) override;
     void keyReleaseEvent(QKeyEvent* event) override;
 
+    void mousePressEvent(QMouseEvent *event) override;
+    void mouseMoveEvent(QMouseEvent *event) override;
+    void mouseReleaseEvent(QMouseEvent *event) override;
+
     void ReloadSetKeymaps() override;
 
     void OnClientAreaResized(unsigned width, unsigned height);

From e9b9f1842be5afa794f03e2a0fa29d49cfca2601 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 21:21:25 -0400
Subject: [PATCH 07/14] HID: Added static asserts to check register position in
 shared memory.

---
 src/core/hle/service/hid/hid.h | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index f2affb5c5..e4665a43c 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -89,7 +89,7 @@ struct TouchDataEntry {
  * Structure of data stored in HID shared memory
  */
 struct SharedMem {
-    // Offset 0x0 : "PAD" data, this is used for buttons and the circle pad
+    // "Pad data, this is used for buttons and the circle pad
     struct {
         s64 index_reset_ticks;
         s64 index_reset_ticks_previous;
@@ -105,7 +105,7 @@ struct SharedMem {
         std::array<PadDataEntry, 8> entries; // Pad state history
     } pad;
 
-    // Offset 0xA8 : Touchpad data, this is used for touchpad input
+    // Touchpad data, this is used for touchpad input
     struct {
         s64 index_reset_ticks;
         s64 index_reset_ticks_previous;
@@ -117,6 +117,20 @@ struct SharedMem {
     } touch;
 };
 
+// TODO: MSVC does not support using offsetof() on non-static data members even though this
+//       is technically allowed since C++11. This macro should be enabled once MSVC adds
+//       support for that.
+#ifndef _MSC_VER
+#define ASSERT_REG_POSITION(field_name, position)                  \
+    static_assert(offsetof(SharedMem, field_name) == position * 4, \
+                  "Field "#field_name" has invalid position")
+
+ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0);
+ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A);
+
+#undef ASSERT_REG_POSITION
+#endif // !defined(_MSC_VER)
+
 // Pre-defined PadStates for single button presses
 const PadState PAD_NONE         = {{0}};
 const PadState PAD_A            = {{1u << 0}};

From 432aa1044c12b9b2ac9815c6ab41917ac971a616 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 21:28:23 -0400
Subject: [PATCH 08/14] HID: Changed TouchDataEntry `valid` to a BitField and
 added some doc strings.

---
 src/core/hle/service/hid/hid.cpp | 2 +-
 src/core/hle/service/hid/hid.h   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 29213e0fe..72e2d63e3 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -156,7 +156,7 @@ void TouchUpdateComplete() {
     current_touch_entry->y = next_touch_y;
 
     // TODO(bunnei): Verify this behavior on real hardware
-    current_touch_entry->data_valid = (next_touch_x || next_touch_y) ? 1 : 0;
+    current_touch_entry->valid = (next_touch_x || next_touch_y) ? 1 : 0;
 
     // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
     // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index e4665a43c..7fdf5828a 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -80,9 +80,9 @@ struct PadDataEntry {
  * Structure of a single entry of touch state history within HID shared memory
  */
 struct TouchDataEntry {
-    u16 x;
-    u16 y;
-    u32 data_valid;
+    u16 x;                   ///< Y-coordinate of a touchpad press on the lower screen
+    u16 y;                   ///< X-coordinate of a touchpad press on the lower screen
+    BitField<0,7,u32> valid; ///< Set to 1 when this entry contains actual X/Y data, otherwise 0
 };
 
 /**

From a1a1a5c6c537fa35f914e3bb5deaae48ada95c99 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 21:32:13 -0400
Subject: [PATCH 09/14] HID: Cleanup how `next_touch_index` is calculated for
 Pad and touch.

---
 src/core/hle/service/hid/hid.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 72e2d63e3..703a765b5 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -88,7 +88,7 @@ void PadUpdateComplete() {
 
     shared_mem->pad.current_state.hex = next_state.hex;
     shared_mem->pad.index = next_pad_index;
-    next_pad_index = (next_pad_index + 1) % shared_mem->pad.entries.size();
+    ++next_touch_index %= shared_mem->pad.entries.size();
 
     // Get the previous Pad state
     u32 last_entry_index = (shared_mem->pad.index - 1) % shared_mem->pad.entries.size();
@@ -146,7 +146,7 @@ void TouchUpdateComplete() {
         return;
 
     shared_mem->touch.index = next_touch_index;
-    next_touch_index = (next_touch_index + 1) % shared_mem->touch.entries.size();
+    ++next_touch_index %= shared_mem->touch.entries.size();
 
     // Get the current touch entry
     TouchDataEntry* current_touch_entry = &shared_mem->touch.entries[shared_mem->touch.index];

From 953e09ddb5cab8f4d8606966020e8eefa20e04ce Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 8 Mar 2015 21:45:45 -0400
Subject: [PATCH 10/14] EmuWindow: Made pad/touch functions non-static.

---
 src/citra/emu_window/emu_window_glfw.cpp | 27 ++++++++++++------------
 src/common/emu_window.cpp                |  2 --
 src/common/emu_window.h                  | 15 ++++++-------
 3 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
index 8a0cd9b5a..3e58d6663 100644
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ b/src/citra/emu_window/emu_window_glfw.cpp
@@ -16,35 +16,36 @@ EmuWindow_GLFW* EmuWindow_GLFW::GetEmuWindow(GLFWwindow* win) {
     return static_cast<EmuWindow_GLFW*>(glfwGetWindowUserPointer(win));
 }
 
-void EmuWindow_GLFW::OnMouseButtonEvent(GLFWwindow* window, int button, int action, int mods) {
+void EmuWindow_GLFW::OnMouseButtonEvent(GLFWwindow* win, int button, int action, int mods) {
     if (button == GLFW_MOUSE_BUTTON_LEFT) {
-        auto layout = GetEmuWindow(window)->GetFramebufferLayout();
+        auto emu_window = GetEmuWindow(win);
+        auto layout = emu_window->GetFramebufferLayout();
         double x, y;
-        glfwGetCursorPos(window, &x, &y);
+        glfwGetCursorPos(win, &x, &y);
 
         if (action == GLFW_PRESS) {
-            EmuWindow::TouchPressed(layout, static_cast<u16>(x), static_cast<u16>(y));
+            emu_window->TouchPressed(layout, static_cast<u16>(x), static_cast<u16>(y));
         } else if (action == GLFW_RELEASE) {
-            EmuWindow::TouchReleased(layout, static_cast<u16>(x), static_cast<u16>(y));
+            emu_window->TouchReleased(layout, static_cast<u16>(x), static_cast<u16>(y));
         }
     }
 }
 
-void EmuWindow_GLFW::OnCursorPosEvent(GLFWwindow* window, double x, double y) {
-
-    auto layout = GetEmuWindow(window)->GetFramebufferLayout();
-    EmuWindow::TouchMoved(layout, static_cast<u16>(x), static_cast<u16>(y));
+void EmuWindow_GLFW::OnCursorPosEvent(GLFWwindow* win, double x, double y) {
+    auto emu_window = GetEmuWindow(win);
+    auto layout = emu_window->GetFramebufferLayout();
+    emu_window->TouchMoved(layout, static_cast<u16>(x), static_cast<u16>(y));
 }
 
 /// Called by GLFW when a key event occurs
 void EmuWindow_GLFW::OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods) {
-
-    int keyboard_id = GetEmuWindow(win)->keyboard_id;
+    auto emu_window = GetEmuWindow(win);
+    int keyboard_id = emu_window->keyboard_id;
 
     if (action == GLFW_PRESS) {
-        EmuWindow::KeyPressed({key, keyboard_id});
+        emu_window->KeyPressed({key, keyboard_id});
     } else if (action == GLFW_RELEASE) {
-        EmuWindow::KeyReleased({key, keyboard_id});
+        emu_window->KeyReleased({ key, keyboard_id });
     }
 
     Service::HID::PadUpdateComplete();
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
index 11e6ad76b..89bb89481 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -5,8 +5,6 @@
 #include "emu_window.h"
 #include "video_core/video_core.h"
 
-bool EmuWindow::touch_pressed = false;
-
 void EmuWindow::KeyPressed(KeyMap::HostDeviceKey key) {
     Service::HID::PadState mapped_key = KeyMap::GetPadKey(key);
 
diff --git a/src/common/emu_window.h b/src/common/emu_window.h
index df81e9e0f..8e4b510e9 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -71,10 +71,10 @@ public:
     virtual void ReloadSetKeymaps() = 0;
 
     /// Signals a key press action to the HID module
-    static void KeyPressed(KeyMap::HostDeviceKey key);
+    void KeyPressed(KeyMap::HostDeviceKey key);
 
     /// Signals a key release action to the HID module
-    static void KeyReleased(KeyMap::HostDeviceKey key);
+    void KeyReleased(KeyMap::HostDeviceKey key);
 
     /**
      * Signal that a touch pressed event has occurred (e.g. mouse click pressed)
@@ -82,8 +82,7 @@ public:
      * @param framebuffer_x Framebuffer x-coordinate that was pressed
      * @param framebuffer_y Framebuffer y-coordinate that was pressed
      */
-    static void TouchPressed(const FramebufferLayout& layout, unsigned framebuffer_x,
-        unsigned framebuffer_y);
+    void TouchPressed(const FramebufferLayout& layout, unsigned framebuffer_x, unsigned framebuffer_y);
 
     /**
      * Signal that a touch released event has occurred (e.g. mouse click released)
@@ -91,8 +90,7 @@ public:
      * @param framebuffer_x Framebuffer x-coordinate that was released
      * @param framebuffer_y Framebuffer y-coordinate that was released
      */
-    static void TouchReleased(const FramebufferLayout& layout, unsigned framebuffer_x,
-        unsigned framebuffer_y);
+    void TouchReleased(const FramebufferLayout& layout, unsigned framebuffer_x, unsigned framebuffer_y);
 
     /**
      * Signal that a touch movement event has occurred (e.g. mouse was moved over the emu window)
@@ -100,8 +98,7 @@ public:
      * @param framebuffer_x Framebuffer x-coordinate
      * @param framebuffer_y Framebuffer y-coordinate
      */
-    static void TouchMoved(const FramebufferLayout& layout, unsigned framebuffer_x,
-        unsigned framebuffer_y);
+    void TouchMoved(const FramebufferLayout& layout, unsigned framebuffer_x, unsigned framebuffer_y);
 
     /**
      * Returns currently active configuration.
@@ -196,5 +193,5 @@ private:
     WindowConfig config;         ///< Internal configuration (changes pending for being applied in ProcessConfigurationChanges)
     WindowConfig active_config;  ///< Internal active configuration
 
-    static bool touch_pressed;   ///< True if touchpad area is currently pressed, otherwise false
+    bool touch_pressed;          ///< True if touchpad area is currently pressed, otherwise false
 };

From d61b26b79f889603a084e148626bba3c267cf75f Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Mon, 9 Mar 2015 00:14:59 -0400
Subject: [PATCH 11/14] HID: Complete refactor of pad/touch input to fix
 threading issues.

---
 src/citra/emu_window/emu_window_glfw.cpp |  17 ++--
 src/citra_qt/bootmanager.cpp             |  22 ++---
 src/common/emu_window.cpp                |  74 ++++++----------
 src/common/emu_window.h                  |  57 ++++++++-----
 src/core/hle/service/hid/hid.cpp         | 104 +++++------------------
 src/core/hle/service/hid/hid.h           |  35 ++------
 src/core/hw/gpu.cpp                      |   4 +
 7 files changed, 109 insertions(+), 204 deletions(-)

diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
index 3e58d6663..997e3bc7d 100644
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ b/src/citra/emu_window/emu_window_glfw.cpp
@@ -23,18 +23,15 @@ void EmuWindow_GLFW::OnMouseButtonEvent(GLFWwindow* win, int button, int action,
         double x, y;
         glfwGetCursorPos(win, &x, &y);
 
-        if (action == GLFW_PRESS) {
-            emu_window->TouchPressed(layout, static_cast<u16>(x), static_cast<u16>(y));
-        } else if (action == GLFW_RELEASE) {
-            emu_window->TouchReleased(layout, static_cast<u16>(x), static_cast<u16>(y));
-        }
+        if (action == GLFW_PRESS)
+            emu_window->TouchPressed(static_cast<unsigned>(x), static_cast<unsigned>(y));
+        else if (action == GLFW_RELEASE)
+            emu_window->TouchReleased();
     }
 }
 
 void EmuWindow_GLFW::OnCursorPosEvent(GLFWwindow* win, double x, double y) {
-    auto emu_window = GetEmuWindow(win);
-    auto layout = emu_window->GetFramebufferLayout();
-    emu_window->TouchMoved(layout, static_cast<u16>(x), static_cast<u16>(y));
+    GetEmuWindow(win)->TouchMoved(static_cast<unsigned>(x), static_cast<unsigned>(y));
 }
 
 /// Called by GLFW when a key event occurs
@@ -45,10 +42,8 @@ void EmuWindow_GLFW::OnKeyEvent(GLFWwindow* win, int key, int scancode, int acti
     if (action == GLFW_PRESS) {
         emu_window->KeyPressed({key, keyboard_id});
     } else if (action == GLFW_RELEASE) {
-        emu_window->KeyReleased({ key, keyboard_id });
+        emu_window->KeyReleased({key, keyboard_id});
     }
-
-    Service::HID::PadUpdateComplete();
 }
 
 /// Whether the window is still open, and a close request hasn't yet been sent
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index cf07e65cc..b81bd6167 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -268,39 +268,33 @@ QByteArray GRenderWindow::saveGeometry()
 
 void GRenderWindow::keyPressEvent(QKeyEvent* event)
 {
-    EmuWindow::KeyPressed({event->key(), keyboard_id});
-    Service::HID::PadUpdateComplete();
+    this->KeyPressed({event->key(), keyboard_id});
 }
 
 void GRenderWindow::keyReleaseEvent(QKeyEvent* event)
 {
-    EmuWindow::KeyReleased({event->key(), keyboard_id});
-    Service::HID::PadUpdateComplete();
+    this->KeyReleased({event->key(), keyboard_id});
 }
 
 void GRenderWindow::mousePressEvent(QMouseEvent *event)
 {
-    if (event->button() == Qt::LeftButton)  {
+    if (event->button() == Qt::LeftButton)
+    {
         auto pos = event->pos();
-        EmuWindow::TouchPressed(GetFramebufferLayout(), static_cast<u16>(pos.x()),
-            static_cast<u16>(pos.y()));
+        this->TouchPressed(static_cast<unsigned>(pos.x()), static_cast<unsigned>(pos.y()));
     }
 }
 
 void GRenderWindow::mouseMoveEvent(QMouseEvent *event)
 {
     auto pos = event->pos();
-    EmuWindow::TouchMoved(GetFramebufferLayout(), static_cast<u16>(pos.x()),
-        static_cast<u16>(pos.y()));
+    this->TouchMoved(static_cast<unsigned>(pos.x()), static_cast<unsigned>(pos.y()));
 }
 
 void GRenderWindow::mouseReleaseEvent(QMouseEvent *event)
 {
-    if (event->button() == Qt::LeftButton)  {
-        auto pos = event->pos();
-        EmuWindow::TouchReleased(GetFramebufferLayout(), static_cast<u16>(pos.x()),
-            static_cast<u16>(pos.y()));
-    }
+    if (event->button() == Qt::LeftButton)
+        this->TouchReleased();
 }
 
 void GRenderWindow::ReloadSetKeymaps()
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
index 89bb89481..6516fc633 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -6,15 +6,11 @@
 #include "video_core/video_core.h"
 
 void EmuWindow::KeyPressed(KeyMap::HostDeviceKey key) {
-    Service::HID::PadState mapped_key = KeyMap::GetPadKey(key);
-
-    Service::HID::PadButtonPress(mapped_key);
+    pad_state.hex |= KeyMap::GetPadKey(key).hex;
 }
 
 void EmuWindow::KeyReleased(KeyMap::HostDeviceKey key) {
-    Service::HID::PadState mapped_key = KeyMap::GetPadKey(key);
-
-    Service::HID::PadButtonRelease(mapped_key);
+    pad_state.hex &= ~KeyMap::GetPadKey(key).hex;
 }
 
 /**
@@ -25,55 +21,41 @@ void EmuWindow::KeyReleased(KeyMap::HostDeviceKey key) {
  * @return True if the coordinates are within the touchpad, otherwise false
  */
 static bool IsWithinTouchscreen(const EmuWindow::FramebufferLayout& layout, unsigned framebuffer_x,
-    unsigned framebuffer_y) {
-
-    return (framebuffer_y >= layout.bottom_screen.top &&
-        framebuffer_y < layout.bottom_screen.bottom &&
-        framebuffer_x >= layout.bottom_screen.left &&
-        framebuffer_x < layout.bottom_screen.right);
+                                unsigned framebuffer_y) {
+    return (framebuffer_y >= layout.bottom_screen.top    &&
+            framebuffer_y <  layout.bottom_screen.bottom &&
+            framebuffer_x >= layout.bottom_screen.left   &&
+            framebuffer_x <  layout.bottom_screen.right);
 }
 
-void EmuWindow::TouchPressed(const FramebufferLayout& layout, unsigned framebuffer_x,
-    unsigned framebuffer_y) {
+void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
+    if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y))
+        return;
 
-    if (IsWithinTouchscreen(layout, framebuffer_x, framebuffer_y)) {
-        u16 touch_x = VideoCore::kScreenBottomWidth * (framebuffer_x - layout.bottom_screen.left) /
-            (layout.bottom_screen.right - layout.bottom_screen.left);
-        u16 touch_y = VideoCore::kScreenBottomHeight * (framebuffer_y - layout.bottom_screen.top) /
-            (layout.bottom_screen.bottom - layout.bottom_screen.top);
+    touch_x = VideoCore::kScreenBottomWidth * (framebuffer_x - framebuffer_layout.bottom_screen.left) /
+        (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left);
+    touch_y = VideoCore::kScreenBottomHeight * (framebuffer_y - framebuffer_layout.bottom_screen.top) /
+        (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top);
 
-        Service::HID::TouchPress(touch_x, touch_y);
-        Service::HID::TouchUpdateComplete();
-
-        touch_pressed = true;
-    }
+    touch_pressed = true;
+    pad_state.touch = 1;
 }
 
-void EmuWindow::TouchReleased(const FramebufferLayout& layout, unsigned framebuffer_x,
-    unsigned framebuffer_y) {
-
-    if (IsWithinTouchscreen(layout, framebuffer_x, framebuffer_y)) {
-
-        Service::HID::TouchRelease();
-        Service::HID::TouchUpdateComplete();
-
-        touch_pressed = false;
-    }
+void EmuWindow::TouchReleased() {
+    touch_pressed = false;
+    touch_x = 0;
+    touch_y = 0;
+    pad_state.touch = 0;
 }
 
-void EmuWindow::TouchMoved(const FramebufferLayout& layout, unsigned framebuffer_x,
-    unsigned framebuffer_y) {
+void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) {
+    if (!touch_pressed)
+        return;
 
-    if (touch_pressed) {
-        if (IsWithinTouchscreen(layout, framebuffer_x, framebuffer_y)) {
-            EmuWindow::TouchPressed(layout, framebuffer_x, framebuffer_y);
-        } else {
-            Service::HID::TouchRelease();
-            Service::HID::TouchUpdateComplete();
-
-            touch_pressed = false;
-        }
-    }
+    if (IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y))
+        TouchPressed(framebuffer_x, framebuffer_y);
+    else
+        TouchReleased();
 }
 
 EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width,
diff --git a/src/common/emu_window.h b/src/common/emu_window.h
index 8e4b510e9..2be7517bc 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -78,27 +78,41 @@ public:
 
     /**
      * Signal that a touch pressed event has occurred (e.g. mouse click pressed)
-     * @param layout FramebufferLayout object describing the framebuffer size and screen positions
      * @param framebuffer_x Framebuffer x-coordinate that was pressed
      * @param framebuffer_y Framebuffer y-coordinate that was pressed
      */
-    void TouchPressed(const FramebufferLayout& layout, unsigned framebuffer_x, unsigned framebuffer_y);
+    void TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y);
 
-    /**
-     * Signal that a touch released event has occurred (e.g. mouse click released)
-     * @param layout FramebufferLayout object describing the framebuffer size and screen positions
-     * @param framebuffer_x Framebuffer x-coordinate that was released
-     * @param framebuffer_y Framebuffer y-coordinate that was released
-     */
-    void TouchReleased(const FramebufferLayout& layout, unsigned framebuffer_x, unsigned framebuffer_y);
+    /// Signal that a touch released event has occurred (e.g. mouse click released)
+    void TouchReleased();
 
     /**
      * Signal that a touch movement event has occurred (e.g. mouse was moved over the emu window)
-     * @param layout FramebufferLayout object describing the framebuffer size and screen positions
      * @param framebuffer_x Framebuffer x-coordinate
      * @param framebuffer_y Framebuffer y-coordinate
      */
-    void TouchMoved(const FramebufferLayout& layout, unsigned framebuffer_x, unsigned framebuffer_y);
+    void TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y);
+
+    /**
+     * Gets the current pad state (which buttons are pressed and the circle pad direction).
+     * @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 PadState object indicating the current pad state
+     */
+    const Service::HID::PadState GetPadState() const {
+        return pad_state;
+    }
+
+    /**
+     * 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
+     */
+    const std::tuple<u16, u16, bool>& GetTouchState() const {
+        return std::make_tuple(touch_x, touch_y, touch_pressed);
+    }
 
     /**
      * Returns currently active configuration.
@@ -124,21 +138,15 @@ public:
         return framebuffer_layout;
     }
 
-    /**
-     * Gets window client area width in logical coordinates.
-     * @note For high-DPI systems, this is smaller than the framebuffer size.
-     * @note This method is thread-safe
-     */
-    std::pair<unsigned,unsigned> GetClientAreaSize() const {
-        return std::make_pair(client_area_width, client_area_height);
-    }
-
 protected:
-    EmuWindow()
-    {
+    EmuWindow() {
         // TODO: Find a better place to set this.
         config.min_client_area_size = std::make_pair(400u, 480u);
         active_config = config;
+        pad_state.hex = 0;
+        touch_x = 0;
+        touch_y = 0;
+        touch_pressed = false;
     }
     virtual ~EmuWindow() {}
 
@@ -194,4 +202,9 @@ private:
     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)
+
+    Service::HID::PadState pad_state;
 };
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 703a765b5..baff92716 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -12,6 +12,8 @@
 #include "core/hle/kernel/shared_memory.h"
 #include "core/hle/hle.h"
 
+#include "video_core/video_core.h"
+
 namespace Service {
 namespace HID {
 
@@ -23,15 +25,8 @@ Kernel::SharedPtr<Kernel::Event> g_event_accelerometer;
 Kernel::SharedPtr<Kernel::Event> g_event_gyroscope;
 Kernel::SharedPtr<Kernel::Event> g_event_debug_pad;
 
-// Next Pad state update information
-static PadState next_state = {{0}};
 static u32 next_pad_index = 0;
-static s16 next_pad_circle_x = 0;
-static s16 next_pad_circle_y = 0;
-
 static u32 next_touch_index = 0;
-static u16 next_touch_x = 0;
-static u16 next_touch_y = 0;
 
 /**
  * Gets a pointer to the PadData structure inside HID shared memory
@@ -55,38 +50,15 @@ static inline SharedMem* GetSharedMem() {
 //     * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41
 //     * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
 
-/**
- * Circle Pad from keys.
- *
- * This is implemented as "pushed all the way to an edge (max) or centered (0)".
- *
- * Indicate the circle pad is pushed completely to the edge in 1 of 8 directions.
- */
-static void UpdateNextCirclePadState() {
-    static const s16 max_value = 0x9C;
-    next_pad_circle_x = next_state.circle_left ? -max_value : 0x0;
-    next_pad_circle_x += next_state.circle_right ? max_value : 0x0;
-    next_pad_circle_y = next_state.circle_down ? -max_value : 0x0;
-    next_pad_circle_y += next_state.circle_up ? max_value : 0x0;
-}
-
-void PadButtonPress(const PadState& pad_state) {
-    next_state.hex |= pad_state.hex;
-    UpdateNextCirclePadState();
-}
-
-void PadButtonRelease(const PadState& pad_state) {
-    next_state.hex &= ~pad_state.hex;
-    UpdateNextCirclePadState();
-}
-
-void PadUpdateComplete() {
+void HIDUpdate() {
     SharedMem* shared_mem = GetSharedMem();
 
     if (shared_mem == nullptr)
         return;
 
-    shared_mem->pad.current_state.hex = next_state.hex;
+    const PadState& state = VideoCore::g_emu_window->GetPadState();
+
+    shared_mem->pad.current_state.hex = state.hex;
     shared_mem->pad.index = next_pad_index;
     ++next_touch_index %= shared_mem->pad.entries.size();
 
@@ -95,28 +67,19 @@ void PadUpdateComplete() {
     PadState old_state = shared_mem->pad.entries[last_entry_index].current_state;
 
     // Compute bitmask with 1s for bits different from the old state
-    PadState changed;
-    changed.hex = (next_state.hex ^ old_state.hex);
-
-    // Compute what was added
-    PadState additions;
-    additions.hex = changed.hex & next_state.hex;
-
-    // Compute what was removed
-    PadState removals;
-    removals.hex = changed.hex & old_state.hex;
+    PadState changed = { { (state.hex ^ old_state.hex) } };
 
     // Get the current Pad entry
-    PadDataEntry* current_pad_entry = &shared_mem->pad.entries[shared_mem->pad.index];
+    PadDataEntry* pad_entry = &shared_mem->pad.entries[shared_mem->pad.index];
 
     // Update entry properties
-    current_pad_entry->current_state.hex = next_state.hex;
-    current_pad_entry->delta_additions.hex = additions.hex;
-    current_pad_entry->delta_removals.hex = removals.hex;
+    pad_entry->current_state.hex = state.hex;
+    pad_entry->delta_additions.hex = changed.hex & state.hex;
+    pad_entry->delta_removals.hex = changed.hex & old_state.hex;;
 
     // Set circle Pad
-    current_pad_entry->circle_pad_x = next_pad_circle_x;
-    current_pad_entry->circle_pad_y = next_pad_circle_y;
+    pad_entry->circle_pad_x = state.circle_left ? -0x9C : state.circle_right ? 0x9C : 0x0;
+    pad_entry->circle_pad_y = state.circle_down ? -0x9C : state.circle_up ? 0x9C : 0x0;
 
     // If we just updated index 0, provide a new timestamp
     if (shared_mem->pad.index == 0) {
@@ -124,39 +87,15 @@ void PadUpdateComplete() {
         shared_mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks();
     }
 
-    // Signal both handles when there's an update to Pad or touch
-    g_event_pad_or_touch_1->Signal();
-    g_event_pad_or_touch_2->Signal();
-}
-
-void TouchPress(u16 x, u16 y) {
-    next_touch_x = x;
-    next_touch_y = y;
-}
-
-void TouchRelease() {
-    next_touch_x = 0;
-    next_touch_y = 0;
-}
-
-void TouchUpdateComplete() {
-    SharedMem* shared_mem = GetSharedMem();
-
-    if (shared_mem == nullptr)
-        return;
-
     shared_mem->touch.index = next_touch_index;
     ++next_touch_index %= shared_mem->touch.entries.size();
 
     // Get the current touch entry
-    TouchDataEntry* current_touch_entry = &shared_mem->touch.entries[shared_mem->touch.index];
+    TouchDataEntry* touch_entry = &shared_mem->touch.entries[shared_mem->touch.index];
+    bool pressed = false;
 
-    // Set touchpad position
-    current_touch_entry->x = next_touch_x;
-    current_touch_entry->y = next_touch_y;
-
-    // TODO(bunnei): Verify this behavior on real hardware
-    current_touch_entry->valid = (next_touch_x || next_touch_y) ? 1 : 0;
+    std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState();
+    touch_entry->valid = pressed ? 1 : 0;
 
     // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
     // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
@@ -194,6 +133,9 @@ void HIDInit() {
 
     g_shared_mem = SharedMemory::Create("HID:SharedMem");
 
+    next_pad_index = 0;
+    next_touch_index = 0;
+
     // Create event handles
     g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1");
     g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2");
@@ -203,8 +145,8 @@ void HIDInit() {
 }
 
 void HIDShutdown() {
-
 }
 
-}
-}
+} // namespace HID
+
+} // namespace Service
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 7fdf5828a..063f06858 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -176,38 +176,13 @@ const PadState PAD_CIRCLE_DOWN  = {{1u << 31}};
  */
 void GetIPCHandles(Interface* self);
 
-/**
- * Sets a Pad state (button or button combo) as pressed
- * @param pad_state PadState data indicating which buttons have been pressed
- */
-void PadButtonPress(const PadState& pad_state);
-
-/**
- * Sets a Pad state (button or button combo) as released
- * @param pad_state PadState data indicating which buttons have been released
- */
-void PadButtonRelease(const PadState& pad_state);
-
-/**
- * Called after all Pad changes to be included in this update have been made, including both Pad
- * key changes and analog circle Pad changes.
- */
-void PadUpdateComplete();
-
-/**
- * Signal that the touchpad has been pressed
- * @param x Touchpad x-coordinate in bottom screen pixels (between 0 and 320)
- * @param y Touchpad y-coordinate in bottom screen pixels (between 0 and 240)
- */
-void TouchPress(u16 x, u16 y);
-
-/// Signal that touchpad has been released
-void TouchRelease();
-
-/// Signal that touchpad updates have been completed
-void TouchUpdateComplete();
+/// Checks for user input updates
+void HIDUpdate();
 
+/// Initialize HID service
 void HIDInit();
+
+/// Shutdown HID service
 void HIDShutdown();
 
 }
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index b7102b874..f7b822c58 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -14,6 +14,7 @@
 #include "core/hle/hle.h"
 #include "core/hle/service/gsp_gpu.h"
 #include "core/hle/service/dsp_dsp.h"
+#include "core/hle/service/hid/hid.h"
 
 #include "core/hw/gpu.h"
 
@@ -294,6 +295,9 @@ static void VBlankCallback(u64 userdata, int cycles_late) {
     // this. Certain games expect this to be periodically signaled.
     DSP_DSP::SignalInterrupt();
 
+    // Check for user input updates
+    Service::HID::HIDUpdate();
+
     // Reschedule recurrent event
     CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event);
 }

From 85cbccb1d3110c934ccf0edddf86a03fa692f27b Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Mon, 9 Mar 2015 23:03:24 -0400
Subject: [PATCH 12/14] HID: Added additional variable comments and some code
 cleanups.

---
 src/core/hle/service/hid/hid.cpp |  8 +++++--
 src/core/hle/service/hid/hid.h   | 41 ++++++++++++++++++--------------
 2 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index baff92716..6aa8bfd1f 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -17,6 +17,8 @@
 namespace Service {
 namespace HID {
 
+static const int MAX_CIRCLEPAD_POS = 0x9C; ///< Max value for a circle pad position
+
 Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem = nullptr;
 
 Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_1;
@@ -78,8 +80,10 @@ void HIDUpdate() {
     pad_entry->delta_removals.hex = changed.hex & old_state.hex;;
 
     // Set circle Pad
-    pad_entry->circle_pad_x = state.circle_left ? -0x9C : state.circle_right ? 0x9C : 0x0;
-    pad_entry->circle_pad_y = state.circle_down ? -0x9C : state.circle_up ? 0x9C : 0x0;
+    pad_entry->circle_pad_x = state.circle_left  ? -MAX_CIRCLEPAD_POS :
+                              state.circle_right ?  MAX_CIRCLEPAD_POS : 0x0;
+    pad_entry->circle_pad_y = state.circle_down  ? -MAX_CIRCLEPAD_POS :
+                              state.circle_up    ?  MAX_CIRCLEPAD_POS : 0x0;
 
     // If we just updated index 0, provide a new timestamp
     if (shared_mem->pad.index == 0) {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 063f06858..03971d3c7 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -80,40 +80,45 @@ struct PadDataEntry {
  * Structure of a single entry of touch state history within HID shared memory
  */
 struct TouchDataEntry {
-    u16 x;                   ///< Y-coordinate of a touchpad press on the lower screen
-    u16 y;                   ///< X-coordinate of a touchpad press on the lower screen
-    BitField<0,7,u32> valid; ///< Set to 1 when this entry contains actual X/Y data, otherwise 0
+    u16 x;                     ///< Y-coordinate of a touchpad press on the lower screen
+    u16 y;                     ///< X-coordinate of a touchpad press on the lower screen
+    BitField<0, 7, u32> valid; ///< Set to 1 when this entry contains actual X/Y data, otherwise 0
 };
 
 /**
  * Structure of data stored in HID shared memory
  */
 struct SharedMem {
-    // "Pad data, this is used for buttons and the circle pad
+    /// Pad data, this is used for buttons and the circle pad
     struct {
-        s64 index_reset_ticks;
-        s64 index_reset_ticks_previous;
-        u32 index; // Index of the last updated pad state history element
+        s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
+        s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
+        u32 index; ///< Index of the last updated pad state entry
 
-        INSERT_PADDING_BYTES(0x8);
+        INSERT_PADDING_WORDS(0x2);
 
-        PadState current_state; // Same as entries[index].current_state
-        u32 raw_circle_pad_data;
+        PadState current_state; ///< Current state of the pad buttons
 
-        INSERT_PADDING_BYTES(0x4);
+        // TODO(bunnei): Implement `raw_circle_pad_data` field
+        u32 raw_circle_pad_data; ///< Raw (analog) circle pad data, before being converted
 
-        std::array<PadDataEntry, 8> entries; // Pad state history
+        INSERT_PADDING_WORDS(0x1);
+
+        std::array<PadDataEntry, 8> entries; ///< Last 8 pad entries
     } pad;
 
-    // Touchpad data, this is used for touchpad input
+    /// Touchpad data, this is used for touchpad input
     struct {
-        s64 index_reset_ticks;
-        s64 index_reset_ticks_previous;
-        u32 index; // Index of the last updated touch state history element
+        s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
+        s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
+        u32 index; ///< Index of the last updated touch entry
 
-        INSERT_PADDING_BYTES(0xC);
+        INSERT_PADDING_WORDS(0x1);
 
-        std::array<TouchDataEntry, 8> entries;
+        // TODO(bunnei): Implement `raw_entry` field
+        TouchDataEntry raw_entry; ///< Raw (analog) touch data, before being converted
+
+        std::array<TouchDataEntry, 8> entries; ///< Last 8 touch entries, in pixel coordinates
     } touch;
 };
 

From e79c27f1e04031e08a14db9517fe6b06647c65b1 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Mon, 9 Mar 2015 23:38:52 -0400
Subject: [PATCH 13/14] HID: Removed unnecessary global variables.

---
 src/core/hle/service/hid/hid.cpp | 90 +++++++++++++++-----------------
 src/core/hle/service/hid/hid.h   | 10 ----
 2 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 6aa8bfd1f..e7f9bec7e 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -19,26 +19,19 @@ namespace HID {
 
 static const int MAX_CIRCLEPAD_POS = 0x9C; ///< Max value for a circle pad position
 
-Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem = nullptr;
+// Handle to shared memory region designated to HID_User service
+static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem = nullptr;
 
-Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_1;
-Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_2;
-Kernel::SharedPtr<Kernel::Event> g_event_accelerometer;
-Kernel::SharedPtr<Kernel::Event> g_event_gyroscope;
-Kernel::SharedPtr<Kernel::Event> g_event_debug_pad;
+// Event handles
+static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1 = nullptr;
+static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2 = nullptr;
+static Kernel::SharedPtr<Kernel::Event> event_accelerometer = nullptr;
+static Kernel::SharedPtr<Kernel::Event> event_gyroscope = nullptr;
+static Kernel::SharedPtr<Kernel::Event> event_debug_pad = nullptr;
 
 static u32 next_pad_index = 0;
 static u32 next_touch_index = 0;
 
-/**
- * Gets a pointer to the PadData structure inside HID shared memory
- */
-static inline SharedMem* GetSharedMem() {
-    if (g_shared_mem == nullptr)
-        return nullptr;
-    return reinterpret_cast<SharedMem*>(g_shared_mem->GetPointer().ValueOr(nullptr));
-}
-
 // TODO(peachum):
 // Add a method for setting analog input from joystick device for the circle Pad.
 //
@@ -53,26 +46,27 @@ static inline SharedMem* GetSharedMem() {
 //     * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
 
 void HIDUpdate() {
-    SharedMem* shared_mem = GetSharedMem();
+    SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer().ValueOr(nullptr));
+    const PadState state = VideoCore::g_emu_window->GetPadState();
 
-    if (shared_mem == nullptr)
+    if (mem == nullptr) {
+        LOG_DEBUG(Service_HID, "Cannot update HID prior to mapping shared memory!");
         return;
+    }
 
-    const PadState& state = VideoCore::g_emu_window->GetPadState();
-
-    shared_mem->pad.current_state.hex = state.hex;
-    shared_mem->pad.index = next_pad_index;
-    ++next_touch_index %= shared_mem->pad.entries.size();
+    mem->pad.current_state.hex = state.hex;
+    mem->pad.index = next_pad_index;
+    ++next_touch_index %= mem->pad.entries.size();
 
     // Get the previous Pad state
-    u32 last_entry_index = (shared_mem->pad.index - 1) % shared_mem->pad.entries.size();
-    PadState old_state = shared_mem->pad.entries[last_entry_index].current_state;
+    u32 last_entry_index = (mem->pad.index - 1) % mem->pad.entries.size();
+    PadState old_state = mem->pad.entries[last_entry_index].current_state;
 
     // Compute bitmask with 1s for bits different from the old state
     PadState changed = { { (state.hex ^ old_state.hex) } };
 
     // Get the current Pad entry
-    PadDataEntry* pad_entry = &shared_mem->pad.entries[shared_mem->pad.index];
+    PadDataEntry* pad_entry = &mem->pad.entries[mem->pad.index];
 
     // Update entry properties
     pad_entry->current_state.hex = state.hex;
@@ -86,16 +80,16 @@ void HIDUpdate() {
                               state.circle_up    ?  MAX_CIRCLEPAD_POS : 0x0;
 
     // If we just updated index 0, provide a new timestamp
-    if (shared_mem->pad.index == 0) {
-        shared_mem->pad.index_reset_ticks_previous = shared_mem->pad.index_reset_ticks;
-        shared_mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks();
+    if (mem->pad.index == 0) {
+        mem->pad.index_reset_ticks_previous = mem->pad.index_reset_ticks;
+        mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks();
     }
 
-    shared_mem->touch.index = next_touch_index;
-    ++next_touch_index %= shared_mem->touch.entries.size();
+    mem->touch.index = next_touch_index;
+    ++next_touch_index %= mem->touch.entries.size();
 
     // Get the current touch entry
-    TouchDataEntry* touch_entry = &shared_mem->touch.entries[shared_mem->touch.index];
+    TouchDataEntry* touch_entry = &mem->touch.entries[mem->touch.index];
     bool pressed = false;
 
     std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState();
@@ -106,14 +100,14 @@ void HIDUpdate() {
     // converted to pixel coordinates." (http://3dbrew.org/wiki/HID_Shared_Memory#Offset_0xA8).
 
     // If we just updated index 0, provide a new timestamp
-    if (shared_mem->touch.index == 0) {
-        shared_mem->touch.index_reset_ticks_previous = shared_mem->touch.index_reset_ticks;
-        shared_mem->touch.index_reset_ticks = (s64)Core::g_app_core->GetTicks();
+    if (mem->touch.index == 0) {
+        mem->touch.index_reset_ticks_previous = mem->touch.index_reset_ticks;
+        mem->touch.index_reset_ticks = (s64)Core::g_app_core->GetTicks();
     }
     
     // Signal both handles when there's an update to Pad or touch
-    g_event_pad_or_touch_1->Signal();
-    g_event_pad_or_touch_2->Signal();
+    event_pad_or_touch_1->Signal();
+    event_pad_or_touch_2->Signal();
 }
 
 void GetIPCHandles(Service::Interface* self) {
@@ -121,12 +115,12 @@ void GetIPCHandles(Service::Interface* self) {
 
     cmd_buff[1] = 0; // No error
     // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling)
-    cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::g_shared_mem).MoveFrom();
-    cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_1).MoveFrom();
-    cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_2).MoveFrom();
-    cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::g_event_accelerometer).MoveFrom();
-    cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::g_event_gyroscope).MoveFrom();
-    cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::g_event_debug_pad).MoveFrom();
+    cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).MoveFrom();
+    cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_1).MoveFrom();
+    cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_2).MoveFrom();
+    cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::event_accelerometer).MoveFrom();
+    cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::event_gyroscope).MoveFrom();
+    cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::event_debug_pad).MoveFrom();
 }
 
 void HIDInit() {
@@ -135,17 +129,17 @@ void HIDInit() {
     AddService(new HID_U_Interface);
     AddService(new HID_SPVR_Interface);
 
-    g_shared_mem = SharedMemory::Create("HID:SharedMem");
+    shared_mem = SharedMemory::Create("HID:SharedMem");
 
     next_pad_index = 0;
     next_touch_index = 0;
 
     // Create event handles
-    g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1");
-    g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2");
-    g_event_accelerometer  = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer");
-    g_event_gyroscope      = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope");
-    g_event_debug_pad      = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad");
+    event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1");
+    event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2");
+    event_accelerometer  = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer");
+    event_gyroscope      = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope");
+    event_debug_pad      = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad");
 }
 
 void HIDShutdown() {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 03971d3c7..0946cf660 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -18,16 +18,6 @@ namespace Kernel {
 namespace Service {
 namespace HID {
 
-// Handle to shared memory region designated to HID_User service
-extern Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem;
-
-// Event handles
-extern Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_1;
-extern Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_2;
-extern Kernel::SharedPtr<Kernel::Event> g_event_accelerometer;
-extern Kernel::SharedPtr<Kernel::Event> g_event_gyroscope;
-extern Kernel::SharedPtr<Kernel::Event> g_event_debug_pad;
-
 /**
  * Structure of a Pad controller state.
  */

From 4bbddda377625332635aa2a2687816435eb574a2 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Mon, 9 Mar 2015 23:47:57 -0400
Subject: [PATCH 14/14] hid_user: Removed unnecessary includes.

---
 src/core/hle/service/hid/hid_user.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp
index 1d0accefe..c2d5758fb 100644
--- a/src/core/hle/service/hid/hid_user.cpp
+++ b/src/core/hle/service/hid/hid_user.cpp
@@ -3,8 +3,6 @@
 // Refer to the license.txt file included.
 
 #include "core/hle/hle.h"
-#include "core/hle/kernel/event.h"
-#include "core/hle/kernel/shared_memory.h"
 #include "core/hle/service/hid/hid.h"
 #include "core/hle/service/hid/hid_user.h"