Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wii addon refactor and button/analog mapping support #501

Merged
merged 23 commits into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
af4fd3e
Added improved Wii extension detection.
mikepparks May 11, 2023
f58175c
Merge branch 'OpenStickCommunity:main' into main
mikepparks May 17, 2023
98a666f
Merge branch 'OpenStickCommunity:main' into main
mikepparks May 24, 2023
f122ec4
Refactor of WiiExtension library to better separate controller contexts.
mikepparks May 24, 2023
0f4df7f
Added analog calibration. If controller does not have stored calibrat…
mikepparks May 25, 2023
60570f5
Adjust default analog calibration when data is unavailable on the dev…
mikepparks May 26, 2023
fb21dbf
Added default calibration for Drums and Turntable extensions since no…
mikepparks May 29, 2023
f27d61d
Merge branch 'OpenStickCommunity:main' into main
mikepparks May 29, 2023
ece63df
Moved WiiExtensionController enum to a type.
mikepparks May 30, 2023
2f9f916
Added toggle state for DJ Hero Euphoria button LED.
mikepparks Jun 2, 2023
9d6f6e2
Merge branch 'OpenStickCommunity:main' into main
mikepparks Jun 2, 2023
ad4f8c2
Merge branch 'OpenStickCommunity:main' into main
mikepparks Jun 7, 2023
4118959
Merge branch 'OpenStickCommunity:main' into main
mikepparks Jun 27, 2023
e0ce2cd
Merge branch 'OpenStickCommunity:main' into main
mikepparks Aug 18, 2023
1d648f6
Refactored polling logic to allow for options on boot
mikepparks Aug 19, 2023
5b173ef
Merge branch 'OpenStickCommunity:main' into main
mikepparks Aug 20, 2023
2813fea
Merge branch 'OpenStickCommunity:main' into main
mikepparks Aug 27, 2023
665a2b4
Merge branch 'OpenStickCommunity:main' into main
mikepparks Sep 5, 2023
81c94ff
Refactor of Wii addon to include button and analog mapping.
mikepparks Sep 6, 2023
7d76a07
Fixed issue causing Classic Pro-based controllers from functioning.
mikepparks Sep 6, 2023
5ede153
Fixes unintentional tabs and moved unneeded debug variables behind WI…
mikepparks Sep 8, 2023
0566ac9
Minor view refactors on input selectors
mikepparks Sep 9, 2023
92a6eba
Fixed key warnings
mikepparks Sep 9, 2023
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
Binary file modified docs/assets/images/gpc-add-ons-wii-extensions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 3 additions & 19 deletions docs/web-configurator-add-ons.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,28 +163,12 @@ Enabling this add-on will allow you to use GP2040-CE on a PS4 with an 8 minute t
* `I2C Block` - The block of I2C to use (i2c0 or i2c1).
* `I2C Speed` - Sets the speed of I2C communication. Common values are `100000` for standard, or `400000` for fast.

Supported Extension Controllers and their mapping is as follows:

| GP2040-CE | Nunchuck | Classic | Guitar Hero Guitar |
|-----------|----------|--------------|--------------------|
| B1 | C | B | Green |
| B2 | Z | A | Red |
| B3 | | Y | Blue |
| B4 | | X | Yellow |
| L1 | | L | |
| L2 | | ZL | |
| R1 | | R | |
| R2 | | ZR | |
| S1 | | Select | |
| S2 | | Start | |
| A1 | | Home | |
| D-Pad | | D-Pad | Strum Up/Down |
| Analog | Left | Left & Right | Left |

Classic Controller support includes Classic, Classic Pro, and NES/SNES Mini Controllers.
Classic Controller support includes Classic, Classic Pro, and NES/SNES Mini Controllers.

Original Classic Controller L & R triggers are analog sensitive, where Pro triggers are not.

Due to an accessory hardware issue, Drum & DJ turntable controllers may require hot-swapping from a Nunchuk or Classic controller before being usable.

## SNES Input

![GP2040-CE Configurator - SNES Input](assets/images/gpc-add-ons-snespad-input.png)
Expand Down
268 changes: 268 additions & 0 deletions headers/addons/wiiext.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#define _WIIExtensionAddon_H

#include <string>
#include <map>
#include <vector>
#include <numeric>
#include <stdint.h>
#include <hardware/i2c.h>
#include "BoardConfig.h"
Expand Down Expand Up @@ -37,6 +40,46 @@
#define WII_EXTENSION_I2C_SPEED 400000
#endif

#define WII_SET_MASK(bits, check, val) ((check) ? ((bits) |= (val)) : ((bits) &= ~(val)))

typedef enum {
WII_ANALOG_TYPE_NONE,
WII_ANALOG_TYPE_LEFT_STICK_X,
WII_ANALOG_TYPE_LEFT_STICK_Y,
WII_ANALOG_TYPE_RIGHT_STICK_X,
WII_ANALOG_TYPE_RIGHT_STICK_Y,
WII_ANALOG_TYPE_DPAD_X,
WII_ANALOG_TYPE_DPAD_Y,
WII_ANALOG_TYPE_LEFT_TRIGGER,
WII_ANALOG_TYPE_RIGHT_TRIGGER,
WII_ANALOG_TYPE_LEFT_STICK_X_PLUS,
WII_ANALOG_TYPE_LEFT_STICK_X_MINUS,
WII_ANALOG_TYPE_LEFT_STICK_Y_PLUS,
WII_ANALOG_TYPE_LEFT_STICK_Y_MINUS,
WII_ANALOG_TYPE_RIGHT_STICK_X_PLUS,
WII_ANALOG_TYPE_RIGHT_STICK_X_MINUS,
WII_ANALOG_TYPE_RIGHT_STICK_Y_PLUS,
WII_ANALOG_TYPE_RIGHT_STICK_Y_MINUS,
WII_ANALOG_TYPE_COUNT
} WiiAnalogType;

typedef struct {
uint16_t axisType;
uint16_t minRange;
uint16_t maxRange;
} WiiAnalogAxis;

typedef struct {
// button ID = gamepad mask value
std::unordered_map<uint16_t, uint32_t> buttonMap;
std::unordered_map<uint16_t, WiiAnalogAxis> analogMap;
} WiiExtensionConfig;

typedef struct {
uint16_t analogInput;
uint16_t analogValue;
} WiiAnalogChange;

class WiiExtensionInput : public GPAddon {
public:
virtual bool available();
Expand All @@ -49,6 +92,189 @@ class WiiExtensionInput : public GPAddon {
uint32_t uIntervalMS;
uint32_t nextTimer;

// controller ID = config
// defaults if no defined config
std::unordered_map<uint16_t, WiiExtensionConfig> extensionConfigs = {
{
WiiExtensionController::WII_EXTENSION_NUNCHUCK,
{
{
{WiiButtons::WII_BUTTON_C,GAMEPAD_MASK_B1},
{WiiButtons::WII_BUTTON_Z,GAMEPAD_MASK_B2},
},
{
{
WiiAnalogs::WII_ANALOG_LEFT_X,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_X, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_LEFT_Y,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_Y, 0, 0 }
},
}
}
},
{
WiiExtensionController::WII_EXTENSION_CLASSIC,
{
{
{WiiButtons::WII_BUTTON_B, GAMEPAD_MASK_B1},
{WiiButtons::WII_BUTTON_A, GAMEPAD_MASK_B2},
{WiiButtons::WII_BUTTON_X, GAMEPAD_MASK_B4},
{WiiButtons::WII_BUTTON_Y, GAMEPAD_MASK_B3},
{WiiButtons::WII_BUTTON_L, GAMEPAD_MASK_L2},
{WiiButtons::WII_BUTTON_ZL, GAMEPAD_MASK_L1},
{WiiButtons::WII_BUTTON_R, GAMEPAD_MASK_R2},
{WiiButtons::WII_BUTTON_ZR, GAMEPAD_MASK_R1},
{WiiButtons::WII_BUTTON_MINUS, GAMEPAD_MASK_S1},
{WiiButtons::WII_BUTTON_PLUS, GAMEPAD_MASK_S2},
{WiiButtons::WII_BUTTON_HOME, GAMEPAD_MASK_A1},
{WiiButtons::WII_BUTTON_UP, GAMEPAD_MASK_DU},
{WiiButtons::WII_BUTTON_DOWN, GAMEPAD_MASK_DD},
{WiiButtons::WII_BUTTON_LEFT, GAMEPAD_MASK_DL},
{WiiButtons::WII_BUTTON_RIGHT, GAMEPAD_MASK_DR},
},
{
{
WiiAnalogs::WII_ANALOG_LEFT_X,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_X, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_LEFT_Y,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_Y, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_RIGHT_X,
{ WiiAnalogType::WII_ANALOG_TYPE_RIGHT_STICK_X, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_RIGHT_Y,
{ WiiAnalogType::WII_ANALOG_TYPE_RIGHT_STICK_Y, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_LEFT_TRIGGER,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_TRIGGER, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER,
{ WiiAnalogType::WII_ANALOG_TYPE_RIGHT_TRIGGER, 0, 0 }
},
}
}
},
{
WiiExtensionController::WII_EXTENSION_TAIKO,
{
{
{TaikoButtons::TATA_KAT_LEFT, GAMEPAD_MASK_L2},
{TaikoButtons::TATA_KAT_RIGHT, GAMEPAD_MASK_R2},
{TaikoButtons::TATA_DON_RIGHT, GAMEPAD_MASK_B1},
{TaikoButtons::TATA_DON_LEFT, GAMEPAD_MASK_DL},
},
{}
}
},
{
WiiExtensionController::WII_EXTENSION_GUITAR,
{
{
{GuitarButtons::GUITAR_RED, GAMEPAD_MASK_B2},
{GuitarButtons::GUITAR_GREEN, GAMEPAD_MASK_B1},
{GuitarButtons::GUITAR_YELLOW, GAMEPAD_MASK_B4},
{GuitarButtons::GUITAR_BLUE, GAMEPAD_MASK_B3},
{GuitarButtons::GUITAR_ORANGE, GAMEPAD_MASK_L2},
{GuitarButtons::GUITAR_PEDAL, GAMEPAD_MASK_R2},
{WiiButtons::WII_BUTTON_MINUS, GAMEPAD_MASK_S1},
{WiiButtons::WII_BUTTON_PLUS, GAMEPAD_MASK_S2},
{WiiButtons::WII_BUTTON_UP, GAMEPAD_MASK_DU},
{WiiButtons::WII_BUTTON_DOWN, GAMEPAD_MASK_DD},
},
{
{
WiiAnalogs::WII_ANALOG_LEFT_X,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_X, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_LEFT_Y,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_Y, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_RIGHT_X,
{ WiiAnalogType::WII_ANALOG_TYPE_RIGHT_STICK_X, 0, 0 }
},
}
}
},
{
WiiExtensionController::WII_EXTENSION_DRUMS,
{
{
{DrumButtons::DRUM_RED, GAMEPAD_MASK_B2},
{DrumButtons::DRUM_GREEN, GAMEPAD_MASK_B1},
{DrumButtons::DRUM_BLUE, GAMEPAD_MASK_B4},
{DrumButtons::DRUM_YELLOW, GAMEPAD_MASK_B3},
{DrumButtons::DRUM_ORANGE, GAMEPAD_MASK_L2},
{DrumButtons::DRUM_PEDAL, GAMEPAD_MASK_R2},
{WiiButtons::WII_BUTTON_MINUS, GAMEPAD_MASK_S1},
{WiiButtons::WII_BUTTON_PLUS, GAMEPAD_MASK_S2},
},
{
{
WiiAnalogs::WII_ANALOG_LEFT_X,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_X, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_LEFT_Y,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_Y, 0, 0 }
},
}
}
},
{
WiiExtensionController::WII_EXTENSION_TURNTABLE,
{
{
{TurntableButtons::TURNTABLE_RIGHT_GREEN, GAMEPAD_MASK_B3},
{TurntableButtons::TURNTABLE_RIGHT_RED, GAMEPAD_MASK_B4},
{TurntableButtons::TURNTABLE_RIGHT_BLUE, GAMEPAD_MASK_B2},
{TurntableButtons::TURNTABLE_EUPHORIA, GAMEPAD_MASK_R1},
{TurntableButtons::TURNTABLE_LEFT_GREEN, GAMEPAD_MASK_DL},
{TurntableButtons::TURNTABLE_LEFT_RED, GAMEPAD_MASK_DU},
{TurntableButtons::TURNTABLE_LEFT_BLUE, GAMEPAD_MASK_DR},
{WiiButtons::WII_BUTTON_MINUS, GAMEPAD_MASK_S1},
{WiiButtons::WII_BUTTON_PLUS, GAMEPAD_MASK_S2},
},
{
{
WiiAnalogs::WII_ANALOG_LEFT_X,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_X, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_LEFT_Y,
{ WiiAnalogType::WII_ANALOG_TYPE_LEFT_STICK_Y, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_RIGHT_X,
{ WiiAnalogType::WII_ANALOG_TYPE_RIGHT_STICK_X, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_RIGHT_Y,
{ WiiAnalogType::WII_ANALOG_TYPE_RIGHT_STICK_Y, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_LEFT_TRIGGER,
{ WiiAnalogType::WII_ANALOG_TYPE_RIGHT_STICK_X, 0, 0 }
},
{
WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER,
{ WiiAnalogType::WII_ANALOG_TYPE_RIGHT_STICK_X, 0, 0 }
},
}
}
},
};
WiiExtensionConfig* currentConfig = NULL;

bool buttonC = false;
bool buttonZ = false;

Expand All @@ -72,14 +298,56 @@ class WiiExtensionInput : public GPAddon {

uint16_t triggerLeft = 0;
uint16_t triggerRight = 0;
uint16_t lastTriggerLeft = 0;
uint16_t lastTriggerRight = 0;
uint16_t whammyBar = 0;

uint16_t leftX = 0;
uint16_t lastLeftX = 0;

uint16_t leftY = 0;
uint16_t lastLeftY = 0;

uint16_t rightX = 0;
uint16_t lastRightX = 0;

uint16_t rightY = 0;
uint16_t lastRightY = 0;

std::map<uint16_t, std::vector<WiiAnalogChange>> analogChanges = {
{WII_ANALOG_TYPE_LEFT_STICK_X,{}},
{WII_ANALOG_TYPE_LEFT_STICK_Y,{}},
{WII_ANALOG_TYPE_RIGHT_STICK_X,{}},
{WII_ANALOG_TYPE_RIGHT_STICK_Y,{}},
{WII_ANALOG_TYPE_DPAD_X,{}},
{WII_ANALOG_TYPE_DPAD_Y,{}},
{WII_ANALOG_TYPE_LEFT_TRIGGER,{}},
{WII_ANALOG_TYPE_RIGHT_TRIGGER,{}},

{WII_ANALOG_TYPE_LEFT_STICK_X_PLUS,{}},
{WII_ANALOG_TYPE_LEFT_STICK_X_MINUS,{}},
{WII_ANALOG_TYPE_LEFT_STICK_Y_PLUS,{}},
{WII_ANALOG_TYPE_LEFT_STICK_Y_MINUS,{}},
{WII_ANALOG_TYPE_RIGHT_STICK_X_PLUS,{}},
{WII_ANALOG_TYPE_RIGHT_STICK_X_MINUS,{}},
{WII_ANALOG_TYPE_RIGHT_STICK_Y_PLUS,{}},
{WII_ANALOG_TYPE_RIGHT_STICK_Y_MINUS,{}},
};

uint16_t map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max);
uint16_t bounds(uint16_t x, uint16_t out_min, uint16_t out_max);

void update();
void setControllerButton(uint16_t controllerID, uint16_t buttonID, uint32_t buttonMask);
void setControllerAnalog(uint16_t controllerID, uint16_t analogID, uint32_t axisType);
void setControllerStickMode(uint16_t controllerID, uint16_t analogID, uint32_t axisType);
void setButtonState(bool buttonState, uint16_t buttonMask);
void queueAnalogChange(uint16_t analogInput, uint16_t analogValue, uint16_t lastAnalogValue);
void updateAnalogState();
void reloadConfig();

uint16_t getAverage(std::vector<WiiAnalogChange> const& changes);
uint16_t getDelta(std::vector<uint16_t> const& changes, uint16_t baseValue);
};

#endif // _WIIExtensionAddon_H
4 changes: 4 additions & 0 deletions headers/gamepad/GamepadState.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
#define GAMEPAD_JOYSTICK_MID 0x7FFF
#define GAMEPAD_JOYSTICK_MAX 0xFFFF

#define GAMEPAD_TRIGGER_MIN 0
#define GAMEPAD_TRIGGER_MID 0x7F
#define GAMEPAD_TRIGGER_MAX 0xFF

/**
* @brief AUX defines --- gamepad state that doesn't translate to an output button/dpad/etc.
*/
Expand Down
17 changes: 12 additions & 5 deletions lib/WiiExtension/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
add_library(WiiExtension WiiExtension.cpp)
target_link_libraries(WiiExtension PUBLIC BitBang_I2C)
target_include_directories(WiiExtension INTERFACE .)
target_include_directories(WiiExtension PUBLIC
BitBang_I2C
add_library(WiiExtension
WiiExtension.cpp
extensions/ExtensionBase.cpp
extensions/ClassicExtension.cpp
extensions/DrumExtension.cpp
extensions/GuitarExtension.cpp
extensions/NunchuckExtension.cpp
extensions/TaikoExtension.cpp
extensions/TurntableExtension.cpp
)
target_link_libraries(WiiExtension PUBLIC pico_stdlib hardware_i2c)
target_include_directories(WiiExtension INTERFACE .)
target_include_directories(WiiExtension PUBLIC .)
Loading