From c07beb07349c6a21431592fc9c606530ee350a02 Mon Sep 17 00:00:00 2001 From: Raphael Assenat Date: Sat, 22 Aug 2015 00:44:51 -0400 Subject: [PATCH] Button mapping framework --- mappings.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ mappings.h | 16 +++++++++++ usbpad.h | 3 ++ 3 files changed, 99 insertions(+) create mode 100644 mappings.c create mode 100644 mappings.h diff --git a/mappings.c b/mappings.c new file mode 100644 index 0000000..ec88408 --- /dev/null +++ b/mappings.c @@ -0,0 +1,80 @@ +#include "mappings.h" +#include "gamepads.h" +#include "usbpad.h" + +/* Default N64 and Gamecube mappings meant to work together + * i.e. Controllers should be mostly interchangeable + * + * - Main buttons first + * - Common buttons at the same place + * - Similar layout for GC Y/X and N64 C-Left and C-Down + */ + +static struct mapping map_gc_default[] = { + { GC_BTN_A, USB_BTN(0) }, + { GC_BTN_B, USB_BTN(1) }, + { GC_BTN_Z, USB_BTN(2) }, + { GC_BTN_START, USB_BTN(3) }, + + { GC_BTN_L, USB_BTN(4) }, + { GC_BTN_R, USB_BTN(5) }, + + { GC_BTN_Y, USB_BTN(8) }, // N64 C-Left + { GC_BTN_X, USB_BTN(7) }, // N64 C-Down + + { GC_BTN_DPAD_UP, USB_BTN(10) }, + { GC_BTN_DPAD_DOWN, USB_BTN(11) }, + { GC_BTN_DPAD_LEFT, USB_BTN(12) }, + { GC_BTN_DPAD_RIGHT, USB_BTN(13) }, + + { } /* terminator */ +}; + +static struct mapping map_n64_default[] = { + { N64_BTN_A, USB_BTN(0) }, + { N64_BTN_B, USB_BTN(1) }, + { N64_BTN_Z, USB_BTN(2) }, + { N64_BTN_START, USB_BTN(3) }, + + { N64_BTN_L, USB_BTN(4) }, + { N64_BTN_R, USB_BTN(5) }, + { N64_BTN_C_UP, USB_BTN(6) }, + { N64_BTN_C_DOWN, USB_BTN(7) }, // GC X + + { N64_BTN_C_LEFT, USB_BTN(8) }, // GC_Y + { N64_BTN_C_RIGHT, USB_BTN(9) }, + + { N64_BTN_DPAD_UP, USB_BTN(10) }, + { N64_BTN_DPAD_DOWN, USB_BTN(11) }, + { N64_BTN_DPAD_LEFT, USB_BTN(12) }, + { N64_BTN_DPAD_RIGHT, USB_BTN(13) }, + + { } /* terminator */ +}; + +static uint16_t domap(const struct mapping *map, uint16_t input) +{ + const struct mapping *cur = map; + uint16_t out = 0; + + while (cur->ctl_btn && cur->usb_btn) { + if (input & cur->ctl_btn) { + out |= cur->usb_btn; + } + cur++; + } + + return out; +} + +uint16_t mappings_do(uint8_t mapping_id, uint16_t input) +{ + switch(mapping_id) { + case MAPPING_GAMECUBE_DEFAULT: + return domap(map_gc_default, input); + case MAPPING_N64_DEFAULT: + return domap(map_n64_default, input); + } + + return 0; +} diff --git a/mappings.h b/mappings.h new file mode 100644 index 0000000..ffa5d27 --- /dev/null +++ b/mappings.h @@ -0,0 +1,16 @@ +#ifndef _mappings_h__ +#define _mappings_h__ + +#include + +struct mapping { + uint16_t ctl_btn; + uint16_t usb_btn; +}; + +#define MAPPING_GAMECUBE_DEFAULT 0x00 +#define MAPPING_N64_DEFAULT 0x10 + +uint16_t mappings_do(uint8_t mapping_id, uint16_t input); + +#endif // _mappings_h__ diff --git a/usbpad.h b/usbpad.h index 3dbd361..ceaafd2 100644 --- a/usbpad.h +++ b/usbpad.h @@ -5,4 +5,7 @@ void usbpad_init(void); int usbpad_getReportSize(void); void usbpad_buildReport(const gamepad_data *pad_data, unsigned char *dstbuf); +// For mappings. ID starts at 0. +#define USB_BTN(id) (0x0001 << (id)) + #endif // USBPAD_H__