mirror of
https://github.com/mist-devel/mist-firmware.git
synced 2026-05-05 07:44:31 +00:00
[FIRMWARE] Test version with support for HATs on USB gamepads
This commit is contained in:
@@ -17,7 +17,11 @@ void mist_ini_parse()
|
||||
|
||||
//// vars ////
|
||||
// config data
|
||||
mist_cfg_t mist_cfg = {.scandoubler_disable = 0};
|
||||
mist_cfg_t mist_cfg = {
|
||||
.scandoubler_disable = 0,
|
||||
.mouse_boot_mode = 0,
|
||||
.joystick_ignore_hat = 0
|
||||
};
|
||||
|
||||
// mist ini sections
|
||||
const ini_section_t mist_ini_sections[] = {
|
||||
@@ -27,6 +31,8 @@ const ini_section_t mist_ini_sections[] = {
|
||||
// mist ini vars
|
||||
const ini_var_t mist_ini_vars[] = {
|
||||
{"SCANDOUBLER_DISABLE", (void*)(&(mist_cfg.scandoubler_disable)), UINT8, 0, 1, 1},
|
||||
{"MOUSE_BOOT_MODE", (void*)(&(mist_cfg.mouse_boot_mode)), UINT8, 0, 1, 1},
|
||||
{"JOYSTICK_IGNORE_HAT", (void*)(&(mist_cfg.joystick_ignore_hat)), UINT8, 0, 1, 1},
|
||||
{"KEY_REMAP", (void*)user_io_key_remap, CUSTOM_HANDLER, 0, 0, 1},
|
||||
// {"JOYSTICK_AXIS_REMAP", (void*)user_io_joystick_axis_remap, CUSTOM_HANDLER, 0, 0, 1},
|
||||
{"JOYSTICK_BUTTON_REMAP", (void*)hid_joystick_axis_remap, CUSTOM_HANDLER, 0, 0, 1}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
//// type definitions ////
|
||||
typedef struct {
|
||||
uint8_t scandoubler_disable;
|
||||
uint8_t mouse_boot_mode;
|
||||
uint8_t joystick_ignore_hat;
|
||||
} mist_cfg_t;
|
||||
|
||||
|
||||
|
||||
62
usb/hid.c
62
usb/hid.c
@@ -8,6 +8,7 @@
|
||||
#include "debug.h"
|
||||
#include "../user_io.h"
|
||||
#include "../hardware.h"
|
||||
#include "../mist_cfg.h"
|
||||
|
||||
static unsigned char kbd_led_state = 0; // default: all leds off
|
||||
static unsigned char joysticks = 0; // number of detected usb joysticks
|
||||
@@ -138,8 +139,10 @@ static uint8_t usb_hid_parse_conf(usb_device_t *dev, uint8_t conf, uint16_t len)
|
||||
|
||||
case HID_PROTOCOL_MOUSE:
|
||||
hid_debugf("HID protocol is MOUSE");
|
||||
// don't use boot mode for mice
|
||||
info->iface[info->bNumIfaces].ignore_boot_mode = true;
|
||||
// don't use boot mode for mice unless it's explicitey requested in mist.ini
|
||||
if(!mist_cfg.mouse_boot_mode)
|
||||
info->iface[info->bNumIfaces].ignore_boot_mode = true;
|
||||
|
||||
info->iface[info->bNumIfaces].device_type = HID_DEVICE_MOUSE;
|
||||
break;
|
||||
|
||||
@@ -455,21 +458,29 @@ static uint16_t collect_bits(uint8_t *p, uint16_t offset, uint8_t size, bool is_
|
||||
uint8_t bits = size;
|
||||
uint8_t shift = offset&7;
|
||||
|
||||
// iprintf("%c0 m:%x by:%d bi=%d sh=%d ->", 'X'+i, mask, byte, bits, shift);
|
||||
// iprintf("0 m:%x by:%d bi=%d sh=%d ->", mask, byte, bits, shift);
|
||||
uint16_t rval = (p[byte++] & mask) >> shift;
|
||||
// iprintf("%d\n", (int16_t)a[i]);
|
||||
// iprintf("%d\n", (int16_t)rval);
|
||||
mask = 0xff;
|
||||
shift = 8-shift;
|
||||
bits -= shift;
|
||||
|
||||
// further bytes if required
|
||||
while(bits) {
|
||||
mask = (bits<8)?(0xff>>(8-bits)):0xff;
|
||||
// iprintf("%c+ m:%x by:%d bi=%d sh=%d ->", 'X'+i, mask, byte, bits, shift);
|
||||
rval += (p[byte++] & mask) << shift;
|
||||
// iprintf("%d\n", (int16_t)a[i]);
|
||||
shift += 8;
|
||||
bits -= (bits>8)?8:bits;
|
||||
// first byte already contained more bits than we need
|
||||
if(shift > size) {
|
||||
// iprintf(" too many bits, masked %x ->", (1<<size)-1);
|
||||
// mask unused bits
|
||||
rval &= (1<<size)-1;
|
||||
// iprintf("%d\n", (int16_t)rval);
|
||||
} else {
|
||||
// further bytes if required
|
||||
while(bits) {
|
||||
mask = (bits<8)?(0xff>>(8-bits)):0xff;
|
||||
// iprintf("+ m:%x by:%d bi=%d sh=%d ->", mask, byte, bits, shift);
|
||||
rval += (p[byte++] & mask) << shift;
|
||||
// iprintf("%d\n", (int16_t)rval);
|
||||
shift += 8;
|
||||
bits -= (bits>8)?8:bits;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_signed) {
|
||||
@@ -480,7 +491,7 @@ static uint16_t collect_bits(uint8_t *p, uint16_t offset, uint8_t size, bool is_
|
||||
rval |= sign_bit;
|
||||
sign_bit <<= 1;
|
||||
}
|
||||
// iprintf("%c is negative -> sign expand to %d\n", 'X'+i, (int16_t)a[i]);
|
||||
// iprintf(" is negative -> sign expand to %d\n", (int16_t)rval);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +590,7 @@ static uint8_t usb_hid_poll(usb_device_t *dev) {
|
||||
|
||||
// ---------- process joystick -------------
|
||||
if(iface->device_type == HID_DEVICE_JOYSTICK) {
|
||||
|
||||
for(i=0;i<2;i++) {
|
||||
// scale to 0 -> 255 range. 99% of the joysticks already deliver that
|
||||
if((conf->joystick_mouse.axis[i].logical.min != 0) ||
|
||||
@@ -589,7 +601,29 @@ static uint8_t usb_hid_poll(usb_device_t *dev) {
|
||||
}
|
||||
}
|
||||
|
||||
// iprintf("JOY X:%d Y:%d\n", a[0], a[1]);
|
||||
// handle hat if present and overwrite any axis value
|
||||
if(conf->joystick_mouse.hat.size && !mist_cfg.joystick_ignore_hat) {
|
||||
uint8_t hat = collect_bits(p, conf->joystick_mouse.hat.offset,
|
||||
conf->joystick_mouse.hat.size, 0);
|
||||
|
||||
// we don't want more than 4 bits
|
||||
uint8_t size = conf->joystick_mouse.hat.size;
|
||||
while(size-- > 4)
|
||||
hat >>= 1;
|
||||
|
||||
// TODO: Deal with 3 bit (4 direction/no diagonal) hats
|
||||
static const uint8_t hat2x[] = { 128,255,255,255,128, 0, 0, 0 };
|
||||
static const uint8_t hat2y[] = { 0, 0,128,255,255,255,128, 0 };
|
||||
|
||||
if(hat&8)
|
||||
a[0] = a[1] = 128;
|
||||
else {
|
||||
a[0] = hat2x[hat];
|
||||
a[1] = hat2y[hat];
|
||||
}
|
||||
}
|
||||
|
||||
// iprintf("JOY X:%d Y:%d\n", a[0], a[1]);
|
||||
|
||||
if(a[0] < 64) jmap |= JOY_LEFT;
|
||||
if(a[0] > 192) jmap |= JOY_RIGHT;
|
||||
|
||||
@@ -53,6 +53,7 @@ typedef struct {
|
||||
#define USAGE_Y 49
|
||||
#define USAGE_Z 50
|
||||
#define USAGE_WHEEL 56
|
||||
#define USAGE_HAT 57
|
||||
|
||||
// check if the current report
|
||||
bool report_is_usable(uint16_t bit_count, uint8_t report_complete, hid_report_t *conf) {
|
||||
@@ -93,6 +94,7 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
|
||||
// joystick/mouse components
|
||||
int8_t axis[2] = { -1, -1};
|
||||
uint8_t btns = 0;
|
||||
int8_t hat = -1;
|
||||
|
||||
conf->type = REPORT_TYPE_NONE;
|
||||
|
||||
@@ -155,7 +157,7 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
|
||||
|
||||
switch(tag) {
|
||||
case 8:
|
||||
//
|
||||
// handle found buttons
|
||||
if(btns) {
|
||||
if((conf->type == REPORT_TYPE_JOYSTICK) ||
|
||||
(conf->type == REPORT_TYPE_MOUSE)) {
|
||||
@@ -180,7 +182,7 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// handle found axes
|
||||
char c;
|
||||
for(c=0;c<2;c++) {
|
||||
if(axis[c] >= 0) {
|
||||
@@ -201,6 +203,17 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
|
||||
}
|
||||
}
|
||||
|
||||
// handle found hat
|
||||
if(hat >= 0) {
|
||||
uint16_t cnt = bit_count + report_size * hat;
|
||||
hidp_debugf(" (HAT @ %d (byte %d, bit %d), size %d)",
|
||||
cnt, cnt/8, cnt&7, report_size);
|
||||
if(conf->type == REPORT_TYPE_JOYSTICK) {
|
||||
conf->joystick_mouse.hat.offset = cnt;
|
||||
conf->joystick_mouse.hat.size = report_size;
|
||||
}
|
||||
}
|
||||
|
||||
hidp_extreme_debugf("INPUT(%d)", value);
|
||||
|
||||
// reset for next inputs
|
||||
@@ -208,6 +221,7 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
|
||||
usage_count = 0;
|
||||
btns = 0;
|
||||
axis[0] = axis[1] = -1;
|
||||
hat = -1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
@@ -390,6 +404,15 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
|
||||
axis[1] = usage_count;
|
||||
}
|
||||
}
|
||||
} else if((value == USAGE_HAT) && app_collection) {
|
||||
// usage(hat) is allowed within the app collection
|
||||
hidp_extreme_debugf(" -> hat usage");
|
||||
|
||||
// we support hat on joysticks only
|
||||
if(conf->type == REPORT_TYPE_JOYSTICK) {
|
||||
hidp_extreme_debugf("JOYSTICK: found hat @ %d", usage_count);
|
||||
hat = usage_count;
|
||||
}
|
||||
} else {
|
||||
hidp_extreme_debugf(" -> UNSUPPORTED USAGE");
|
||||
// return false;
|
||||
|
||||
@@ -27,6 +27,12 @@ typedef struct {
|
||||
uint8_t byte_offset;
|
||||
uint8_t bitmask;
|
||||
} button[4]; // 4 buttons
|
||||
|
||||
struct {
|
||||
uint16_t offset;
|
||||
uint8_t size;
|
||||
} hat; // 1 hat (joystick only)
|
||||
|
||||
} joystick_mouse;
|
||||
};
|
||||
} hid_report_t;
|
||||
|
||||
Reference in New Issue
Block a user