Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ MPG is a C++ library for processing and converting gamepad inputs, with support
* XInput (PC, Android, Raspberry Pi, MiSTer, etc.)
* DirectInput (PC, Mac, PS3)
* Nintendo Switch
* Mega Drive 2 Mini
* A standard set of USB descriptors, report data structures and conversion methods for supported input types
* Per-button debouncing with a configurable interval
* Use D-pad to emulate Left or Right analog stick movement
Expand Down Expand Up @@ -294,22 +295,22 @@ void GamepadStorage::save() { }

MPG uses a generic button labeling for gamepad state, which is then converted to the appropriate input type before sending. Here are the mappings of generic buttons to each supported platform/layout:

| MPG | XInput | Switch | PS3 | DirectInput | Arcade |
| ------ | ------ | ------- | ------------ | ------------ | ------ |
| **B1** | A | B | Cross | 2 | K1 |
| **B2** | B | A | Circle | 3 | K2 |
| **B3** | X | Y | Square | 1 | P1 |
| **B4** | Y | X | Triangle | 4 | P2 |
| **L1** | LB | L | L1 | 5 | P4 |
| **R1** | RB | R | R1 | 6 | P3 |
| **L2** | LT | ZL | L2 | 7 | K4 |
| **R2** | RT | ZR | R2 | 8 | K3 |
| **S1** | Back | Minus | Select | 9 | Coin |
| **S2** | Start | Plus | Start | 10 | Start |
| **L3** | LS | LS | L3 | 11 | LS |
| **R3** | RS | RS | R3 | 12 | RS |
| **A1** | Guide | Home | - | 13 | - |
| **A2** | - | Capture | - | 14 | - |
| MPG | XInput | Switch | PS3 | MD-Mini | DirectInput | Arcade |
| ------ | ------ | ------- | ------------ |---------| ------------ | ------ |
| **B1** | A | B | Cross | A | 2 | K1 |
| **B2** | B | A | Circle | B | 3 | K2 |
| **B3** | X | Y | Square | X | 1 | P1 |
| **B4** | Y | X | Triangle | Y | 4 | P2 |
| **L1** | LB | L | L1 | - | 5 | P4 |
| **R1** | RB | R | R1 | Z | 6 | P3 |
| **L2** | LT | ZL | L2 | - | 7 | K4 |
| **R2** | RT | ZR | R2 | C | 8 | K3 |
| **S1** | Back | Minus | Select | Mode | 9 | Coin |
| **S2** | Start | Plus | Start | Start | 10 | Start |
| **L3** | LS | LS | L3 | - | 11 | LS |
| **R3** | RS | RS | R3 | - | 12 | RS |
| **A1** | Guide | Home | - | - | 13 | - |
| **A2** | - | Capture | - | - | 14 | - |

The MPG class contains helper methods for checking the state of each button, for instance `MPG::pressedB1()`, `MPG::pressedR3`, etc.

Expand Down
6 changes: 3 additions & 3 deletions library.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "MPG",
"version": "0.4.0",
"version": "0.4.1",
"description": "C++ library for processing and converting gamepad inputs, with support for XInput, DirectInput and Nintendo Switch.",
"keywords": ["c++", "baremetal", "gamepad", "hid", "dinput", "directinput", "switch", "xinput"],
"authors": [
{
"name": "FeralAI",
"url": "https://github.com/FeralAI/MPG"
"name": "Ann",
"url": "https://github.com/alirin222/MPG"
}
],
"license": "MIT"
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=MPG
version=0.4.0
version=0.4.1
author=FeralAI
maintainer=FeralAI
sentence=C++ library for processing and converting gamepad inputs, with support for XInput, DirectInput and Nintendo Switch.
Expand Down
21 changes: 21 additions & 0 deletions src/GamepadDescriptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ static uint16_t getConfigurationDescriptor(const uint8_t *buffer, InputMode mode
buffer = switch_configuration_descriptor;
return sizeof(switch_configuration_descriptor);

case INPUT_MODE_MDMINI:
buffer = mdmini_configuration_descriptor;
return sizeof(mdmini_configuration_descriptor);

default:
buffer = hid_configuration_descriptor;
return sizeof(hid_configuration_descriptor);
Expand All @@ -30,6 +34,10 @@ static uint16_t getDeviceDescriptor(const uint8_t *buffer, InputMode mode)
buffer = switch_device_descriptor;
return sizeof(switch_device_descriptor);

case INPUT_MODE_MDMINI:
buffer = mdmini_device_descriptor;
return sizeof(mdmini_device_descriptor);

default:
buffer = hid_device_descriptor;
return sizeof(hid_device_descriptor);
Expand All @@ -44,6 +52,10 @@ static uint16_t getHIDDescriptor(const uint8_t *buffer, InputMode mode)
buffer = switch_hid_descriptor;
return sizeof(switch_hid_descriptor);

case INPUT_MODE_MDMINI:
buffer = mdmini_hid_descriptor;
return sizeof(mdmini_hid_descriptor);

default:
buffer = hid_hid_descriptor;
return sizeof(hid_hid_descriptor);
Expand All @@ -58,6 +70,10 @@ static uint16_t getHIDReport(const uint8_t *buffer, InputMode mode)
buffer = switch_report_descriptor;
return sizeof(switch_report_descriptor);

case INPUT_MODE_MDMINI:
buffer = mdmini_report_descriptor;
return sizeof(mdmini_report_descriptor);

default:
buffer = hid_report_descriptor;
return sizeof(hid_report_descriptor);
Expand All @@ -84,6 +100,11 @@ static uint16_t getStringDescriptor(const uint16_t *buffer, InputMode mode, uint
size = sizeof(switch_string_descriptors[index]);
break;

case INPUT_MODE_MDMINI:
value = (const char *)mdmini_string_descriptors[index];
size = sizeof(mdmini_string_descriptors[index]);
break;

default:
value = (const char *)hid_string_descriptors[index];
size = sizeof(hid_string_descriptors[index]);
Expand Down
21 changes: 21 additions & 0 deletions src/GamepadDescriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "descriptors/HIDDescriptors.h"
#include "descriptors/SwitchDescriptors.h"
#include "descriptors/XInputDescriptors.h"
#include "descriptors/MdminiDescriptors.h"

// Default value used for networking, override if necessary
static uint8_t macAddress[6] = { 0x02, 0x02, 0x84, 0x6A, 0x96, 0x00 };
Expand All @@ -26,6 +27,10 @@ static const uint8_t *getConfigurationDescriptor(uint16_t *size, InputMode mode)
*size = sizeof(switch_configuration_descriptor);
return switch_configuration_descriptor;

case INPUT_MODE_MDMINI:
*size = sizeof(mdmini_configuration_descriptor);
return mdmini_configuration_descriptor;

default:
*size = sizeof(hid_configuration_descriptor);
return hid_configuration_descriptor;
Expand All @@ -44,6 +49,10 @@ static const uint8_t *getDeviceDescriptor(uint16_t *size, InputMode mode)
*size = sizeof(switch_device_descriptor);
return switch_device_descriptor;

case INPUT_MODE_MDMINI:
*size = sizeof(mdmini_device_descriptor);
return mdmini_device_descriptor;

default:
*size = sizeof(hid_device_descriptor);
return hid_device_descriptor;
Expand All @@ -58,6 +67,10 @@ static const uint8_t *getHIDDescriptor(uint16_t *size, InputMode mode)
*size = sizeof(switch_hid_descriptor);
return switch_hid_descriptor;

case INPUT_MODE_MDMINI:
*size = sizeof(mdmini_hid_descriptor);
return mdmini_hid_descriptor;

default:
*size = sizeof(hid_hid_descriptor);
return hid_hid_descriptor;
Expand All @@ -72,6 +85,10 @@ static const uint8_t *getHIDReport(uint16_t *size, InputMode mode)
*size = sizeof(switch_report_descriptor);
return switch_report_descriptor;

case INPUT_MODE_MDMINI:
*size = sizeof(mdmini_report_descriptor);
return mdmini_report_descriptor;

default:
*size = sizeof(hid_report_descriptor);
return hid_report_descriptor;
Expand Down Expand Up @@ -127,6 +144,10 @@ static const uint16_t *getStringDescriptor(uint16_t *size, InputMode mode, uint8
str = (char *)switch_string_descriptors[index];
break;

case INPUT_MODE_MDMINI:
str = (char *)mdmini_string_descriptors[index];
break;

default:
str = (char *)hid_string_descriptors[index];
break;
Expand Down
1 change: 1 addition & 0 deletions src/GamepadEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ typedef enum
INPUT_MODE_XINPUT,
INPUT_MODE_SWITCH,
INPUT_MODE_HID,
INPUT_MODE_MDMINI,
INPUT_MODE_CONFIG = 255,
} InputMode;

Expand Down
36 changes: 18 additions & 18 deletions src/GamepadState.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,24 @@
/*
Gamepad button mapping table:

+--------+--------+---------+----------+----------+--------+
| MPG | XInput | Switch | PS3 | DInput | Arcade |
+--------+--------+---------+----------|----------+--------+
| B1 | A | B | Cross | 2 | K1 |
| B2 | B | A | Circle | 3 | K2 |
| B3 | X | Y | Square | 1 | P1 |
| B4 | Y | X | Triangle | 4 | P2 |
| L1 | LB | L | L1 | 5 | P4 |
| R1 | RB | R | R1 | 6 | P3 |
| L2 | LT | ZL | L2 | 7 | K4 |
| R2 | RT | ZR | R2 | 8 | K3 |
| S1 | Back | - | Select | 9 | Coin |
| S2 | Start | + | Start | 10 | Start |
| L3 | LS | LS | L3 | 11 | LS |
| R3 | RS | RS | R3 | 12 | RS |
| A1 | Guide | Home | - | 13 | - |
| A2 | - | Capture | - | 14 | - |
+--------+--------+---------+----------+----------+--------+
+--------+--------+---------+----------+---------+----------+--------+
| MPG | XInput | Switch | PS3 | MD-MINI | DInput | Arcade |
+--------+--------+---------+----------|---------|----------+--------+
| B1 | A | B | Cross | A | 2 | K1 |
| B2 | B | A | Circle | B | 3 | K2 |
| B3 | X | Y | Square | X | 1 | P1 |
| B4 | Y | X | Triangle | Y | 4 | P2 |
| L1 | LB | L | L1 | - | 5 | P4 |
| R1 | RB | R | R1 | Z | 6 | P3 |
| L2 | LT | ZL | L2 | - | 7 | K4 |
| R2 | RT | ZR | R2 | C | 8 | K3 |
| S1 | Back | - | Select | Mode | 9 | Coin |
| S2 | Start | + | Start | Start | 10 | Start |
| L3 | LS | LS | L3 | - | 11 | LS |
| R3 | RS | RS | R3 | - | 12 | RS |
| A1 | Guide | Home | - | - | 13 | - |
| A2 | - | Capture | - | - | 14 | - |
+--------+--------+---------+----------+---------|----------+--------+
*/

#define GAMEPAD_MASK_UP (1U << 0)
Expand Down
45 changes: 45 additions & 0 deletions src/MPG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ static XInputReport xinputReport
._reserved = { },
};

static MdminiReport mdminiReport
{
.id = 0x01, // ID
.notuse1 = 0x7f, // [Not Use] 0x7f
.notuse2 = 0x7f, // [Not Use] 0x7f
.hat1 = 0x7f, // LEFT:0x00, RIGHT:0xFF
.hat2 = 0x7f, // UP:0x00, DOWN:0xFF
.buttons1 = 0x0f, // X A B Y 1b 1b 1b 1b
.buttons2 = 0x00, // 0b 0b START MODE 0b 0b C Z
.notuse3 = 0x00, // [Not Use] 0x00
};

void *MPG::getReport()
{
switch (options.inputMode)
Expand All @@ -51,6 +63,9 @@ void *MPG::getReport()
case INPUT_MODE_SWITCH:
return getSwitchReport();

case INPUT_MODE_MDMINI:
return getMdminiReport();

default:
return getHIDReport();
}
Expand All @@ -67,6 +82,9 @@ uint16_t MPG::getReportSize()
case INPUT_MODE_SWITCH:
return sizeof(SwitchReport);

case INPUT_MODE_MDMINI:
return sizeof(MdminiReport);

default:
return sizeof(HIDReport);
}
Expand Down Expand Up @@ -197,6 +215,33 @@ XInputReport *MPG::getXInputReport()
return &xinputReport;
}

MdminiReport *MPG::getMdminiReport()
{
mdminiReport.hat1 = 0x7f;
mdminiReport.hat2 = 0x7f;

if (pressedLeft()) { mdminiReport.hat1 = MDMINI_MASK_LEFT; }
if (pressedRight()) { mdminiReport.hat1 = MDMINI_MASK_RIGHT; }

if (pressedUp()) { mdminiReport.hat2 = MDMINI_MASK_UP; }
if (pressedDown()) { mdminiReport.hat2 = MDMINI_MASK_DOWN; }

mdminiReport.buttons1 = 0x0f
| (pressedB1() ? MDMINI_MASK_A : 0)
| (pressedB2() ? MDMINI_MASK_B : 0)
| (pressedB3() ? MDMINI_MASK_X : 0)
| (pressedB4() ? MDMINI_MASK_Y : 0)
;

mdminiReport.buttons2 = 0x00
| (pressedR1() ? MDMINI_MASK_Z : 0)
| (pressedR2() ? MDMINI_MASK_C : 0)
| (pressedS2() ? MDMINI_MASK_START : 0)
| (pressedS1() ? MDMINI_MASK_MODE : 0)
;

return &mdminiReport;
}

GamepadHotkey MPG::hotkey()
{
Expand Down
7 changes: 7 additions & 0 deletions src/MPG.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ class MPG
*/
XInputReport *getXInputReport();

/**
* @brief Generate USB report for MD-mini 6B Pad mode.
*
* @return MdminiReport MDmini report pointer.
*/
MdminiReport *getMdminiReport();

/**
* @brief Check for a button press. Used by `pressed[Button]` helper methods.
*/
Expand Down
Loading