1
0
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:
harbaum
2015-05-24 20:19:02 +00:00
parent 110b1de6fd
commit 1ac253c864
5 changed files with 88 additions and 17 deletions

View File

@@ -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}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;