summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/citra/emu_window/emu_window_glfw.cpp65
-rw-r--r--src/citra/emu_window/emu_window_glfw.h5
-rw-r--r--src/citra_qt/bootmanager.cpp49
-rw-r--r--src/citra_qt/bootmanager.hxx2
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/emu_window.cpp17
-rw-r--r--src/common/emu_window.h19
-rw-r--r--src/common/key_map.cpp18
-rw-r--r--src/common/key_map.h46
-rw-r--r--src/core/hle/service/hid.cpp160
-rw-r--r--src/core/hle/service/hid.h80
-rw-r--r--src/video_core/video_core.h1
12 files changed, 259 insertions, 204 deletions
diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
index 0a861cff0..b911e60c5 100644
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ b/src/citra/emu_window/emu_window_glfw.cpp
@@ -8,49 +8,53 @@
8 8
9#include "citra/emu_window/emu_window_glfw.h" 9#include "citra/emu_window/emu_window_glfw.h"
10 10
11static const KeyMap::DefaultKeyMapping default_key_map[] = { 11static const std::pair<int, HID_User::PadState> default_key_map[] = {
12 { KeyMap::CitraKey(GLFW_KEY_A), HID_User::PAD_A }, 12 { GLFW_KEY_A, HID_User::PAD_A },
13 { KeyMap::CitraKey(GLFW_KEY_B), HID_User::PAD_B }, 13 { GLFW_KEY_B, HID_User::PAD_B },
14 { KeyMap::CitraKey(GLFW_KEY_BACKSLASH), HID_User::PAD_SELECT }, 14 { GLFW_KEY_BACKSLASH, HID_User::PAD_SELECT },
15 { KeyMap::CitraKey(GLFW_KEY_ENTER), HID_User::PAD_START }, 15 { GLFW_KEY_ENTER, HID_User::PAD_START },
16 { KeyMap::CitraKey(GLFW_KEY_RIGHT), HID_User::PAD_RIGHT }, 16 { GLFW_KEY_RIGHT, HID_User::PAD_RIGHT },
17 { KeyMap::CitraKey(GLFW_KEY_LEFT), HID_User::PAD_LEFT }, 17 { GLFW_KEY_LEFT, HID_User::PAD_LEFT },
18 { KeyMap::CitraKey(GLFW_KEY_UP), HID_User::PAD_UP }, 18 { GLFW_KEY_UP, HID_User::PAD_UP },
19 { KeyMap::CitraKey(GLFW_KEY_DOWN), HID_User::PAD_DOWN }, 19 { GLFW_KEY_DOWN, HID_User::PAD_DOWN },
20 { KeyMap::CitraKey(GLFW_KEY_R), HID_User::PAD_R }, 20 { GLFW_KEY_R, HID_User::PAD_R },
21 { KeyMap::CitraKey(GLFW_KEY_L), HID_User::PAD_L }, 21 { GLFW_KEY_L, HID_User::PAD_L },
22 { KeyMap::CitraKey(GLFW_KEY_X), HID_User::PAD_X }, 22 { GLFW_KEY_X, HID_User::PAD_X },
23 { KeyMap::CitraKey(GLFW_KEY_Y), HID_User::PAD_Y }, 23 { GLFW_KEY_Y, HID_User::PAD_Y },
24 { KeyMap::CitraKey(GLFW_KEY_H), HID_User::PAD_CIRCLE_RIGHT }, 24 { GLFW_KEY_H, HID_User::PAD_CIRCLE_RIGHT },
25 { KeyMap::CitraKey(GLFW_KEY_F), HID_User::PAD_CIRCLE_LEFT }, 25 { GLFW_KEY_F, HID_User::PAD_CIRCLE_LEFT },
26 { KeyMap::CitraKey(GLFW_KEY_T), HID_User::PAD_CIRCLE_UP }, 26 { GLFW_KEY_T, HID_User::PAD_CIRCLE_UP },
27 { KeyMap::CitraKey(GLFW_KEY_G), HID_User::PAD_CIRCLE_DOWN }, 27 { GLFW_KEY_G, HID_User::PAD_CIRCLE_DOWN },
28}; 28};
29 29
30/// Called by GLFW when a key event occurs
31void EmuWindow_GLFW::OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods) {
32
33 if (!VideoCore::g_emu_window) {
34 return;
35 }
36
37 int keyboard_id = ((EmuWindow_GLFW*)VideoCore::g_emu_window)->keyboard_id;
30 38
31static void OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods) {
32 if (action == GLFW_PRESS) { 39 if (action == GLFW_PRESS) {
33 EmuWindow::KeyPressed(KeyMap::CitraKey(key)); 40 EmuWindow::KeyPressed({key, keyboard_id});
34 } 41 }
35 42
36 if (action == GLFW_RELEASE) { 43 if (action == GLFW_RELEASE) {
37 EmuWindow::KeyReleased(KeyMap::CitraKey(key)); 44 EmuWindow::KeyReleased({key, keyboard_id});
38 } 45 }
39 HID_User::PADUpdateComplete(); 46 HID_User::PadUpdateComplete();
40}
41
42static void OnWindowSizeEvent(GLFWwindow* win, int width, int height) {
43 EmuWindow_GLFW* emu_window = (EmuWindow_GLFW*)glfwGetWindowUserPointer(win);
44 emu_window->SetClientAreaWidth(width);
45 emu_window->SetClientAreaHeight(height);
46} 47}
47 48
48/// EmuWindow_GLFW constructor 49/// EmuWindow_GLFW constructor
49EmuWindow_GLFW::EmuWindow_GLFW() { 50EmuWindow_GLFW::EmuWindow_GLFW() {
50 51
51 // Set default key mappings 52 // Register a new ID for the default keyboard
52 for (int i = 0; i < ARRAY_SIZE(default_key_map); i++) { 53 keyboard_id = KeyMap::NewDeviceId();
53 KeyMap::SetKeyMapping(default_key_map[i].key, default_key_map[i].state); 54
55 // Set default key mappings for keyboard
56 for (auto mapping : default_key_map) {
57 KeyMap::SetKeyMapping({mapping.first, keyboard_id}, mapping.second);
54 } 58 }
55 59
56 // Initialize the window 60 // Initialize the window
@@ -79,7 +83,6 @@ EmuWindow_GLFW::EmuWindow_GLFW() {
79 // Setup callbacks 83 // Setup callbacks
80 glfwSetWindowUserPointer(m_render_window, this); 84 glfwSetWindowUserPointer(m_render_window, this);
81 glfwSetKeyCallback(m_render_window, OnKeyEvent); 85 glfwSetKeyCallback(m_render_window, OnKeyEvent);
82 //glfwSetWindowSizeCallback(m_render_window, OnWindowSizeEvent);
83 86
84 DoneCurrent(); 87 DoneCurrent();
85} 88}
diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h
index c1b41203b..29325bb75 100644
--- a/src/citra/emu_window/emu_window_glfw.h
+++ b/src/citra/emu_window/emu_window_glfw.h
@@ -25,8 +25,9 @@ public:
25 /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread 25 /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread
26 void DoneCurrent(); 26 void DoneCurrent();
27 27
28 GLFWwindow* m_render_window; ///< Internal GLFW render window 28 static void OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods);
29 29
30private: 30private:
31 31 GLFWwindow* m_render_window; ///< Internal GLFW render window
32 int keyboard_id; ///< Device id of keyboard for use with KeyMap
32}; 33};
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 573060d30..657e39bea 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -109,8 +109,35 @@ EmuThread& GRenderWindow::GetEmuThread()
109 return emu_thread; 109 return emu_thread;
110} 110}
111 111
112static const std::pair<int, HID_User::PadState> default_key_map[] = {
113 { Qt::Key_A, HID_User::PAD_A },
114 { Qt::Key_B, HID_User::PAD_B },
115 { Qt::Key_Backslash, HID_User::PAD_SELECT },
116 { Qt::Key_Enter, HID_User::PAD_START },
117 { Qt::Key_Right, HID_User::PAD_RIGHT },
118 { Qt::Key_Left, HID_User::PAD_LEFT },
119 { Qt::Key_Up, HID_User::PAD_UP },
120 { Qt::Key_Down, HID_User::PAD_DOWN },
121 { Qt::Key_R, HID_User::PAD_R },
122 { Qt::Key_L, HID_User::PAD_L },
123 { Qt::Key_X, HID_User::PAD_X },
124 { Qt::Key_Y, HID_User::PAD_Y },
125 { Qt::Key_H, HID_User::PAD_CIRCLE_RIGHT },
126 { Qt::Key_F, HID_User::PAD_CIRCLE_LEFT },
127 { Qt::Key_T, HID_User::PAD_CIRCLE_UP },
128 { Qt::Key_G, HID_User::PAD_CIRCLE_DOWN },
129};
130
112GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this) 131GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this)
113{ 132{
133 // Register a new ID for the default keyboard
134 keyboard_id = KeyMap::NewDeviceId();
135
136 // Set default key mappings for keyboard
137 for (auto mapping : default_key_map) {
138 KeyMap::SetKeyMapping({mapping.first, keyboard_id}, mapping.second);
139 }
140
114 // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, WA_DontShowOnScreen, WA_DeleteOnClose 141 // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, WA_DontShowOnScreen, WA_DeleteOnClose
115 QGLFormat fmt; 142 QGLFormat fmt;
116 fmt.setProfile(QGLFormat::CoreProfile); 143 fmt.setProfile(QGLFormat::CoreProfile);
@@ -209,27 +236,13 @@ QByteArray GRenderWindow::saveGeometry()
209 236
210void GRenderWindow::keyPressEvent(QKeyEvent* event) 237void GRenderWindow::keyPressEvent(QKeyEvent* event)
211{ 238{
212 /* 239 EmuWindow::KeyPressed({event->key(), keyboard_id});
213 bool key_processed = false; 240 HID_User::PadUpdateComplete();
214 for (unsigned int channel = 0; channel < 4 && controller_interface(); ++channel)
215 if (controller_interface()->SetControllerStatus(channel, event->key(), input_common::GCController::PRESSED))
216 key_processed = true;
217
218 if (!key_processed)
219 QWidget::keyPressEvent(event);
220 */
221} 241}
222 242
223void GRenderWindow::keyReleaseEvent(QKeyEvent* event) 243void GRenderWindow::keyReleaseEvent(QKeyEvent* event)
224{ 244{
225 /* 245 EmuWindow::KeyReleased({event->key(), keyboard_id});
226 bool key_processed = false; 246 HID_User::PadUpdateComplete();
227 for (unsigned int channel = 0; channel < 4 && controller_interface(); ++channel)
228 if (controller_interface()->SetControllerStatus(channel, event->key(), input_common::GCController::RELEASED))
229 key_processed = true;
230
231 if (!key_processed)
232 QWidget::keyPressEvent(event);
233 */
234} 247}
235 248
diff --git a/src/citra_qt/bootmanager.hxx b/src/citra_qt/bootmanager.hxx
index 51cb781e9..eedf19471 100644
--- a/src/citra_qt/bootmanager.hxx
+++ b/src/citra_qt/bootmanager.hxx
@@ -116,4 +116,6 @@ private:
116 EmuThread emu_thread; 116 EmuThread emu_thread;
117 117
118 QByteArray geometry; 118 QByteArray geometry;
119
120 int keyboard_id;
119}; 121};
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 4ae34bea9..9d5a90762 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -4,6 +4,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOU
4set(SRCS 4set(SRCS
5 break_points.cpp 5 break_points.cpp
6 console_listener.cpp 6 console_listener.cpp
7 emu_window.cpp
7 extended_trace.cpp 8 extended_trace.cpp
8 file_search.cpp 9 file_search.cpp
9 file_util.cpp 10 file_util.cpp
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
new file mode 100644
index 000000000..7a2c50ac8
--- /dev/null
+++ b/src/common/emu_window.cpp
@@ -0,0 +1,17 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "emu_window.h"
6
7void EmuWindow::KeyPressed(KeyMap::HostDeviceKey key) {
8 HID_User::PadState mapped_key = KeyMap::GetPadKey(key);
9
10 HID_User::PadButtonPress(mapped_key);
11}
12
13void EmuWindow::KeyReleased(KeyMap::HostDeviceKey key) {
14 HID_User::PadState mapped_key = KeyMap::GetPadKey(key);
15
16 HID_User::PadButtonRelease(mapped_key);
17}
diff --git a/src/common/emu_window.h b/src/common/emu_window.h
index 90fbd9335..23f178fdf 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -8,7 +8,6 @@
8#include "common/scm_rev.h" 8#include "common/scm_rev.h"
9 9
10#include "common/key_map.h" 10#include "common/key_map.h"
11#include "core/hle/service/hid.h"
12 11
13// Abstraction class used to provide an interface between emulation code and the frontend (e.g. SDL, 12// Abstraction class used to provide an interface between emulation code and the frontend (e.g. SDL,
14// QGLWidget, GLFW, etc...) 13// QGLWidget, GLFW, etc...)
@@ -35,21 +34,11 @@ public:
35 /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread 34 /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread
36 virtual void DoneCurrent() = 0; 35 virtual void DoneCurrent() = 0;
37 36
38 static void KeyPressed(KeyMap::CitraKey key) { 37 /// Signals a key press action to the HID module
39 HID_User::PADState mapped_key = KeyMap::Get3DSKey(key); 38 static void KeyPressed(KeyMap::HostDeviceKey key);
40 39
41 if (mapped_key.hex != HID_User::PAD_NONE.hex) { 40 /// Signals a key release action to the HID module
42 HID_User::PADButtonPress(mapped_key); 41 static void KeyReleased(KeyMap::HostDeviceKey key);
43 }
44 }
45
46 static void KeyReleased(KeyMap::CitraKey key) {
47 HID_User::PADState mapped_key = KeyMap::Get3DSKey(key);
48
49 if (mapped_key.hex != HID_User::PAD_NONE.hex) {
50 HID_User::PADButtonRelease(mapped_key);
51 }
52 }
53 42
54 Config GetConfig() const { 43 Config GetConfig() const {
55 return m_config; 44 return m_config;
diff --git a/src/common/key_map.cpp b/src/common/key_map.cpp
index 5941a105b..309caab98 100644
--- a/src/common/key_map.cpp
+++ b/src/common/key_map.cpp
@@ -1,21 +1,25 @@
1// Copyright 2013 Dolphin Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "key_map.h" 5#include "key_map.h"
6#include <map> 6#include <map>
7 7
8
9namespace KeyMap { 8namespace KeyMap {
10 9
11std::map<CitraKey, HID_User::PADState> g_key_map; 10static std::map<HostDeviceKey, HID_User::PadState> key_map;
11static int next_device_id = 0;
12
13int NewDeviceId() {
14 return next_device_id++;
15}
12 16
13void SetKeyMapping(CitraKey key, HID_User::PADState padState) { 17void SetKeyMapping(HostDeviceKey key, HID_User::PadState padState) {
14 g_key_map[key].hex = padState.hex; 18 key_map[key].hex = padState.hex;
15} 19}
16 20
17HID_User::PADState Get3DSKey(CitraKey key) { 21HID_User::PadState GetPadKey(HostDeviceKey key) {
18 return g_key_map[key]; 22 return key_map[key];
19} 23}
20 24
21} 25}
diff --git a/src/common/key_map.h b/src/common/key_map.h
index 7e94df618..b5acfbab0 100644
--- a/src/common/key_map.h
+++ b/src/common/key_map.h
@@ -1,4 +1,4 @@
1// Copyright 2013 Dolphin Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
@@ -8,28 +8,38 @@
8 8
9namespace KeyMap { 9namespace KeyMap {
10 10
11class CitraKey { 11/**
12public: 12 * Represents a key for a specific host device.
13 CitraKey() : keyCode(0) {} 13 */
14 CitraKey(int code) : keyCode(code) {} 14struct HostDeviceKey {
15 15 int key_code;
16 int keyCode; 16 int device_id; ///< Uniquely identifies a host device
17 17
18 bool operator < (const CitraKey &other) const { 18 bool operator < (const HostDeviceKey &other) const {
19 return keyCode < other.keyCode; 19 if (device_id == other.device_id) {
20 return key_code < other.key_code;
21 }
22 return device_id < other.device_id;
20 } 23 }
21 24
22 bool operator == (const CitraKey &other) const { 25 bool operator == (const HostDeviceKey &other) const {
23 return keyCode == other.keyCode; 26 return device_id == other.device_id && key_code == other.key_code;
24 } 27 }
25}; 28};
26 29
27struct DefaultKeyMapping { 30/**
28 KeyMap::CitraKey key; 31 * Generates a new device id, which uniquely identifies a host device within KeyMap.
29 HID_User::PADState state; 32 */
30}; 33int NewDeviceId();
34
35/**
36 * Maps a device-specific key to a PadState.
37 */
38void SetKeyMapping(HostDeviceKey key, HID_User::PadState padState);
31 39
32void SetKeyMapping(CitraKey key, HID_User::PADState padState); 40/**
33HID_User::PADState Get3DSKey(CitraKey key); 41 * Gets the PadState that's mapped to the provided device-specific key.
42 */
43HID_User::PadState GetPadKey(HostDeviceKey key);
34 44
35} 45}
diff --git a/src/core/hle/service/hid.cpp b/src/core/hle/service/hid.cpp
index 1ef39fced..b6ec1b8ff 100644
--- a/src/core/hle/service/hid.cpp
+++ b/src/core/hle/service/hid.cpp
@@ -14,96 +14,102 @@
14 14
15namespace HID_User { 15namespace HID_User {
16 16
17Handle g_shared_mem = 0; ///< Handle to shared memory region designated to HID_User service 17// Handle to shared memory region designated to HID_User service
18static Handle shared_mem = 0;
18 19
19// Event handles 20// Event handles
20Handle g_event_pad_or_touch_1 = 0; 21static Handle event_pad_or_touch_1 = 0;
21Handle g_event_pad_or_touch_2 = 0; 22static Handle event_pad_or_touch_2 = 0;
22Handle g_event_accelerometer = 0; 23static Handle event_accelerometer = 0;
23Handle g_event_gyroscope = 0; 24static Handle event_gyroscope = 0;
24Handle g_event_debug_pad = 0; 25static Handle event_debug_pad = 0;
25 26
26// Next PAD state update information 27// Next Pad state update information
27PADState g_next_state = {{0}}; 28static PadState next_state = {{0}};
28u32 g_next_index = 0; 29static u32 next_index = 0;
29s16 g_next_circle_x = 0; 30static s16 next_circle_x = 0;
30s16 g_next_circle_y = 0; 31static s16 next_circle_y = 0;
31 32
32/** Gets a pointer to the PADData structure inside HID shared memory 33/**
34 * Gets a pointer to the PadData structure inside HID shared memory
33 */ 35 */
34static inline PADData* GetPADData() { 36static inline PadData* GetPadData() {
35 if (0 == g_shared_mem) 37 if (0 == shared_mem)
36 return nullptr; 38 return nullptr;
37 39
38 return reinterpret_cast<PADData*>(Kernel::GetSharedMemoryPointer(g_shared_mem, 0)); 40 return reinterpret_cast<PadData*>(Kernel::GetSharedMemoryPointer(shared_mem, 0));
39} 41}
40 42
41/** Circle PAD from keys. 43/**
44 * Circle Pad from keys.
42 * 45 *
43 * This is implemented as "pushed all the way to an edge (max) or centered (0)". 46 * This is implemented as "pushed all the way to an edge (max) or centered (0)".
44 * 47 *
45 * Indicate the circle pad is pushed completely to the edge in 1 of 8 directions. 48 * Indicate the circle pad is pushed completely to the edge in 1 of 8 directions.
46 */ 49 */
47void UpdateNextCirclePADState() { 50void UpdateNextCirclePadState() {
48 static const s16 max_value = 0x9C; 51 static const s16 max_value = 0x9C;
49 g_next_circle_x = g_next_state.circle_left ? -max_value : 0x0; 52 next_circle_x = next_state.circle_left ? -max_value : 0x0;
50 g_next_circle_x += g_next_state.circle_right ? max_value : 0x0; 53 next_circle_x += next_state.circle_right ? max_value : 0x0;
51 g_next_circle_y = g_next_state.circle_down ? -max_value : 0x0; 54 next_circle_y = next_state.circle_down ? -max_value : 0x0;
52 g_next_circle_y += g_next_state.circle_up ? max_value : 0x0; 55 next_circle_y += next_state.circle_up ? max_value : 0x0;
53} 56}
54 57
55/** Sets a PAD state (button or button combo) as pressed 58/**
59 * Sets a Pad state (button or button combo) as pressed
56 */ 60 */
57void PADButtonPress(PADState pad_state) { 61void PadButtonPress(PadState pad_state) {
58 g_next_state.hex |= pad_state.hex; 62 next_state.hex |= pad_state.hex;
59 UpdateNextCirclePADState(); 63 UpdateNextCirclePadState();
60} 64}
61 65
62/** Sets a PAD state (button or button combo) as released 66/**
67 * Sets a Pad state (button or button combo) as released
63 */ 68 */
64void PADButtonRelease(PADState pad_state) { 69void PadButtonRelease(PadState pad_state) {
65 g_next_state.hex &= ~pad_state.hex; 70 next_state.hex &= ~pad_state.hex;
66 UpdateNextCirclePADState(); 71 UpdateNextCirclePadState();
67} 72}
68 73
69/** Called after all PAD changes to be included in this update have been made, 74/**
70 * including both PAD key changes and analog circle PAD changes. 75 * Called after all Pad changes to be included in this update have been made,
76 * including both Pad key changes and analog circle Pad changes.
71 */ 77 */
72void PADUpdateComplete() { 78void PadUpdateComplete() {
73 PADData* pad_data = GetPADData(); 79 PadData* pad_data = GetPadData();
74 80
75 // Update PADData struct 81 // Update PadData struct
76 pad_data->current_state.hex = g_next_state.hex; 82 pad_data->current_state.hex = next_state.hex;
77 pad_data->index = g_next_index; 83 pad_data->index = next_index;
78 g_next_index = (g_next_index + 1) % pad_data->entries.size(); 84 next_index = (next_index + 1) % pad_data->entries.size();
79 85
80 // Get the previous PAD state 86 // Get the previous Pad state
81 u32 last_entry_index = (pad_data->index - 1) % pad_data->entries.size(); 87 u32 last_entry_index = (pad_data->index - 1) % pad_data->entries.size();
82 PADState old_state = pad_data->entries[last_entry_index].current_state; 88 PadState old_state = pad_data->entries[last_entry_index].current_state;
83 89
84 // Compute bitmask with 1s for bits different from the old state 90 // Compute bitmask with 1s for bits different from the old state
85 PADState changed; 91 PadState changed;
86 changed.hex = (g_next_state.hex ^ old_state.hex); 92 changed.hex = (next_state.hex ^ old_state.hex);
87 93
88 // Compute what was added 94 // Compute what was added
89 PADState additions; 95 PadState additions;
90 additions.hex = changed.hex & g_next_state.hex; 96 additions.hex = changed.hex & next_state.hex;
91 97
92 // Compute what was removed 98 // Compute what was removed
93 PADState removals; 99 PadState removals;
94 removals.hex = changed.hex & old_state.hex; 100 removals.hex = changed.hex & old_state.hex;
95 101
96 // Get the current PAD entry 102 // Get the current Pad entry
97 PADDataEntry* current_pad_entry = &pad_data->entries[pad_data->index]; 103 PadDataEntry* current_pad_entry = &pad_data->entries[pad_data->index];
98 104
99 // Update entry properties 105 // Update entry properties
100 current_pad_entry->current_state.hex = g_next_state.hex; 106 current_pad_entry->current_state.hex = next_state.hex;
101 current_pad_entry->delta_additions.hex = additions.hex; 107 current_pad_entry->delta_additions.hex = additions.hex;
102 current_pad_entry->delta_removals.hex = removals.hex; 108 current_pad_entry->delta_removals.hex = removals.hex;
103 109
104 // Set circle PAD 110 // Set circle Pad
105 current_pad_entry->circle_pad_x = g_next_circle_x; 111 current_pad_entry->circle_pad_x = next_circle_x;
106 current_pad_entry->circle_pad_y = g_next_circle_y; 112 current_pad_entry->circle_pad_y = next_circle_y;
107 113
108 // If we just updated index 0, provide a new timestamp 114 // If we just updated index 0, provide a new timestamp
109 if (pad_data->index == 0) { 115 if (pad_data->index == 0) {
@@ -111,24 +117,24 @@ void PADUpdateComplete() {
111 pad_data->index_reset_ticks = (s64)Core::g_app_core->GetTicks(); 117 pad_data->index_reset_ticks = (s64)Core::g_app_core->GetTicks();
112 } 118 }
113 119
114 // Signal both handles when there's an update to PAD or touch 120 // Signal both handles when there's an update to Pad or touch
115 Kernel::SignalEvent(g_event_pad_or_touch_1); 121 Kernel::SignalEvent(event_pad_or_touch_1);
116 Kernel::SignalEvent(g_event_pad_or_touch_2); 122 Kernel::SignalEvent(event_pad_or_touch_2);
117} 123}
118 124
119 125
120// TODO(peachum): 126// TODO(peachum):
121// Add a method for setting analog input from joystick device for the circle PAD. 127// Add a method for setting analog input from joystick device for the circle Pad.
122// 128//
123// This method should: 129// This method should:
124// * Be called after both PADButton<Press, Release>(). 130// * Be called after both PadButton<Press, Release>().
125// * Be called before PADUpdateComplete() 131// * Be called before PadUpdateComplete()
126// * Set current PADEntry.circle_pad_<axis> using analog data 132// * Set current PadEntry.circle_pad_<axis> using analog data
127// * Set PadData.raw_circle_pad_data 133// * Set PadData.raw_circle_pad_data
128// * Set PadData.current_state.circle_right = 1 if current PADEntry.circle_pad_x >= 41 134// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_x >= 41
129// * Set PadData.current_state.circle_up = 1 if current PADEntry.circle_pad_y >= 41 135// * Set PadData.current_state.circle_up = 1 if current PadEntry.circle_pad_y >= 41
130// * Set PadData.current_state.circle_left = 1 if current PADEntry.circle_pad_x <= -41 136// * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41
131// * Set PadData.current_state.circle_right = 1 if current PADEntry.circle_pad_y <= -41 137// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
132 138
133 139
134/** 140/**
@@ -149,12 +155,12 @@ void GetIPCHandles(Service::Interface* self) {
149 u32* cmd_buff = Service::GetCommandBuffer(); 155 u32* cmd_buff = Service::GetCommandBuffer();
150 156
151 cmd_buff[1] = 0; // No error 157 cmd_buff[1] = 0; // No error
152 cmd_buff[3] = g_shared_mem; 158 cmd_buff[3] = shared_mem;
153 cmd_buff[4] = g_event_pad_or_touch_1; 159 cmd_buff[4] = event_pad_or_touch_1;
154 cmd_buff[5] = g_event_pad_or_touch_2; 160 cmd_buff[5] = event_pad_or_touch_2;
155 cmd_buff[6] = g_event_accelerometer; 161 cmd_buff[6] = event_accelerometer;
156 cmd_buff[7] = g_event_gyroscope; 162 cmd_buff[7] = event_gyroscope;
157 cmd_buff[8] = g_event_debug_pad; 163 cmd_buff[8] = event_debug_pad;
158 164
159 DEBUG_LOG(KERNEL, "called"); 165 DEBUG_LOG(KERNEL, "called");
160} 166}
@@ -177,14 +183,14 @@ const Interface::FunctionInfo FunctionTable[] = {
177// Interface class 183// Interface class
178 184
179Interface::Interface() { 185Interface::Interface() {
180 g_shared_mem = Kernel::CreateSharedMemory("HID_User:SharedMem"); // Create shared memory object 186 shared_mem = Kernel::CreateSharedMemory("HID_User:SharedMem"); // Create shared memory object
181 187
182 // Create event handles 188 // Create event handles
183 g_event_pad_or_touch_1 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventPADOrTouch1"); 189 event_pad_or_touch_1 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventPadOrTouch1");
184 g_event_pad_or_touch_2 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventPADOrTouch2"); 190 event_pad_or_touch_2 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventPadOrTouch2");
185 g_event_accelerometer = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventAccelerometer"); 191 event_accelerometer = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventAccelerometer");
186 g_event_gyroscope = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventGyroscope"); 192 event_gyroscope = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventGyroscope");
187 g_event_debug_pad = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventDebugPAD"); 193 event_debug_pad = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventDebugPad");
188 194
189 Register(FunctionTable, ARRAY_SIZE(FunctionTable)); 195 Register(FunctionTable, ARRAY_SIZE(FunctionTable));
190} 196}
diff --git a/src/core/hle/service/hid.h b/src/core/hle/service/hid.h
index f5f76f0fc..a077e25cd 100644
--- a/src/core/hle/service/hid.h
+++ b/src/core/hle/service/hid.h
@@ -10,13 +10,15 @@
10//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
11// Namespace HID_User 11// Namespace HID_User
12 12
13// This service is used for interfacing to physical user controls... perhaps "Human Interface 13// This service is used for interfacing to physical user controls.
14// Devices"? Uses include game pad controls, accelerometers, gyroscopes, etc. 14// Uses include game pad controls, touchscreen, accelerometers, gyroscopes, and debug pad.
15 15
16namespace HID_User { 16namespace HID_User {
17 17
18/// Structure of a PAD controller state 18/**
19struct PADState { 19 * Structure of a Pad controller state.
20 */
21struct PadState {
20 union { 22 union {
21 u32 hex; 23 u32 hex;
22 24
@@ -40,58 +42,64 @@ struct PADState {
40 }; 42 };
41}; 43};
42 44
43/// Structure of a single entry in the PADData's PAD state history array 45/**
44struct PADDataEntry { 46 * Structure of a single entry in the PadData's Pad state history array.
45 PADState current_state; 47 */
46 PADState delta_additions; 48struct PadDataEntry {
47 PADState delta_removals; 49 PadState current_state;
50 PadState delta_additions;
51 PadState delta_removals;
48 52
49 s16 circle_pad_x; 53 s16 circle_pad_x;
50 s16 circle_pad_y; 54 s16 circle_pad_y;
51}; 55};
52 56
53/// Structure of all data related to the 3DS Pad 57/**
54struct PADData { 58 * Structure of all data related to the 3DS Pad.
59 */
60struct PadData {
55 s64 index_reset_ticks; 61 s64 index_reset_ticks;
56 s64 index_reset_ticks_previous; 62 s64 index_reset_ticks_previous;
57 u32 index; // the index of the last updated PAD state history element 63 u32 index; // the index of the last updated Pad state history element
58 64
59 u32 pad1; 65 u32 pad1;
60 u32 pad2; 66 u32 pad2;
61 67
62 PADState current_state; // same as entries[index].current_state 68 PadState current_state; // same as entries[index].current_state
63 u32 raw_circle_pad_data; 69 u32 raw_circle_pad_data;
64 70
65 u32 pad3; 71 u32 pad3;
66 72
67 std::array<PADDataEntry, 8> entries; // PAD state history 73 std::array<PadDataEntry, 8> entries; // Pad state history
68}; 74};
69 75
70// Pre-defined PADStates for single button presses 76// Pre-defined PadStates for single button presses
71const PADState PAD_NONE = {{0}}; 77const PadState PAD_NONE = {{0}};
72const PADState PAD_A = {{1u << 0}}; 78const PadState PAD_A = {{1u << 0}};
73const PADState PAD_B = {{1u << 1}}; 79const PadState PAD_B = {{1u << 1}};
74const PADState PAD_SELECT = {{1u << 2}}; 80const PadState PAD_SELECT = {{1u << 2}};
75const PADState PAD_START = {{1u << 3}}; 81const PadState PAD_START = {{1u << 3}};
76const PADState PAD_RIGHT = {{1u << 4}}; 82const PadState PAD_RIGHT = {{1u << 4}};
77const PADState PAD_LEFT = {{1u << 5}}; 83const PadState PAD_LEFT = {{1u << 5}};
78const PADState PAD_UP = {{1u << 6}}; 84const PadState PAD_UP = {{1u << 6}};
79const PADState PAD_DOWN = {{1u << 7}}; 85const PadState PAD_DOWN = {{1u << 7}};
80const PADState PAD_R = {{1u << 8}}; 86const PadState PAD_R = {{1u << 8}};
81const PADState PAD_L = {{1u << 9}}; 87const PadState PAD_L = {{1u << 9}};
82const PADState PAD_X = {{1u << 10}}; 88const PadState PAD_X = {{1u << 10}};
83const PADState PAD_Y = {{1u << 11}}; 89const PadState PAD_Y = {{1u << 11}};
84const PADState PAD_CIRCLE_RIGHT = {{1u << 28}}; 90const PadState PAD_CIRCLE_RIGHT = {{1u << 28}};
85const PADState PAD_CIRCLE_LEFT = {{1u << 29}}; 91const PadState PAD_CIRCLE_LEFT = {{1u << 29}};
86const PADState PAD_CIRCLE_UP = {{1u << 30}}; 92const PadState PAD_CIRCLE_UP = {{1u << 30}};
87const PADState PAD_CIRCLE_DOWN = {{1u << 31}}; 93const PadState PAD_CIRCLE_DOWN = {{1u << 31}};
88 94
89// Methods for updating the HID module's state 95// Methods for updating the HID module's state
90void PADButtonPress(PADState pad_state); 96void PadButtonPress(PadState pad_state);
91void PADButtonRelease(PADState pad_state); 97void PadButtonRelease(PadState pad_state);
92void PADUpdateComplete(); 98void PadUpdateComplete();
93 99
94/// HID service interface 100/**
101 * HID service interface.
102 */
95class Interface : public Service::Interface { 103class Interface : public Service::Interface {
96public: 104public:
97 105
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h
index d227b6aa4..5e8129b5a 100644
--- a/src/video_core/video_core.h
+++ b/src/video_core/video_core.h
@@ -27,6 +27,7 @@ static const int kScreenBottomHeight = 240; ///< 3DS bottom screen height
27 27
28extern RendererBase* g_renderer; ///< Renderer plugin 28extern RendererBase* g_renderer; ///< Renderer plugin
29extern int g_current_frame; ///< Current frame 29extern int g_current_frame; ///< Current frame
30extern EmuWindow* g_emu_window; ///< Emu window
30 31
31/// Start the video core 32/// Start the video core
32void Start(); 33void Start();