diff --git a/run/usb_gamepad_input.run b/run/usb_gamepad_input.run
index b52f671..a5cb3a5 100644
--- a/run/usb_gamepad_input.run
+++ b/run/usb_gamepad_input.run
@@ -49,6 +49,7 @@ set config {
+
}
@@ -116,10 +117,8 @@ append config {
-
-
-
+
}
diff --git a/src/drivers/usb_gamepad_input/gravis_gamepadpro.h b/src/drivers/usb_gamepad_input/gravis_gamepadpro.h
new file mode 100644
index 0000000..4e0033d
--- /dev/null
+++ b/src/drivers/usb_gamepad_input/gravis_gamepadpro.h
@@ -0,0 +1,129 @@
+/*
+ * \brief Gravis Gamepad Pro USB
+ * \author Emery Hemingway
+ * \date 2017-11-12
+ */
+
+/*
+ * Copyright (C) 2017 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+#ifndef _GRAVIS_GAMEPADPRO_H_
+#define _GRAVIS_GAMEPADPRO_H_
+
+/* Genode includes */
+#include
+
+/* local includes */
+#include
+
+
+struct Gravis_gamepadpro : Hid_device
+{
+ /*
+ * Supported devices
+ */
+ struct {
+ uint16_t vendor_id;
+ uint16_t product_id;
+ } devices[1] = {
+ {0x0428, 0x4001}
+ };
+
+ enum { B_NUM = 8 };
+ Input::Keycode butt_map[B_NUM] = {
+ Input::Keycode::BTN_Y, /* 0x01 Red */
+ Input::Keycode::BTN_B, /* 0x02 Yellow */
+ Input::Keycode::BTN_A, /* 0x04 Green */
+ Input::Keycode::BTN_X, /* 0x08 Blue */
+ Input::Keycode::BTN_TL, /* 0x10 */
+ Input::Keycode::BTN_TR, /* 0x20 */
+ Input::Keycode::BTN_TL2, /* 0x40 */
+ Input::Keycode::BTN_TR2, /* 0x80 */
+ };
+
+ Input::Keycode ss_map[2] = {
+ Input::Keycode::BTN_SELECT, /* 0x01 */
+ Input::Keycode::BTN_START, /* 0x02 */
+ };
+
+ enum {
+ IFACE_NUM = 0,
+ ALT_NUM = 0,
+ EP_NUM = 0,
+
+ DATA_LENGTH = 4,
+ };
+
+ uint8_t old_data[DATA_LENGTH] = { };
+
+ Gravis_gamepadpro(Input::Session_component &input_session)
+ : Hid_device(input_session, "Gravis Gamepad Pro") { }
+
+ /**************************
+ ** HID device interface **
+ **************************/
+
+ bool probe(uint16_t vendor_id, uint16_t product_id) const override
+ {
+ for (size_t i = 0; i < sizeof(devices)/sizeof(devices[0]); i++) {
+ if ( vendor_id == devices[i].vendor_id
+ && product_id == devices[i].product_id) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void parse(uint8_t const *new_data, size_t len) override
+ {
+ using namespace Genode;
+
+ if (len < DATA_LENGTH) return;
+
+ /* submit D-pad events */
+ {
+ uint8_t const xo = old_data[0];
+ uint8_t const yo = old_data[1];
+ uint8_t const xn = new_data[0];
+ uint8_t const yn = new_data[1];
+
+ if (xo != xn) {
+ Input::Event ev(
+ xn == 0x7f ? Input::Event::RELEASE : Input::Event::PRESS,
+ (xn & xo) ? Input::Keycode::BTN_RIGHT : Input::Keycode::BTN_LEFT,
+ 0, 0, 0, 0);
+ input_session.submit(ev);
+ }
+ if (yo != yn) {
+ Input::Event ev(
+ yn == 0x7f ? Input::Event::RELEASE : Input::Event::PRESS,
+ (yn & yo) ? Input::Keycode::BTN_BACK : Input::Keycode::BTN_FORWARD,
+ 0, 0, 0, 0);
+ input_session.submit(ev);
+ }
+ }
+
+ /* submit button events */
+ Utils::check_buttons(
+ input_session, old_data[2], new_data[2], B_NUM, butt_map);
+
+ /* Submit start/select events */
+ Utils::check_buttons(
+ input_session, old_data[3], new_data[3], 2, ss_map);
+
+ /* save for next poll */
+ Genode::memcpy(old_data, new_data, DATA_LENGTH);
+
+ /* Simple! And it was only $1.99! */
+ }
+
+ uint8_t iface() const { return IFACE_NUM; }
+ uint8_t ep() const { return EP_NUM; }
+ uint8_t alt() const { return ALT_NUM; }
+};
+
+#endif /* _GRAVIS_GAMEPADPRO_H_ */
diff --git a/src/drivers/usb_gamepad_input/main.cc b/src/drivers/usb_gamepad_input/main.cc
index dcf81f5..eb97e04 100644
--- a/src/drivers/usb_gamepad_input/main.cc
+++ b/src/drivers/usb_gamepad_input/main.cc
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
static bool const verbose_intr = false;
@@ -77,8 +78,9 @@ struct Usb::Hid
Retrolink_n64 retrolink_n64 { input_session };
Sony_ds3 sony_ds3 { input_session };
Sony_ds4 sony_ds4 { input_session };
+ Gravis_gamepadpro gravis_gamepadpro { input_session };
- enum { MAX_DEVICES = 8, };
+ enum { MAX_DEVICES = 9, };
Hid_device *devices[MAX_DEVICES] {
&generic,
&buffalo_snes,
@@ -88,6 +90,7 @@ struct Usb::Hid
&xboxone,
&sony_ds3,
&sony_ds4,
+ &gravis_gamepadpro
};
Hid_device *device = &generic;
@@ -541,7 +544,7 @@ struct Usb::Main
Env &env;
Heap heap { env.ram(), env.rm() };
- Input::Session_component input_session;
+ Input::Session_component input_session { env, env.pd() };
Static_root input_root { env.ep().manage(input_session) };
Usb::Hid hid { env, heap, input_session };