diff --git a/docs/assets/images/gpc-add-ons-wii-extensions.png b/docs/assets/images/gpc-add-ons-wii-extensions.png index 5d504578b..88313c8cf 100644 Binary files a/docs/assets/images/gpc-add-ons-wii-extensions.png and b/docs/assets/images/gpc-add-ons-wii-extensions.png differ diff --git a/docs/web-configurator-add-ons.md b/docs/web-configurator-add-ons.md index 3a71bc4e2..f86d65902 100644 --- a/docs/web-configurator-add-ons.md +++ b/docs/web-configurator-add-ons.md @@ -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) diff --git a/headers/addons/wiiext.h b/headers/addons/wiiext.h index 823488f2e..3d7377367 100644 --- a/headers/addons/wiiext.h +++ b/headers/addons/wiiext.h @@ -2,6 +2,9 @@ #define _WIIExtensionAddon_H #include +#include +#include +#include #include #include #include "BoardConfig.h" @@ -37,18 +40,241 @@ #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 buttonMap; + std::unordered_map analogMap; +} WiiExtensionConfig; + +typedef struct { + uint16_t analogInput; + uint16_t analogValue; +} WiiAnalogChange; + class WiiExtensionInput : public GPAddon { public: - virtual bool available(); - virtual void setup(); // WiiExtension Setup - virtual void process(); // WiiExtension Process - virtual void preprocess() {} - virtual std::string name() { return WiiExtensionName; } + virtual bool available(); + virtual void setup(); // WiiExtension Setup + virtual void process(); // WiiExtension Process + virtual void preprocess() {} + virtual std::string name() { return WiiExtensionName; } private: WiiExtension * wii; uint32_t uIntervalMS; uint32_t nextTimer; + // controller ID = config + // defaults if no defined config + std::unordered_map 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; @@ -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> 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 const& changes); + uint16_t getDelta(std::vector const& changes, uint16_t baseValue); }; #endif // _WIIExtensionAddon_H diff --git a/headers/gamepad/GamepadState.h b/headers/gamepad/GamepadState.h index 9361eca6a..f48ec03f1 100644 --- a/headers/gamepad/GamepadState.h +++ b/headers/gamepad/GamepadState.h @@ -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. */ diff --git a/lib/WiiExtension/CMakeLists.txt b/lib/WiiExtension/CMakeLists.txt index 1048267f6..cc6c49c8c 100644 --- a/lib/WiiExtension/CMakeLists.txt +++ b/lib/WiiExtension/CMakeLists.txt @@ -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 .) diff --git a/lib/WiiExtension/README.md b/lib/WiiExtension/README.md index 1321909f7..f375f90eb 100644 --- a/lib/WiiExtension/README.md +++ b/lib/WiiExtension/README.md @@ -1,5 +1,4 @@ # WiiExtension -# Ported to BitBangI2C # # Written by: # Mike Parks diff --git a/lib/WiiExtension/WiiExtension.cpp b/lib/WiiExtension/WiiExtension.cpp index 8fa828008..6238cd306 100644 --- a/lib/WiiExtension/WiiExtension.cpp +++ b/lib/WiiExtension/WiiExtension.cpp @@ -45,23 +45,34 @@ void WiiExtension::start(){ if (idRead[5] == 0x00) { extensionType = WII_EXTENSION_NUNCHUCK; + extensionController = new NunchuckExtension(); } else if (idRead[5] == 0x01) { extensionType = WII_EXTENSION_CLASSIC; - if (idRead[0] == 0x01) { - extensionType = WII_EXTENSION_CLASSIC_PRO; - } + //if (idRead[0] == 0x01) { + // extensionType = WII_EXTENSION_CLASSIC_PRO; + //} + extensionController = new ClassicExtension(); } else if (idRead[5] == 0x03) { extensionType = WII_EXTENSION_GUITAR; if (idRead[0] == 0x01) { extensionType = WII_EXTENSION_DRUMS; + extensionController = new DrumExtension(); + } else if (idRead[0] == 0x03) { + extensionType = WII_EXTENSION_TURNTABLE; + extensionController = new TurntableExtension(); + } else { + extensionController = new GuitarExtension(); } } else if (idRead[5] == 0x11) { extensionType = WII_EXTENSION_TAIKO; + extensionController = new TaikoExtension(); } // in certain situations (eg. Nunchuck), setting the data type in reset() does not affect what this value will be dataType = idRead[4]; if (dataType == WII_DATA_TYPE_0) dataType = WII_DATA_TYPE_1; + extensionController->init(dataType); + extensionController->setExtensionType(extensionType); #if WII_EXTENSION_DEBUG==true printf("WiiExtension::Extension ID: %02x%02x %02x%02x %02x%02x\n", idRead[0], idRead[1], idRead[2], idRead[3], idRead[4], idRead[5]); @@ -69,192 +80,16 @@ void WiiExtension::start(){ #endif if (extensionType != WII_EXTENSION_NONE) { -#if WII_EXTENSION_DEBUG==true - //printf("Extension Type: %d\n", extensionType); -#endif - -#if WII_EXTENSION_DEBUG==true - printf("WiiExtension::Calibration Data\n"); -#endif - if (extensionType == WII_EXTENSION_NUNCHUCK) { - _analogPrecision1From = WII_ANALOG_PRECISION_2; - _analogPrecision1To = WII_ANALOG_PRECISION_3; - -#if WII_EXTENSION_CALIBRATION==true - // read calibration - regWrite[0] = 0x20; - doI2CWrite(regWrite, 1); - - doI2CRead(idRead, 16); - - _maxX1 = idRead[8]; - _minX1 = idRead[9]; - _cenX1 = idRead[10]; - - _maxY1 = idRead[11]; - _minY1 = idRead[12]; - _cenY1 = idRead[13]; - - _accelX0G = ((idRead[0] << 2) | ((idRead[3] >> 2) & 0x03)); - _accelY0G = ((idRead[1] << 2) | ((idRead[3] >> 4) & 0x03)); - _accelZ0G = ((idRead[2] << 2) | ((idRead[3] >> 6) & 0x03)); - - _accelX1G = ((idRead[4] << 2) | ((idRead[7] >> 2) & 0x03)); - _accelY1G = ((idRead[5] << 2) | ((idRead[7] >> 4) & 0x03)); - _accelZ1G = ((idRead[6] << 2) | ((idRead[7] >> 6) & 0x03)); - -#if WII_EXTENSION_DEBUG==true - //printf("Calibration:\n"); - //printf("X0G: %d\n", _accelX0G); - //printf("Y0G: %d\n", _accelY0G); - //printf("Z0G: %d\n", _accelZ0G); - //printf("X1G: %d\n", _accelX1G); - //printf("Y1G: %d\n", _accelY1G); - //printf("YZG: %d\n", _accelZ1G); - //printf("X Min: %d\n", _minX); - //printf("X Max: %d\n", _maxX); - //printf("X Center: %d\n", _cenX); - //printf("Y Min: %d\n", _minY); - //printf("Y Max: %d\n", _maxY); - //printf("Y Center: %d\n", _cenY); -#endif -#endif - } else { - if (dataType == WII_DATA_TYPE_1) { - _analogPrecision1From = WII_ANALOG_PRECISION_1; - _analogPrecision1To = WII_ANALOG_PRECISION_3; - _analogPrecision2From = WII_ANALOG_PRECISION_0; - _analogPrecision2To = WII_ANALOG_PRECISION_3; - - _triggerPrecision1From = WII_ANALOG_PRECISION_0; - _triggerPrecision1To = WII_ANALOG_PRECISION_2; - _triggerPrecision2From = WII_ANALOG_PRECISION_0; - _triggerPrecision2To = WII_ANALOG_PRECISION_2; - } else if (dataType == WII_DATA_TYPE_2) { - _analogPrecision1From = WII_ANALOG_PRECISION_3; - _analogPrecision1To = WII_ANALOG_PRECISION_3; - _analogPrecision2From = WII_ANALOG_PRECISION_3; - _analogPrecision2To = WII_ANALOG_PRECISION_3; - - _triggerPrecision1From = WII_ANALOG_PRECISION_2; - _triggerPrecision1To = WII_ANALOG_PRECISION_2; - _triggerPrecision2From = WII_ANALOG_PRECISION_2; - _triggerPrecision2To = WII_ANALOG_PRECISION_2; - } else if (dataType == WII_DATA_TYPE_3) { - _analogPrecision1From = WII_ANALOG_PRECISION_2; - _analogPrecision1To = WII_ANALOG_PRECISION_3; - _analogPrecision2From = WII_ANALOG_PRECISION_2; - _analogPrecision2To = WII_ANALOG_PRECISION_3; - - _triggerPrecision1From = WII_ANALOG_PRECISION_2; - _triggerPrecision1To = WII_ANALOG_PRECISION_2; - _triggerPrecision2From = WII_ANALOG_PRECISION_2; - _triggerPrecision2To = WII_ANALOG_PRECISION_2; - } - #if WII_EXTENSION_CALIBRATION==true - regWrite[0] = 0x20; - doI2CWrite(regWrite, 1); - - doI2CRead(idRead, 16); - - if (dataType == WII_DATA_TYPE_1) { - _calibrationPrecision1From = WII_ANALOG_PRECISION_2; - _calibrationPrecision1To = WII_ANALOG_PRECISION_1; - _calibrationPrecision2From = WII_ANALOG_PRECISION_2; - _calibrationPrecision2To = WII_ANALOG_PRECISION_0; - } else if (dataType == WII_DATA_TYPE_2) { - _calibrationPrecision1From = WII_ANALOG_PRECISION_2; - _calibrationPrecision1To = WII_ANALOG_PRECISION_3; - _calibrationPrecision2From = WII_ANALOG_PRECISION_2; - _calibrationPrecision2To = WII_ANALOG_PRECISION_3; - } else if (dataType == WII_DATA_TYPE_3) { - _calibrationPrecision1From = WII_ANALOG_PRECISION_2; - _calibrationPrecision1To = WII_ANALOG_PRECISION_2; - _calibrationPrecision2From = WII_ANALOG_PRECISION_2; - _calibrationPrecision2To = WII_ANALOG_PRECISION_2; - } - - _maxX1 = map(idRead[0],0,(_calibrationPrecision1From-1),0,(_calibrationPrecision1To-1)); - _minX1 = map(idRead[1],0,(_calibrationPrecision1From-1),0,(_calibrationPrecision1To-1)); - _cenX1 = map(idRead[2],0,(_calibrationPrecision1From-1),0,(_calibrationPrecision1To-1)); - - _maxY1 = map(idRead[3],0,(_calibrationPrecision1From-1),0,(_calibrationPrecision1To-1)); - _minY1 = map(idRead[4],0,(_calibrationPrecision1From-1),0,(_calibrationPrecision1To-1)); - _cenY1 = map(idRead[5],0,(_calibrationPrecision1From-1),0,(_calibrationPrecision1To-1)); - - _maxX2 = map(idRead[6],0,(_calibrationPrecision2From-1),0,(_calibrationPrecision2To-1)); - _minX2 = map(idRead[7],0,(_calibrationPrecision2From-1),0,(_calibrationPrecision2To-1)); - _cenX2 = map(idRead[8],0,(_calibrationPrecision2From-1),0,(_calibrationPrecision2To-1)); - - _maxY2 = map(idRead[9],0,(_calibrationPrecision2From-1),0,(_calibrationPrecision2To-1)); - _minY2 = map(idRead[10],0,(_calibrationPrecision2From-1),0,(_calibrationPrecision2To-1)); - _cenY2 = map(idRead[11],0,(_calibrationPrecision2From-1),0,(_calibrationPrecision2To-1)); - #if WII_EXTENSION_DEBUG==true - printf("X1 Min: %d\n", _minX1); - printf("X1 Max: %d\n", _maxX1); - printf("X1 Center: %d\n", _cenX1); - printf("Y1 Min: %d\n", _minY1); - printf("Y1 Max: %d\n", _maxY1); - printf("Y1 Center: %d\n", _cenY1); - printf("X2 Min: %d\n", _minX2); - printf("X2 Max: %d\n", _maxX2); - printf("X2 Center: %d\n", _cenX2); - printf("Y2 Min: %d\n", _minY2); - printf("Y2 Max: %d\n", _maxY2); - printf("Y2 Center: %d\n", _cenY2); + printf("WiiExtension::Calibration Data\n"); #endif + regWrite[0] = 0x20; + doI2CWrite(regWrite, 1); + + doI2CRead(idRead, 16); + extensionController->calibrate(idRead); #endif - } - - // reset to default input values in the event of a removal/hotswap - joy1X = 0; - joy1Y = 0; - joy2X = 0; - joy2Y = 0; - accelX = 0; - accelY = 0; - accelZ = 0; - - buttonZ = 0; - buttonC = 0; - buttonZR = 0; - buttonZL = 0; - buttonA = 0; - buttonB = 0; - buttonX = 0; - buttonY = 0; - buttonPlus = 0; - buttonHome = 0; - buttonMinus = 0; - buttonLT = 0; - buttonRT = 0; - - directionUp = 0; - directionDown = 0; - directionLeft = 0; - directionRight = 0; - - triggerLeft = 0; - triggerRight = 0; - - fretGreen = 0; - fretRed = 0; - fretYellow = 0; - fretBlue = 0; - fretOrange = 0; - pedalButton = 0; - - rimLeft = 0; - rimRight = 0; - drumLeft = 0; - drumRight = 0; - - whammyBar = 0; - touchBar = 0; - - _guitarType = WII_GUITAR_UNSET; } else { #if WII_EXTENSION_DEBUG==true printf("WiiExtension::Unknown Extension: %02x%02x %02x%02x %02x%02x\n", idRead[0], idRead[1], idRead[2], idRead[3], idRead[4], idRead[5]); @@ -271,15 +106,29 @@ void WiiExtension::reset(){ int8_t result; bool canContinue = true; +#if WII_EXTENSION_DEBUG==true + printf("WiiExtension::reset\n"); +#endif + if (canContinue) { result = doI2CTest(); canContinue = (result == 1); } #if WII_EXTENSION_DEBUG==true - printf("WiiExtension::reset\n"); + printf("WiiExtension::i2C tested? %1d\n", result); #endif +#if WII_EXTENSION_ENCRYPTION==true + if (canContinue) { + regWrite[0] = 0x40; + regWrite[1] = 0x00; + result = doI2CWrite(regWrite, 2); + canContinue = (result > -1); + } +#endif + +#if WII_EXTENSION_ENCRYPTION==false if (canContinue) { regWrite[0] = 0xF0; regWrite[1] = 0x55; @@ -287,12 +136,20 @@ void WiiExtension::reset(){ canContinue = (result > -1); } +#if WII_EXTENSION_DEBUG==true + printf("WiiExtension::reset 0xF0? %1d\n", result); +#endif + if (canContinue) { regWrite[0] = 0xFB; regWrite[1] = 0x00; result = doI2CWrite(regWrite, 2); canContinue = (result > -1); } +#if WII_EXTENSION_DEBUG==true + printf("WiiExtension::reset 0xFB? %1d\n", result); +#endif +#endif if (canContinue) { // set data format @@ -303,7 +160,7 @@ void WiiExtension::reset(){ } #if WII_EXTENSION_DEBUG==true - printf("WiiExtension::reset canContinue? %1d\n", canContinue); + printf("WiiExtension::reset 0xFE? %1d\n", result); #endif if (canContinue) { @@ -351,305 +208,21 @@ void WiiExtension::poll() { } if (result > 0) { - switch (extensionType) { - case WII_EXTENSION_NUNCHUCK: - joy1X = (regRead[0] & 0xFF); - joy1Y = (regRead[1] & 0xFF); - - accelX = (((regRead[2] << 2) | ((regRead[5] >> 2) & 0x03))); - accelY = (((regRead[3] << 2) | ((regRead[5] >> 4) & 0x03))); - accelZ = (((regRead[4] << 2) | ((regRead[5] >> 6) & 0x03))); - buttonZ = (!(regRead[5] & 0x01)); - buttonC = (!(regRead[5] & 0x02)); - -#if WII_EXTENSION_DEBUG==true - printf("Joy X=%4d Y=%4d Acc X=%4d Y=%4d Z=%4d Btn Z=%1d C=%1d\n", joy1X, joy1Y, accelX, accelY, accelZ, buttonZ, buttonC); -#endif - - break; - case WII_EXTENSION_CLASSIC: - case WII_EXTENSION_CLASSIC_PRO: - // write data format to return - // see wiki for data types - if (dataType == WII_DATA_TYPE_1) { - joy1X = (regRead[0] & 0x3F); - joy1Y = (regRead[1] & 0x3F); - joy2X = ((regRead[0] & 0xC0) >> 3) | ((regRead[1] & 0xC0) >> 5) | ((regRead[2] & 0x80) >> 7); - joy2Y = (regRead[2] & 0x1F); - - triggerLeft = (((regRead[2] & 0x60) >> 2) | ((regRead[3] & 0xE0) >> 5)); - triggerRight = ((regRead[3] & 0x1F) >> 0); - - directionRight = !((regRead[4] & 0x80) >> 7); - directionDown = !((regRead[4] & 0x40) >> 6); - buttonLT = !((regRead[4] & 0x20) >> 5); - buttonMinus = !((regRead[4] & 0x10) >> 4); - buttonHome = !((regRead[4] & 0x08) >> 3); - buttonPlus = !((regRead[4] & 0x04) >> 2); - buttonRT = !((regRead[4] & 0x02) >> 1); - - buttonZL = !((regRead[5] & 0x80) >> 7); - buttonB = !((regRead[5] & 0x40) >> 6); - buttonY = !((regRead[5] & 0x20) >> 5); - buttonA = !((regRead[5] & 0x10) >> 4); - buttonX = !((regRead[5] & 0x08) >> 3); - buttonZR = !((regRead[5] & 0x04) >> 2); - directionLeft = !((regRead[5] & 0x02) >> 1); - directionUp = !((regRead[5] & 0x01) >> 0); - } else if (dataType == WII_DATA_TYPE_2) { - joy1X = ((regRead[0] << 2) | ((regRead[4] & 0x03) >> 0)); - joy1Y = ((regRead[2] << 2) | ((regRead[4] & 0x30) >> 4)); - joy2X = ((regRead[1] << 2) | ((regRead[4] & 0x0C) >> 2)); - joy2Y = ((regRead[3] << 2) | ((regRead[4] & 0xC0) >> 6)); - - triggerLeft = (regRead[5] & 0xFF); - triggerRight = (regRead[6] & 0xFF); - - directionRight = !((regRead[7] & 0x80) >> 7); - directionDown = !((regRead[7] & 0x40) >> 6); - buttonLT = !((regRead[7] & 0x20) >> 5); - buttonMinus = !((regRead[7] & 0x10) >> 4); - buttonHome = !((regRead[7] & 0x08) >> 3); - buttonPlus = !((regRead[7] & 0x04) >> 2); - buttonRT = !((regRead[7] & 0x02) >> 1); - - buttonZL = !((regRead[8] & 0x80) >> 7); - buttonB = !((regRead[8] & 0x40) >> 6); - buttonY = !((regRead[8] & 0x20) >> 5); - buttonA = !((regRead[8] & 0x10) >> 4); - buttonX = !((regRead[8] & 0x08) >> 3); - buttonZR = !((regRead[8] & 0x04) >> 2); - directionLeft = !((regRead[8] & 0x02) >> 1); - directionUp = !((regRead[8] & 0x01) >> 0); - } else if (dataType == WII_DATA_TYPE_3) { - joy1X = (regRead[0] & 0xFF); - joy1Y = (regRead[2] & 0xFF); - joy2X = (regRead[1] & 0xFF); - joy2Y = (regRead[3] & 0xFF); - - triggerLeft = (regRead[4] & 0xFF); - triggerRight = (regRead[5] & 0xFF); - - directionRight = !((regRead[6] & 0x80) >> 7); - directionDown = !((regRead[6] & 0x40) >> 6); - buttonLT = !((regRead[6] & 0x20) >> 5); - buttonMinus = !((regRead[6] & 0x10) >> 4); - buttonHome = !((regRead[6] & 0x08) >> 3); - buttonPlus = !((regRead[6] & 0x04) >> 2); - buttonRT = !((regRead[6] & 0x02) >> 1); - - buttonZL = !((regRead[7] & 0x80) >> 7); - buttonB = !((regRead[7] & 0x40) >> 6); - buttonY = !((regRead[7] & 0x20) >> 5); - buttonA = !((regRead[7] & 0x10) >> 4); - buttonX = !((regRead[7] & 0x08) >> 3); - buttonZR = !((regRead[7] & 0x04) >> 2); - directionLeft = !((regRead[7] & 0x02) >> 1); - directionUp = !((regRead[7] & 0x01) >> 0); - } else { - // unknown - } - -#if WII_EXTENSION_DEBUG==true - //if ((_lastRead[0] != regRead[0]) || (_lastRead[1] != regRead[1]) || (_lastRead[2] != regRead[2]) || (_lastRead[3] != regRead[3])) { - printf("Joy1 X=%4d Y=%4d Joy2 X=%4d Y=%4d\n", joy1X, joy1Y, joy2X, joy2Y); - //} - //printf("Joy1 X=%4d Y=%4d Joy2 X=%4d Y=%4d U=%1d D=%1d L=%1d R=%1d TL=%4d TR=%4d\n", joy1X, joy1Y, joy2X, joy2Y, directionUp, directionDown, directionLeft, directionRight, triggerLeft, triggerRight); - //printf("A=%1d B=%1d X=%1d Y=%1d ZL=%1d ZR=%1d LT=%1d RT=%1d -=%1d H=%1d +=%1d\n", buttonA, buttonB, buttonX, buttonY, buttonZL, buttonZR, buttonLT, buttonRT, buttonMinus, buttonHome, buttonPlus); -#endif + extensionController->process(regRead); + extensionController->postProcess(); - break; - case WII_EXTENSION_GUITAR: - // on first read, check the status of the guitar flag - if (_guitarType == WII_GUITAR_UNSET) { - if (((regRead[0] & 0x80) >> 7) == 0) { - _guitarType = WII_GUITAR_GHWT; - } else { - _guitarType = WII_GUITAR_GH3; - } - // force the data type to 1 when a World Tour guitar is detected - if ((_guitarType == WII_GUITAR_GHWT) && (dataType != WII_DATA_TYPE_1)) { - dataType = WII_DATA_TYPE_1; - _analogPrecision1From = WII_ANALOG_PRECISION_1; - _analogPrecision1To = WII_ANALOG_PRECISION_3; - _analogPrecision2From = WII_ANALOG_PRECISION_0; - _analogPrecision2To = WII_ANALOG_PRECISION_3; - } - } - if (_guitarType != WII_GUITAR_UNSET) { - // as defined works for GH3 guitar - if (dataType == WII_DATA_TYPE_1) { - joy1X = (regRead[0] & 0x3F); - joy1Y = (regRead[1] & 0x3F); - - touchBar = ((_guitarType == WII_GUITAR_GHWT) ? (regRead[2] & 0x1F) : 0); - - whammyBar = (regRead[3] & 0x1F); - joy2X = (regRead[3] & 0x1F); - - directionDown = !((regRead[4] & 0x40) >> 6); - buttonMinus = !((regRead[4] & 0x10) >> 4); - buttonPlus = !((regRead[4] & 0x04) >> 2); - - fretOrange = !((regRead[5] & 0x80) >> 7); - fretRed = !((regRead[5] & 0x40) >> 6); - fretBlue = !((regRead[5] & 0x20) >> 5); - fretGreen = !((regRead[5] & 0x10) >> 4); - fretYellow = !((regRead[5] & 0x08) >> 3); - pedalButton = !((regRead[5] & 0x04) >> 2); - directionUp = !((regRead[5] & 0x01) >> 0); - - isTouched = (touchBar != WII_GUITAR_TOUCHPAD_NONE); - - // process the touch bar for button states - // touch only seems to exist in GHWT, and GHWT always reports data type 1 format regardless of setting - if (isTouched) { - // touched - fretGreen = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_GREEN,WII_GUITAR_TOUCHPAD_RED)); - fretRed = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_RED,WII_GUITAR_TOUCHPAD_YELLOW)); - fretYellow = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_YELLOW,WII_GUITAR_TOUCHPAD_BLUE)); - fretBlue = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_BLUE,WII_GUITAR_TOUCHPAD_ORANGE)); - fretOrange = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_ORANGE,WII_GUITAR_TOUCHPAD_MAX)); - directionDown = isTouched; - } - } else if (dataType == WII_DATA_TYPE_2) { - joy1X = ((regRead[0] << 2) | ((regRead[4] & 0x03) >> 0)); - joy1Y = ((regRead[2] << 2) | ((regRead[4] & 0x30) >> 4)); - - touchBar = 0; - - whammyBar = (regRead[6] & 0xFF); - joy2X = (regRead[6] & 0xFF); - - directionDown = !((regRead[7] & 0x40) >> 6); - buttonMinus = !((regRead[7] & 0x10) >> 4); - buttonPlus = !((regRead[7] & 0x04) >> 2); - - fretOrange = !((regRead[8] & 0x80) >> 7); - fretRed = !((regRead[8] & 0x40) >> 6); - fretBlue = !((regRead[8] & 0x20) >> 5); - fretGreen = !((regRead[8] & 0x10) >> 4); - fretYellow = !((regRead[8] & 0x08) >> 3); - pedalButton = !((regRead[8] & 0x04) >> 2); - directionUp = !((regRead[8] & 0x01) >> 0); - } else if (dataType == WII_DATA_TYPE_3) { - joy1X = (regRead[0] & 0xFF); - joy1Y = (regRead[2] & 0xFF); - - touchBar = 0; - - whammyBar = (regRead[5] & 0xFF); - joy2X = (regRead[5] & 0xFF); - - directionDown = !((regRead[6] & 0x40) >> 6); - buttonMinus = !((regRead[6] & 0x10) >> 4); - buttonPlus = !((regRead[6] & 0x04) >> 2); - - fretOrange = !((regRead[7] & 0x80) >> 7); - fretRed = !((regRead[7] & 0x40) >> 6); - fretBlue = !((regRead[7] & 0x20) >> 5); - fretGreen = !((regRead[7] & 0x10) >> 4); - fretYellow = !((regRead[7] & 0x08) >> 3); - pedalButton = !((regRead[7] & 0x04) >> 2); - directionUp = !((regRead[7] & 0x01) >> 0); - } - } #if WII_EXTENSION_DEBUG==true -// printf("Joy1 X=%4d Y=%4d Whammy=%4d U=%1d D=%1d -=%1d +=%1d\n", joy1X, joy1Y, whammyBar, directionUp, directionDown, buttonMinus, buttonPlus); -// printf("Joy1 X=%4d Y=%4d Whammy=%4d U=%1d D=%1d -=%1d +=%1d\n", joy1X, joy1Y, whammyBar, directionUp, directionDown, buttonMinus, buttonPlus); -// printf("O=%1d B=%1d Y=%1d R=%1d G=%1d\n", fretOrange, fretBlue, fretYellow, fretRed, fretGreen); -#endif - break; - case WII_EXTENSION_TAIKO: - if (dataType == WII_DATA_TYPE_1) { - drumLeft = !((regRead[5] & 0x40) >> 6); - rimLeft = !((regRead[5] & 0x20) >> 5); - drumRight = !((regRead[5] & 0x10) >> 4); - rimRight = !((regRead[5] & 0x08) >> 3); - } else if (dataType == WII_DATA_TYPE_2) { - drumLeft = !((regRead[8] & 0x40) >> 6); - rimLeft = !((regRead[8] & 0x20) >> 5); - drumRight = !((regRead[8] & 0x10) >> 4); - rimRight = !((regRead[8] & 0x08) >> 3); - } else if (dataType == WII_DATA_TYPE_3) { - drumLeft = !((regRead[7] & 0x40) >> 6); - rimLeft = !((regRead[7] & 0x20) >> 5); - drumRight = !((regRead[7] & 0x10) >> 4); - rimRight = !((regRead[7] & 0x08) >> 3); - } - -#if WII_EXTENSION_DEBUG==true - //if (_lastRead[0] != regRead[0]) printf("Byte0 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[0])); - //if (_lastRead[1] != regRead[1]) printf("Byte1 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[1])); - //if (_lastRead[2] != regRead[2]) printf("Byte2 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[2])); - //if (_lastRead[3] != regRead[3]) printf("Byte3 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[3])); - //if (_lastRead[4] != regRead[4]) printf("Byte4 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[4])); - //if (_lastRead[5] != regRead[5]) printf("Byte5 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[5])); - // - //if (_lastRead[7] != regRead[7]) { - // printf("DL=%1d RL=%1d DR=%1d RR=%1d\n", drumLeft, rimLeft, drumRight, rimRight); - //} -#endif - - break; - } - - // calibrate and remap - joy1X = map( - calibrate(joy1X, _minX1, _maxX1, _cenX1), - 0+_minX1, - (_analogPrecision1From-_maxX1), - 0, - (_analogPrecision1To-1) - ); - joy1Y = map( - calibrate(joy1Y, _minY1, _maxY1, _cenY1), - 0+_minY1, - (_analogPrecision1From-_maxY1), - 0, - (_analogPrecision1To-1) - ); - - joy2X = map( - calibrate(joy2X, _minX2, _maxX2, _cenX2), - 0+_minX2, - (_analogPrecision2From-_maxX2), - 0, - (_analogPrecision2To-1) - ); - joy2Y = map( - calibrate(joy2Y, _minY2, _maxY2, _cenY2), - 0+_minY2, - (_analogPrecision2From-_maxY2), - 0, - (_analogPrecision2To-1) - ); - - triggerLeft = map( - triggerLeft, - 0, - (_triggerPrecision1From-1), - 0, - (_triggerPrecision1To-1) - ); - triggerRight = map( - triggerRight, - 0, - (_triggerPrecision2From-1), - 0, - (_triggerPrecision2To-1) - ); - -#if WII_EXTENSION_DEBUG==true - //if ((_lastRead[0] != regRead[0]) || (_lastRead[1] != regRead[1]) || (_lastRead[2] != regRead[2]) || (_lastRead[3] != regRead[3])) { - // printf("Joy1 X=%4d Y=%4d Joy2 X=%4d Y=%4d\n", joy1X, joy1Y, joy2X, joy2Y); - //} - //printf("Joy1 X=%4d Y=%4d Joy2 X=%4d Y=%4d U=%1d D=%1d L=%1d R=%1d TL=%4d TR=%4d\n", joy1X, joy1Y, joy2X, joy2Y, directionUp, directionDown, directionLeft, directionRight, triggerLeft, triggerRight); - //printf("A=%1d B=%1d X=%1d Y=%1d ZL=%1d ZR=%1d LT=%1d RT=%1d -=%1d H=%1d +=%1d\n", buttonA, buttonB, buttonX, buttonY, buttonZL, buttonZR, buttonLT, buttonRT, buttonMinus, buttonHome, buttonPlus); for (int i = 0; i < result; ++i) { _lastRead[i] = regRead[i]; } #endif + + if (extensionType == WII_EXTENSION_TURNTABLE) { + regWrite[0] = 0xFB; + regWrite[1] = ((TurntableExtension*)extensionController)->getLED(); + result = doI2CWrite(regWrite, 2); + } + // continue poll regWrite[0] = 0x00; result = doI2CWrite(regWrite, 1); @@ -665,32 +238,6 @@ void WiiExtension::poll() { } } -uint16_t WiiExtension::map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} - -uint16_t WiiExtension::calibrate(uint16_t pos, uint16_t min, uint16_t max, uint16_t cen) { - uint16_t result; - -#if WII_EXTENSION_CALIBRATION==true - if (pos >= min && pos <= max) { - result = pos; - } else { - if (pos < min) { - result = min; - } else if (pos > max) { - result = max; - } else { - result = cen; - } - } -#else - result = pos; -#endif - - return result; -} - int WiiExtension::doI2CWrite(uint8_t *pData, int iLen) { int result = i2c_write_blocking(picoI2C, address, pData, iLen, false); waitUntil_us(WII_EXTENSION_DELAY); @@ -700,23 +247,32 @@ int WiiExtension::doI2CWrite(uint8_t *pData, int iLen) { int WiiExtension::doI2CRead(uint8_t *pData, int iLen) { int result = i2c_read_blocking(picoI2C, address, pData, iLen, false); waitUntil_us(WII_EXTENSION_DELAY); +#if WII_EXTENSION_ENCRYPTION==true + for (int i = 0; i < iLen; ++i) { + pData[i] = WII_DECRYPT_BYTE(pData[i]); + } +#endif return result; } uint8_t WiiExtension::doI2CTest() { - int result; + int result; uint8_t rxdata; result = doI2CRead(&rxdata, 1); +#if WII_EXTENSION_DEBUG==true + printf("WiiExtension::doI2CTest: %d\n", result); +#endif return (result >= 0); } void WiiExtension::doI2CInit() { - if ((iSDA + 2 * i2c_hw_index(picoI2C))%4 != 0) return; - if ((iSCL + 3 + 2 * i2c_hw_index(picoI2C))%4 != 0) return; + if ((iSDA + 2 * i2c_hw_index(picoI2C))%4 != 0) return; + if ((iSCL + 3 + 2 * i2c_hw_index(picoI2C))%4 != 0) return; i2c_init(picoI2C, iSpeed); gpio_set_function(iSDA, GPIO_FUNC_I2C); gpio_set_function(iSCL, GPIO_FUNC_I2C); + gpio_pull_up(iSDA); gpio_pull_up(iSCL); diff --git a/lib/WiiExtension/WiiExtension.h b/lib/WiiExtension/WiiExtension.h index fd0626f39..b3ee39113 100644 --- a/lib/WiiExtension/WiiExtension.h +++ b/lib/WiiExtension/WiiExtension.h @@ -7,18 +7,24 @@ #include "pico/stdlib.h" #include "hardware/i2c.h" -#define WII_EXTENSION_NONE -1 -#define WII_EXTENSION_NUNCHUCK 0 -#define WII_EXTENSION_CLASSIC 1 -#define WII_EXTENSION_CLASSIC_PRO 2 -#define WII_EXTENSION_DRAWSOME 3 -#define WII_EXTENSION_GUITAR 4 -#define WII_EXTENSION_DRUMS 5 -#define WII_EXTENSION_TURNTABLE 6 -#define WII_EXTENSION_TAIKO 7 -#define WII_EXTENSION_UDRAW 8 -#define WII_EXTENSION_BALANCE_BOARD 9 -#define WII_EXTENSION_MOTION_PLUS 10 +#include "extensions/Extensions.h" + +#define WII_EXTENSION_NONE -1 + +typedef enum { + WII_EXTENSION_NUNCHUCK, + WII_EXTENSION_CLASSIC, + WII_EXTENSION_CLASSIC_PRO, + WII_EXTENSION_GUITAR, + WII_EXTENSION_DRUMS, + WII_EXTENSION_TURNTABLE, + WII_EXTENSION_TAIKO, + WII_EXTENSION_TRAIN, + WII_EXTENSION_DRAWSOME, + WII_EXTENSION_UDRAW, + WII_EXTENSION_MOTION_PLUS, + WII_EXTENSION_COUNT +} WiiExtensionController; #define WII_DATA_TYPE_0 0 #define WII_DATA_TYPE_1 1 @@ -52,6 +58,11 @@ #define WII_EXTENSION_DEBUG false #endif +#ifndef WII_EXTENSION_ENCRYPTION +// if a device acts funny with "unencrypted" mode, enable this. used in very rare cases. +#define WII_EXTENSION_ENCRYPTION false +#endif + #ifndef WII_EXTENSION_DELAY #define WII_EXTENSION_DELAY 300 #endif @@ -61,12 +72,16 @@ #endif #ifndef WII_EXTENSION_CALIBRATION -#define WII_EXTENSION_CALIBRATION false +#define WII_EXTENSION_CALIBRATION true #endif #define WII_ALARM_NUM 0 #define WII_ALARM_IRQ TIMER_IRQ_0 +#define WII_CHECKSUM_MAGIC 0x55 +#define WII_CALIBRATION_SIZE 0x10 +#define WII_CALIBRATION_CHECKSUM_SIZE 0x02 + static volatile bool WiiExtension_alarmFired; #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" @@ -81,123 +96,38 @@ static volatile bool WiiExtension_alarmFired; ((byte) & 0x01 ? '1' : '0') #define TOUCH_BETWEEN_RANGE(val,beg,end) (((val) >= ((beg)-WII_GUITAR_TOUCHPAD_OVERLAP)) && ((val) < (end))) +#define WII_DECRYPT_BYTE(x) (((x) ^ 0x17) + 0x17) class WiiExtension { protected: - uint8_t address; + uint8_t address; public: int8_t extensionType = WII_EXTENSION_NONE; int8_t dataType = WII_DATA_TYPE_0; - uint16_t joy1X = 0; - uint16_t joy1Y = 0; - uint16_t joy2X = 0; - uint16_t joy2Y = 0; - uint16_t accelX = 0; - uint16_t accelY = 0; - uint16_t accelZ = 0; - - bool buttonZ = false; - bool buttonC = false; - bool buttonZR = false; - bool buttonZL = false; - bool buttonA = false; - bool buttonB = false; - bool buttonX = false; - bool buttonY = false; - bool buttonPlus = false; - bool buttonHome = false; - bool buttonMinus = false; - bool buttonLT = false; - bool buttonRT = false; - - bool directionUp = false; - bool directionDown = false; - bool directionLeft = false; - bool directionRight = false; - - uint16_t triggerLeft = 0; - uint16_t triggerRight = 0; - - bool fretGreen = false; - bool fretRed = false; - bool fretYellow = false; - bool fretBlue = false; - bool fretOrange = false; - bool pedalButton = false; - - uint16_t whammyBar = 0; - int8_t touchBar = 0; - bool isTouched = 0; - - bool rimLeft = false; - bool rimRight = false; - bool drumLeft = false; - bool drumRight = false; - bool isReady = false; // Constructor - WiiExtension(int sda, int scl, i2c_inst_t *i2cCtl, int32_t speed, uint8_t addr); + WiiExtension(int sda, int scl, i2c_inst_t *i2cCtl, int32_t speed, uint8_t addr); // Methods void begin(); - void reset(); - void start(); - void poll(); + void reset(); + void start(); + void poll(); + + ExtensionBase* getController() { return extensionController; }; private: - + ExtensionBase *extensionController = NULL; + uint8_t iSDA; uint8_t iSCL; - uint8_t bWire; i2c_inst_t *picoI2C; + int32_t iSpeed; - int32_t iSpeed; - - uint16_t _minX1 = 0; - uint16_t _maxX1 = 1; - uint16_t _cenX1 = 0; - - uint16_t _minY1 = 0; - uint16_t _maxY1 = 1; - uint16_t _cenY1 = 0; - - uint16_t _minX2 = 0; - uint16_t _maxX2 = 1; - uint16_t _cenX2 = 0; - - uint16_t _minY2 = 0; - uint16_t _maxY2 = 1; - uint16_t _cenY2 = 0; - - uint16_t _accelX0G = 0; - uint16_t _accelY0G = 0; - uint16_t _accelZ0G = 0; - uint16_t _accelX1G = 0; - uint16_t _accelY1G = 0; - uint16_t _accelZ1G = 0; - - //uint8_t _lastRead[16]; - - uint16_t _calibrationPrecision1From = WII_ANALOG_PRECISION_0; - uint16_t _calibrationPrecision1To = WII_ANALOG_PRECISION_0; - uint16_t _calibrationPrecision2From = WII_ANALOG_PRECISION_0; - uint16_t _calibrationPrecision2To = WII_ANALOG_PRECISION_0; - - uint16_t _analogPrecision1From = WII_ANALOG_PRECISION_0; - uint16_t _analogPrecision1To = WII_ANALOG_PRECISION_0; - uint16_t _analogPrecision2From = WII_ANALOG_PRECISION_0; - uint16_t _analogPrecision2To = WII_ANALOG_PRECISION_0; - - uint16_t _triggerPrecision1From = WII_ANALOG_PRECISION_0; - uint16_t _triggerPrecision1To = WII_ANALOG_PRECISION_0; - uint16_t _triggerPrecision2From = WII_ANALOG_PRECISION_0; - uint16_t _triggerPrecision2To = WII_ANALOG_PRECISION_0; - - uint8_t _guitarType = WII_GUITAR_UNSET; - - uint16_t map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max); - uint16_t calibrate(uint16_t pos, uint16_t min, uint16_t max, uint16_t center); +#if WII_EXTENSION_DEBUG==true + uint8_t _lastRead[16] = {0xFF}; +#endif int doI2CWrite(uint8_t *pData, int iLen); int doI2CRead(uint8_t *pData, int iLen); diff --git a/lib/WiiExtension/extensions/ClassicExtension.cpp b/lib/WiiExtension/extensions/ClassicExtension.cpp new file mode 100644 index 000000000..c12a46507 --- /dev/null +++ b/lib/WiiExtension/extensions/ClassicExtension.cpp @@ -0,0 +1,210 @@ +#include "ExtensionBase.h" +#include "ClassicExtension.h" + +#include "WiiExtension.h" + +void ClassicExtension::init(uint8_t dataType) { + ExtensionBase::init(dataType); + if (getDataType() == WII_DATA_TYPE_1) { + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].destination = WII_ANALOG_PRECISION_3; + + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination = WII_ANALOG_PRECISION_3; + } else if (getDataType() == WII_DATA_TYPE_2) { + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].origin = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].origin = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].destination = WII_ANALOG_PRECISION_3; + + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination = WII_ANALOG_PRECISION_3; + } else if (getDataType() == WII_DATA_TYPE_3) { + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].destination = WII_ANALOG_PRECISION_3; + + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination = WII_ANALOG_PRECISION_3; + } + + // preseed calibration data with max ranges + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].minimum = WII_CLASSIC_ANALOG_GAP; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].center = WII_CLASSIC_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].maximum = WII_CLASSIC_GATE_CENTER+WII_CLASSIC_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].minimum = WII_CLASSIC_ANALOG_GAP; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].center = WII_CLASSIC_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].maximum = WII_CLASSIC_GATE_CENTER+WII_CLASSIC_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].minimum = WII_CLASSIC_ANALOG_GAP; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].center = WII_CLASSIC_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].maximum = WII_CLASSIC_GATE_CENTER+WII_CLASSIC_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].minimum = WII_CLASSIC_ANALOG_GAP; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].center = WII_CLASSIC_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].maximum = WII_CLASSIC_GATE_CENTER+WII_CLASSIC_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].minimum = 1; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].center = WII_CLASSIC_TRIGGER_MAX/2; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].maximum = WII_CLASSIC_TRIGGER_MAX; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].minimum = 1; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].center = WII_CLASSIC_TRIGGER_MAX/2; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].maximum = WII_CLASSIC_TRIGGER_MAX; +} + +bool ClassicExtension::calibrate(uint8_t *calibrationData) { +#if WII_EXTENSION_CALIBRATION==true + if (ExtensionBase::calibrate(calibrationData)) { + // calibration passed checksum + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].maximum = calibrationData[0]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].minimum = calibrationData[1]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].center = calibrationData[2]; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].maximum = calibrationData[3]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].minimum = calibrationData[4]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].center = calibrationData[5]; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].maximum = calibrationData[6]; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].minimum = calibrationData[7]; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].center = calibrationData[8]; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].maximum = calibrationData[9]; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].minimum = calibrationData[10]; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].center = calibrationData[11]; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].maximum = calibrationData[12]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].minimum = 1; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].center = calibrationData[12]/2; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].maximum = calibrationData[13]; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].minimum = 1; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].center = calibrationData[12]/2; + return true; + } else { + } +#endif + return false; +} + +void ClassicExtension::process(uint8_t *inputData) { + // write data format to return + // see wiki for data types + if (getDataType() == WII_DATA_TYPE_1) { + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = (inputData[0] & 0x3F); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = (inputData[1] & 0x3F); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_X] = ((inputData[0] & 0xC0) >> 3) | ((inputData[1] & 0xC0) >> 5) | ((inputData[2] & 0x80) >> 7); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_Y] = (inputData[2] & 0x1F); + + analogState[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER] = (((inputData[2] & 0x60) >> 2) | ((inputData[3] & 0xE0) >> 5)); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER] = ((inputData[3] & 0x1F) >> 0); + + buttons[WiiButtons::WII_BUTTON_RIGHT] = !((inputData[4] & 0x80) >> 7); + buttons[WiiButtons::WII_BUTTON_DOWN] = !((inputData[4] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_L] = !((inputData[4] & 0x20) >> 5); + buttons[WiiButtons::WII_BUTTON_MINUS] = !((inputData[4] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_HOME] = !((inputData[4] & 0x08) >> 3); + buttons[WiiButtons::WII_BUTTON_PLUS] = !((inputData[4] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_R] = !((inputData[4] & 0x02) >> 1); + + buttons[WiiButtons::WII_BUTTON_ZL] = !((inputData[5] & 0x80) >> 7); + buttons[WiiButtons::WII_BUTTON_B] = !((inputData[5] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_Y] = !((inputData[5] & 0x20) >> 5); + buttons[WiiButtons::WII_BUTTON_A] = !((inputData[5] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_X] = !((inputData[5] & 0x08) >> 3); + buttons[WiiButtons::WII_BUTTON_ZR] = !((inputData[5] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_LEFT] = !((inputData[5] & 0x02) >> 1); + buttons[WiiButtons::WII_BUTTON_UP] = !((inputData[5] & 0x01) >> 0); + } else if (getDataType() == WII_DATA_TYPE_2) { + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = ((inputData[0] << 2) | ((inputData[4] & 0x03) >> 0)); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = ((inputData[2] << 2) | ((inputData[4] & 0x30) >> 4)); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_X] = ((inputData[1] << 2) | ((inputData[4] & 0x0C) >> 2)); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_Y] = ((inputData[3] << 2) | ((inputData[4] & 0xC0) >> 6)); + + analogState[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER] = (inputData[5] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER] = (inputData[6] & 0xFF); + + buttons[WiiButtons::WII_BUTTON_RIGHT] = !((inputData[7] & 0x80) >> 7); + buttons[WiiButtons::WII_BUTTON_DOWN] = !((inputData[7] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_L] = !((inputData[7] & 0x20) >> 5); + buttons[WiiButtons::WII_BUTTON_MINUS] = !((inputData[7] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_HOME] = !((inputData[7] & 0x08) >> 3); + buttons[WiiButtons::WII_BUTTON_PLUS] = !((inputData[7] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_R] = !((inputData[7] & 0x02) >> 1); + + buttons[WiiButtons::WII_BUTTON_ZL] = !((inputData[8] & 0x80) >> 7); + buttons[WiiButtons::WII_BUTTON_B] = !((inputData[8] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_Y] = !((inputData[8] & 0x20) >> 5); + buttons[WiiButtons::WII_BUTTON_A] = !((inputData[8] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_X] = !((inputData[8] & 0x08) >> 3); + buttons[WiiButtons::WII_BUTTON_ZR] = !((inputData[8] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_LEFT] = !((inputData[8] & 0x02) >> 1); + buttons[WiiButtons::WII_BUTTON_UP] = !((inputData[8] & 0x01) >> 0); + } else if (getDataType() == WII_DATA_TYPE_3) { + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = (inputData[0] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = (inputData[2] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_X] = (inputData[1] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_Y] = (inputData[3] & 0xFF); + + analogState[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER] = (inputData[4] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER] = (inputData[5] & 0xFF); + + buttons[WiiButtons::WII_BUTTON_RIGHT] = !((inputData[6] & 0x80) >> 7); + buttons[WiiButtons::WII_BUTTON_DOWN] = !((inputData[6] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_L] = !((inputData[6] & 0x20) >> 5); + buttons[WiiButtons::WII_BUTTON_MINUS] = !((inputData[6] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_HOME] = !((inputData[6] & 0x08) >> 3); + buttons[WiiButtons::WII_BUTTON_PLUS] = !((inputData[6] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_R] = !((inputData[6] & 0x02) >> 1); + + buttons[WiiButtons::WII_BUTTON_ZL] = !((inputData[7] & 0x80) >> 7); + buttons[WiiButtons::WII_BUTTON_B] = !((inputData[7] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_Y] = !((inputData[7] & 0x20) >> 5); + buttons[WiiButtons::WII_BUTTON_A] = !((inputData[7] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_X] = !((inputData[7] & 0x08) >> 3); + buttons[WiiButtons::WII_BUTTON_ZR] = !((inputData[7] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_LEFT] = !((inputData[7] & 0x02) >> 1); + buttons[WiiButtons::WII_BUTTON_UP] = !((inputData[7] & 0x01) >> 0); + } else { + // unknown + } + +#if WII_EXTENSION_DEBUG==true + //if ((_lastRead[0] != inputData[0]) || (_lastRead[1] != inputData[1]) || (_lastRead[2] != inputData[2]) || (_lastRead[3] != inputData[3])) { + // printf("Joy1 X=%4d Y=%4d Joy2 X=%4d Y=%4d\n", joy1X, joy1Y, joy2X, joy2Y); + //} + //printf("Joy1 X=%5d Y=%5d Joy2 X=%5d Y=%5d U=%1d D=%1d L=%1d R=%1d TL=%5d TR=%5d\n", analogState[WiiAnalogs::ANALOG_LEFT_X], analogState[WiiAnalogs::ANALOG_LEFT_Y], analogState[WiiAnalogs::ANALOG_RIGHT_X], analogState[WiiAnalogs::ANALOG_RIGHT_Y], directionalPad[WiiDirectionalPad::DIRECTION_UP], directionalPad[WiiDirectionalPad::DIRECTION_DOWN], directionalPad[WiiDirectionalPad::DIRECTION_LEFT], directionalPad[WiiDirectionalPad::DIRECTION_RIGHT], analogState[WiiAnalogs::ANALOG_TRIGGER_LEFT], analogState[WiiAnalogs::ANALOG_TRIGGER_RIGHT]); + //printf("A=%1d B=%1d X=%1d Y=%1d ZL=%1d ZR=%1d LT=%1d RT=%1d -=%1d H=%1d +=%1d\n", buttonA, buttonB, buttonX, buttonY, buttonZL, buttonZR, buttonLT, buttonRT, buttonMinus, buttonHome, buttonPlus); +#endif +} \ No newline at end of file diff --git a/lib/WiiExtension/extensions/ClassicExtension.h b/lib/WiiExtension/extensions/ClassicExtension.h new file mode 100644 index 000000000..c2b33f375 --- /dev/null +++ b/lib/WiiExtension/extensions/ClassicExtension.h @@ -0,0 +1,18 @@ +#ifndef _CLASSICEXTENSION_H_ +#define _CLASSICEXTENSION_H_ + +#include "ExtensionBase.h" + +#define WII_CLASSIC_GATE_SIZE 97 +#define WII_CLASSIC_GATE_CENTER 128 +#define WII_CLASSIC_TRIGGER_MAX 32 +#define WII_CLASSIC_ANALOG_GAP (WII_CLASSIC_GATE_CENTER-WII_CLASSIC_GATE_SIZE) + +class ClassicExtension : public ExtensionBase { + public: + void init(uint8_t dataType) override; + bool calibrate(uint8_t *calibrationData) override; + void process(uint8_t *inputData) override; +}; + +#endif \ No newline at end of file diff --git a/lib/WiiExtension/extensions/DrumExtension.cpp b/lib/WiiExtension/extensions/DrumExtension.cpp new file mode 100644 index 000000000..481100325 --- /dev/null +++ b/lib/WiiExtension/extensions/DrumExtension.cpp @@ -0,0 +1,32 @@ +#include "ExtensionBase.h" +#include "DrumExtension.h" + +#include "WiiExtension.h" + +void DrumExtension::process(uint8_t *inputData) { + // drums accept three data modes, but will only report as type 1, much like GHWT + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = (inputData[0] & 0x3F); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = (inputData[1] & 0x3F); + + buttons[WiiButtons::WII_BUTTON_MINUS] = !((inputData[4] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_PLUS] = !((inputData[4] & 0x04) >> 2); + + buttons[DrumButtons::DRUM_ORANGE] = !((inputData[5] & 0x80) >> 7); + buttons[DrumButtons::DRUM_RED] = !((inputData[5] & 0x40) >> 6); + buttons[DrumButtons::DRUM_YELLOW] = !((inputData[5] & 0x20) >> 5); + buttons[DrumButtons::DRUM_GREEN] = !((inputData[5] & 0x10) >> 4); + buttons[DrumButtons::DRUM_BLUE] = !((inputData[5] & 0x08) >> 3); + buttons[DrumButtons::DRUM_PEDAL] = !((inputData[5] & 0x04) >> 2); + +#if WII_EXTENSION_DEBUG==true + //printf("O=%1d R=%1d Y=%1d G=%1d B=%1d P=%1d\n", buttons[DrumButtons::DRUM_ORANGE], buttons[DrumButtons::DRUM_RED], buttons[DrumButtons::DRUM_YELLOW], buttons[DrumButtons::DRUM_GREEN], buttons[DrumButtons::DRUM_BLUE], buttons[DrumButtons::DRUM_PEDAL]); + //printf("-=%1d +=%1d Joy X=%4d Y=%4d\n", buttons[WiiButtons::BUTTON_MINUS], buttons[WiiButtons::BUTTON_PLUS], analogState[WiiAnalogs::ANALOG_LEFT_X], analogState[WiiAnalogs::ANALOG_LEFT_Y]); + //if (_lastRead[2] != inputData[2]) printf("Byte%2d " BYTE_TO_BINARY_PATTERN "\n", 2, BYTE_TO_BINARY(inputData[2])); + //if (_lastRead[3] != inputData[3]) printf("Byte%2d " BYTE_TO_BINARY_PATTERN "\n", 3, BYTE_TO_BINARY(inputData[3])); + //if (_lastRead[5] != inputData[5]) printf("Byte%2d " BYTE_TO_BINARY_PATTERN "\n", 5, BYTE_TO_BINARY(inputData[5])); + //for (int i = 0; i < 8; ++i) { + // //if (_lastRead[i] != inputData[i]) printf("Byte%2d " BYTE_TO_BINARY_PATTERN "\n", i, BYTE_TO_BINARY(inputData[i])); + // _lastRead[i] = inputData[i]; + //} +#endif +} \ No newline at end of file diff --git a/lib/WiiExtension/extensions/DrumExtension.h b/lib/WiiExtension/extensions/DrumExtension.h new file mode 100644 index 000000000..3227159d5 --- /dev/null +++ b/lib/WiiExtension/extensions/DrumExtension.h @@ -0,0 +1,20 @@ +#ifndef _DRUMEXTENSION_H_ +#define _DRUMEXTENSION_H_ + +#include "ExtensionBase.h" + +enum DrumButtons { + DRUM_ORANGE = WiiButtons::WII_BUTTON_ZL, + DRUM_RED = WiiButtons::WII_BUTTON_B, + DRUM_BLUE = WiiButtons::WII_BUTTON_Y, + DRUM_GREEN = WiiButtons::WII_BUTTON_A, + DRUM_YELLOW = WiiButtons::WII_BUTTON_X, + DRUM_PEDAL = WiiButtons::WII_BUTTON_ZR +}; + +class DrumExtension : public ExtensionBase { + public: + void process(uint8_t *inputData) override; +}; + +#endif \ No newline at end of file diff --git a/lib/WiiExtension/extensions/ExtensionBase.cpp b/lib/WiiExtension/extensions/ExtensionBase.cpp new file mode 100644 index 000000000..a561a496b --- /dev/null +++ b/lib/WiiExtension/extensions/ExtensionBase.cpp @@ -0,0 +1,157 @@ +#include "ExtensionBase.h" + +#include +#include + +#include "WiiExtension.h" + +void ExtensionBase::init(uint8_t dataType) { + uint8_t i; + + setDataType(dataType); + isFirstRead = true; + + _hasCalibrationData = false; + for (i = 0; i < WiiButtons::WII_MAX_BUTTONS; ++i) buttons[i] = 0; + for (i = 0; i < WiiMotions::WII_MAX_MOTIONS; ++i) motionState[i] = 0; + for (i = 0; i < WiiAnalogs::WII_MAX_ANALOGS; ++i) { + analogState[i] = 0; + initialAnalogState[i] = 0; + _analogCalibration[i].minimum = 0; + _analogCalibration[i].center = 0; + _analogCalibration[i].maximum = 1; + } +} + +bool ExtensionBase::calibrate(uint8_t *calibrationData) { + // stores calibration data. no calculation is done here. + uint8_t checksum = WII_CHECKSUM_MAGIC; + uint8_t i = 0; + uint8_t checksumBytes[2] = {0x00,0x00}; + bool result = false; + +#if WII_EXTENSION_DEBUG==true + for (int i = 0; i < 16; ++i) { + printf("%02x", calibrationData[i]); + } + printf("\n"); +#endif + + for (i = 0; i < (WII_CALIBRATION_SIZE-WII_CALIBRATION_CHECKSUM_SIZE); ++i) { + checksum += calibrationData[i]; + checksumBytes[0] = checksum; + } + checksum += WII_CHECKSUM_MAGIC; + checksumBytes[1] = checksum; + +#if WII_EXTENSION_DEBUG==true + printf("Checksum: %02x%02x=%02x%02x\n", checksumBytes[0], checksumBytes[1], calibrationData[WII_CALIBRATION_SIZE-2], calibrationData[WII_CALIBRATION_SIZE-1]); +#endif + + // if the checksum passes, the extensions can use the data. if not, it will fall back to the extension defaults + result = ((checksumBytes[0] == calibrationData[WII_CALIBRATION_SIZE-2]) && (checksumBytes[1] == calibrationData[WII_CALIBRATION_SIZE-1])); + + _hasCalibrationData = result; + + return result; +} + +void ExtensionBase::postProcess() { + uint8_t i; + + uint16_t minVal, maxVal, cenVal, outVal; + int16_t centerOffset = 0; + + for (i = 0; i < WiiAnalogs::WII_MAX_ANALOGS; ++i) { + // scale calibration values before using + if (i != WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION) { + minVal = map(_analogCalibration[i].minimum, 0, _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin-1, 0, _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination-1); + maxVal = map(_analogCalibration[i].maximum, 0, _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin-1, 0, _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination-1); + cenVal = map(_analogCalibration[i].center, 0, _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin-1, 0, _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination-1); + + if (isFirstRead) { + // stash the first read as the initial orientation. will reset on hotswap. + initialAnalogState[i] = map(analogState[i], 0, (_analogPrecision[i].origin-1), 0,(_analogPrecision[i].destination-1)); + + if (!_hasCalibrationData) { + cenVal = initialAnalogState[i]; + } + } + + if (_analogCalibration[i].useOffset) { + centerOffset = cenVal-initialAnalogState[i]; + } else { + centerOffset = 0; + } + + outVal = map(analogState[i], 0, (_analogPrecision[i].origin-1), 0,(_analogPrecision[i].destination-1)); + if ((i != WiiAnalogs::WII_ANALOG_LEFT_TRIGGER) && (i != WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER)) { + outVal = bounds(outVal, minVal, maxVal); + outVal = map(outVal+centerOffset, minVal+centerOffset, maxVal+centerOffset, 0, (_analogPrecision[i].destination-1)); + outVal = bounds(outVal, minVal, maxVal); + } else { + outVal = bounds(outVal, 0, (_analogPrecision[i].destination-1)); + } + + applyCalibration(outVal, minVal, maxVal, cenVal); + +#if WII_EXTENSION_DEBUG==true + if (i == WiiAnalogs::WII_ANALOG_RIGHT_Y) { + //printf("cur:%5d min=%5d:%5d max=%5d:%5d cen=%5d:%5d out:%5d off:%5d\n", analogState[i], _analogCalibration[i].minimum, minVal, _analogCalibration[i].maximum, maxVal, _analogCalibration[i].center, cenVal, outVal, centerOffset); + } +#endif + + analogState[i] = outVal; + } + } + + if (isFirstRead) isFirstRead = false; + +#if WII_EXTENSION_DEBUG==true + //if ((_lastRead[0] != regRead[0]) || (_lastRead[1] != regRead[1]) || (_lastRead[2] != regRead[2]) || (_lastRead[3] != regRead[3])) { + // printf("Joy1 X=%4d Y=%4d Joy2 X=%4d Y=%4d\n", joy1X, joy1Y, joy2X, joy2Y); + //} + //printf("C Joy1 X=%5d Y=%5d Joy2 X=%5d Y=%5d U=%1d D=%1d L=%1d R=%1d TL=%5d TR=%4d\n", analogState[WiiAnalogs::WII_ANALOG_LEFT_X], analogState[WiiAnalogs::WII_ANALOG_LEFT_Y], analogState[WiiAnalogs::WII_ANALOG_RIGHT_X], analogState[WiiAnalogs::WII_ANALOG_RIGHT_Y], directionalPad[WiiDirectionalPad::WII_DIRECTION_UP], directionalPad[WiiDirectionalPad::WII_DIRECTION_DOWN], directionalPad[WiiDirectionalPad::WII_DIRECTION_LEFT], directionalPad[WiiDirectionalPad::WII_DIRECTION_RIGHT], analogState[WiiAnalogs::WII_ANALOG_TRIGGER_LEFT], analogState[WiiAnalogs::WII_ANALOG_TRIGGER_RIGHT]); + //printf("A=%1d B=%1d X=%1d Y=%1d ZL=%1d ZR=%1d LT=%1d RT=%1d -=%1d H=%1d +=%1d\n", buttonA, buttonB, buttonX, buttonY, buttonZL, buttonZR, buttonLT, buttonRT, buttonMinus, buttonHome, buttonPlus); +#endif +} + +void ExtensionBase::setDataType(uint8_t dataType) { + _dataType = dataType; +} + +void ExtensionBase::setExtensionType(uint8_t extensionType) { + _extensionType = extensionType; +} + +uint16_t ExtensionBase::map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +uint16_t ExtensionBase::bounds(uint16_t x, uint16_t out_min, uint16_t out_max) { + if (x > out_max) x = out_max; + if (x < out_min) x = out_min; + return x; +} + +uint16_t ExtensionBase::applyCalibration(uint16_t pos, uint16_t min, uint16_t max, uint16_t cen) { + uint16_t result; + +#if WII_EXTENSION_CALIBRATION==true + if (pos >= min && pos <= max) { + result = pos; + } else { + if (pos < min) { + result = min; + } else if (pos > max) { + result = max; + } else { + result = cen; + } + } +#else + result = pos; +#endif + + return result; +} \ No newline at end of file diff --git a/lib/WiiExtension/extensions/ExtensionBase.h b/lib/WiiExtension/extensions/ExtensionBase.h new file mode 100644 index 000000000..48fe56c37 --- /dev/null +++ b/lib/WiiExtension/extensions/ExtensionBase.h @@ -0,0 +1,102 @@ +#ifndef _EXTENSIONBASE_H_ +#define _EXTENSIONBASE_H_ + +#include +#include + +typedef enum { + WII_BUTTON_A, + WII_BUTTON_B, + WII_BUTTON_C, + WII_BUTTON_X, + WII_BUTTON_Y, + WII_BUTTON_Z, + WII_BUTTON_L, + WII_BUTTON_R, + WII_BUTTON_ZL, + WII_BUTTON_ZR, + WII_BUTTON_MINUS, + WII_BUTTON_HOME, + WII_BUTTON_PLUS, + WII_BUTTON_UP, + WII_BUTTON_DOWN, + WII_BUTTON_LEFT, + WII_BUTTON_RIGHT, + WII_MAX_BUTTONS +} WiiButtons; + +typedef enum { + WII_ANALOG_LEFT_X, + WII_ANALOG_LEFT_Y, + WII_ANALOG_RIGHT_X, + WII_ANALOG_RIGHT_Y, + WII_ANALOG_LEFT_TRIGGER, + WII_ANALOG_RIGHT_TRIGGER, + WII_ANALOG_CALIBRATION_PRECISION, + WII_MAX_ANALOGS +} WiiAnalogs; + +typedef enum { + WII_JOYSTICK_NONE, + WII_JOYSTICK_LEFT_ANALOG, + WII_JOYSTICK_RIGHT_ANALOG, + WII_JOYSTICK_DPAD +} WiiJoystickModes; + +typedef enum { + WII_MOTION_X, + WII_MOTION_Y, + WII_MOTION_Z, + WII_MAX_MOTIONS +} WiiMotions; + +typedef struct { + uint16_t origin = 0; + uint16_t destination = 0; +} WiiAnalogPrecision; + +typedef struct { + uint16_t minimum = 0; + uint16_t center = 0; + uint16_t maximum = 0; + bool useOffset = true; +} WiiAnalogCalibration; + +class ExtensionBase { + protected: + uint8_t _dataType; + uint8_t _extensionType; + bool _hasCalibrationData = false; + + WiiAnalogPrecision _analogPrecision[WiiAnalogs::WII_MAX_ANALOGS]; + WiiAnalogCalibration _analogCalibration[WiiAnalogs::WII_MAX_ANALOGS]; + + 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); + private: + uint16_t applyCalibration(uint16_t pos, uint16_t min, uint16_t max, uint16_t cen); + public: + bool buttons[WiiButtons::WII_MAX_BUTTONS]; + uint16_t analogState[WiiAnalogs::WII_MAX_ANALOGS]; + uint16_t motionState[WiiMotions::WII_MAX_MOTIONS]; + + uint16_t initialAnalogState[WiiAnalogs::WII_MAX_ANALOGS]; + bool isFirstRead = true; + + virtual void init(uint8_t dataType); + virtual bool calibrate(uint8_t *calibrationData); + virtual void process(uint8_t *inputData); + virtual void postProcess(); + +#if WII_EXTENSION_DEBUG==true + uint8_t _lastRead[16] = {0xFF}; +#endif + + void setDataType(uint8_t dataType); + uint8_t getDataType() { return _dataType; }; + + void setExtensionType(uint8_t extensionType); + uint8_t getExtensionType() { return _extensionType; }; +}; + +#endif diff --git a/lib/WiiExtension/extensions/Extensions.h b/lib/WiiExtension/extensions/Extensions.h new file mode 100644 index 000000000..1d439e599 --- /dev/null +++ b/lib/WiiExtension/extensions/Extensions.h @@ -0,0 +1,12 @@ +#ifndef _EXTENSIONS_H_ +#define _EXTENSIONS_H_ + +#include "ExtensionBase.h" +#include "ClassicExtension.h" +#include "DrumExtension.h" +#include "GuitarExtension.h" +#include "NunchuckExtension.h" +#include "TaikoExtension.h" +#include "TurntableExtension.h" + +#endif diff --git a/lib/WiiExtension/extensions/GuitarExtension.cpp b/lib/WiiExtension/extensions/GuitarExtension.cpp new file mode 100644 index 000000000..2a90a9366 --- /dev/null +++ b/lib/WiiExtension/extensions/GuitarExtension.cpp @@ -0,0 +1,201 @@ +#include "ExtensionBase.h" +#include "GuitarExtension.h" + +#include "WiiExtension.h" + +void GuitarExtension::init(uint8_t dataType) { + ExtensionBase::init(dataType); + _guitarType = WII_GUITAR_UNSET; + + if (getDataType() == WII_DATA_TYPE_1) { + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].destination = WII_ANALOG_PRECISION_3; + + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination = WII_ANALOG_PRECISION_3; + } else if (getDataType() == WII_DATA_TYPE_2) { + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].origin = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].origin = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].destination = WII_ANALOG_PRECISION_3; + + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination = WII_ANALOG_PRECISION_3; + } else if (getDataType() == WII_DATA_TYPE_3) { + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].destination = WII_ANALOG_PRECISION_3; + + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination = WII_ANALOG_PRECISION_3; + } + + // preseed calibration data with max ranges + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].minimum = WII_GUITAR_ANALOG_GAP; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].center = WII_GUITAR_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].maximum = WII_GUITAR_GATE_CENTER+WII_GUITAR_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].minimum = WII_GUITAR_ANALOG_GAP; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].center = WII_GUITAR_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].maximum = WII_GUITAR_GATE_CENTER+WII_GUITAR_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].minimum = 15; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].center = WII_GUITAR_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].maximum = WII_GUITAR_GATE_CENTER*2; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].useOffset = false; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].minimum = 0; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].center = WII_GUITAR_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].maximum = WII_GUITAR_GATE_CENTER*2; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].useOffset = false; +} + +void GuitarExtension::process(uint8_t *inputData) { + // on first read, check the status of the guitar flag + if (_guitarType == WII_GUITAR_UNSET) { + if (((inputData[0] & 0x80) >> 7) == 0) { + _guitarType = WII_GUITAR_GHWT; + } else { + _guitarType = WII_GUITAR_GH3; + } + // force the data type to 1 when a World Tour guitar is detected + if ((_guitarType == WII_GUITAR_GHWT) && (getDataType() != WII_DATA_TYPE_1)) { + setDataType(WII_DATA_TYPE_1); + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].origin = WII_ANALOG_PRECISION_0; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].destination = WII_ANALOG_PRECISION_3; + } + } + if (_guitarType != WII_GUITAR_UNSET) { + // as defined works for GH3 guitar + if (getDataType() == WII_DATA_TYPE_1) { + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = (inputData[0] & 0x3F); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = (inputData[1] & 0x3F); + + touchBar = ((_guitarType == WII_GUITAR_GHWT) ? (inputData[2] & 0x1F) : 0); + + whammyBar = (inputData[3] & 0x1F); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_X] = (inputData[3] & 0x1F); + + buttons[WiiButtons::WII_BUTTON_DOWN] = !((inputData[4] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_MINUS] = !((inputData[4] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_PLUS] = !((inputData[4] & 0x04) >> 2); + + buttons[GuitarButtons::GUITAR_ORANGE] = !((inputData[5] & 0x80) >> 7); + buttons[GuitarButtons::GUITAR_RED] = !((inputData[5] & 0x40) >> 6); + buttons[GuitarButtons::GUITAR_BLUE] = !((inputData[5] & 0x20) >> 5); + buttons[GuitarButtons::GUITAR_GREEN] = !((inputData[5] & 0x10) >> 4); + buttons[GuitarButtons::GUITAR_YELLOW] = !((inputData[5] & 0x08) >> 3); + buttons[GuitarButtons::GUITAR_PEDAL] = !((inputData[5] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_UP] = !((inputData[5] & 0x01) >> 0); + + isTouched = (touchBar != WII_GUITAR_TOUCHPAD_NONE); + + // process the touch bar for button states + // touch only seems to exist in GHWT, and GHWT always reports data type 1 format regardless of setting + if (isTouched) { + // touched + buttons[GuitarButtons::GUITAR_GREEN] = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_GREEN,WII_GUITAR_TOUCHPAD_RED)); + buttons[GuitarButtons::GUITAR_RED] = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_RED,WII_GUITAR_TOUCHPAD_YELLOW)); + buttons[GuitarButtons::GUITAR_YELLOW] = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_YELLOW,WII_GUITAR_TOUCHPAD_BLUE)); + buttons[GuitarButtons::GUITAR_BLUE] = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_BLUE,WII_GUITAR_TOUCHPAD_ORANGE)); + buttons[GuitarButtons::GUITAR_ORANGE] = (TOUCH_BETWEEN_RANGE(touchBar,WII_GUITAR_TOUCHPAD_ORANGE,WII_GUITAR_TOUCHPAD_MAX)); + buttons[WiiButtons::WII_BUTTON_DOWN] = isTouched; + } + } else if (getDataType() == WII_DATA_TYPE_2) { + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = ((inputData[0] << 2) | ((inputData[4] & 0x03) >> 0)); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = ((inputData[2] << 2) | ((inputData[4] & 0x30) >> 4)); + + touchBar = 0; + + whammyBar = (inputData[6] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_X] = (inputData[6] & 0xFF); + + buttons[WiiButtons::WII_BUTTON_DOWN] = !((inputData[7] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_MINUS] = !((inputData[7] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_PLUS] = !((inputData[7] & 0x04) >> 2); + + buttons[GuitarButtons::GUITAR_ORANGE] = !((inputData[8] & 0x80) >> 7); + buttons[GuitarButtons::GUITAR_RED] = !((inputData[8] & 0x40) >> 6); + buttons[GuitarButtons::GUITAR_BLUE] = !((inputData[8] & 0x20) >> 5); + buttons[GuitarButtons::GUITAR_GREEN] = !((inputData[8] & 0x10) >> 4); + buttons[GuitarButtons::GUITAR_YELLOW] = !((inputData[8] & 0x08) >> 3); + buttons[GuitarButtons::GUITAR_PEDAL] = !((inputData[8] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_UP] = !((inputData[8] & 0x01) >> 0); + } else if (getDataType() == WII_DATA_TYPE_3) { + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = (inputData[0] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = (inputData[2] & 0xFF); + + touchBar = 0; + + whammyBar = (inputData[5] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_RIGHT_X] = (inputData[5] & 0xFF); + + buttons[WiiButtons::WII_BUTTON_DOWN] = !((inputData[6] & 0x40) >> 6); + buttons[WiiButtons::WII_BUTTON_MINUS] = !((inputData[6] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_PLUS] = !((inputData[6] & 0x04) >> 2); + + buttons[GuitarButtons::GUITAR_ORANGE] = !((inputData[7] & 0x80) >> 7); + buttons[GuitarButtons::GUITAR_RED] = !((inputData[7] & 0x40) >> 6); + buttons[GuitarButtons::GUITAR_BLUE] = !((inputData[7] & 0x20) >> 5); + buttons[GuitarButtons::GUITAR_GREEN] = !((inputData[7] & 0x10) >> 4); + buttons[GuitarButtons::GUITAR_YELLOW] = !((inputData[7] & 0x08) >> 3); + buttons[GuitarButtons::GUITAR_PEDAL] = !((inputData[7] & 0x04) >> 2); + buttons[WiiButtons::WII_BUTTON_UP] = !((inputData[7] & 0x01) >> 0); + } + } +#if WII_EXTENSION_DEBUG==true + //if (_lastRead[0] != regRead[0]) { + // printf("GH: %d Byte0 = %d\n", _guitarType, (regRead[0])); + //} + //if (_lastRead[1] != regRead[1]) { + // printf("GH: %d Byte1 = %d\n", _guitarType, (regRead[1])); + //} + //printf("Byte2 " BYTE_TO_BINARY_PATTERN " : " BYTE_TO_BINARY_PATTERN " = %02x\n", BYTE_TO_BINARY(regRead[2]), BYTE_TO_BINARY(regRead[2]^0x1F), regRead[2]); + //printf("G=%1d R=%1d Y=%1d B=%1d O=%1d Touched=%1d\n", fretGreen, fretRed, fretYellow, fretBlue, fretOrange, isTouched); + //} +// for (int i = 0; i < result; ++i) { +// if ((i != 0) && (i != 1) && (i != 3)) { +// if (_lastRead[i] != regRead[i]) printf("Byte%2d " BYTE_TO_BINARY_PATTERN "\n", i, BYTE_TO_BINARY(regRead[i])); +// } +// } +// printf("Joy1 X=%4d Y=%4d Whammy=%4d U=%1d D=%1d -=%1d +=%1d\n", joy1X, joy1Y, whammyBar, directionUp, directionDown, buttonMinus, buttonPlus); +// printf("Whammy=%4d\n", analogState[WiiAnalogs::WII_ANALOG_RIGHT_X]); +// printf("O=%1d B=%1d Y=%1d R=%1d G=%1d\n", buttons[GuitarButtons::GUITAR_ORANGE], buttons[GuitarButtons::GUITAR_BLUE], buttons[GuitarButtons::GUITAR_YELLOW], buttons[GuitarButtons::GUITAR_RED], buttons[GuitarButtons::GUITAR_GREEN]); +#endif +} \ No newline at end of file diff --git a/lib/WiiExtension/extensions/GuitarExtension.h b/lib/WiiExtension/extensions/GuitarExtension.h new file mode 100644 index 000000000..db8cc9dc9 --- /dev/null +++ b/lib/WiiExtension/extensions/GuitarExtension.h @@ -0,0 +1,31 @@ +#ifndef _GUITAREXTENSION_H_ +#define _GUITAREXTENSION_H_ + +#include "ExtensionBase.h" + +#define WII_GUITAR_GATE_SIZE 97 +#define WII_GUITAR_GATE_CENTER 128 +#define WII_GUITAR_TRIGGER_MAX 32 +#define WII_GUITAR_ANALOG_GAP (WII_GUITAR_GATE_CENTER-WII_GUITAR_GATE_SIZE) + +enum GuitarButtons { + GUITAR_ORANGE = WiiButtons::WII_BUTTON_ZL, + GUITAR_RED = WiiButtons::WII_BUTTON_B, + GUITAR_BLUE = WiiButtons::WII_BUTTON_Y, + GUITAR_GREEN = WiiButtons::WII_BUTTON_A, + GUITAR_YELLOW = WiiButtons::WII_BUTTON_X, + GUITAR_PEDAL = WiiButtons::WII_BUTTON_ZR +}; + +class GuitarExtension : public ExtensionBase { + public: + void init(uint8_t dataType) override; + void process(uint8_t *inputData) override; + private: + uint8_t _guitarType = 0; + uint16_t whammyBar = 0; + int8_t touchBar = 0; + bool isTouched = 0; +}; + +#endif \ No newline at end of file diff --git a/lib/WiiExtension/extensions/NunchuckExtension.cpp b/lib/WiiExtension/extensions/NunchuckExtension.cpp new file mode 100644 index 000000000..0666646f9 --- /dev/null +++ b/lib/WiiExtension/extensions/NunchuckExtension.cpp @@ -0,0 +1,81 @@ +#include "ExtensionBase.h" +#include "NunchuckExtension.h" + +#include "WiiExtension.h" + +void NunchuckExtension::init(uint8_t dataType) { + ExtensionBase::init(dataType); + _extensionType = WII_EXTENSION_NUNCHUCK; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + + // preseed calibration data with max ranges + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].minimum = WII_NUNCHUCK_GATE_CENTER-WII_NUNCHUCK_GATE_SIZE; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].center = WII_NUNCHUCK_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].maximum = WII_NUNCHUCK_GATE_CENTER+WII_NUNCHUCK_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].minimum = WII_NUNCHUCK_GATE_CENTER-WII_NUNCHUCK_GATE_SIZE; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].center = WII_NUNCHUCK_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].maximum = WII_NUNCHUCK_GATE_CENTER+WII_NUNCHUCK_GATE_SIZE; + + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination = WII_ANALOG_PRECISION_3; +} + +bool NunchuckExtension::calibrate(uint8_t *calibrationData) { +#if WII_EXTENSION_CALIBRATION==true + if (ExtensionBase::calibrate(calibrationData)) { + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].maximum = calibrationData[8]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].minimum = calibrationData[9]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].center = calibrationData[10]; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].maximum = calibrationData[11]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].minimum = calibrationData[12]; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].center = calibrationData[13]; + + //_accelX0G = ((idRead[0] << 2) | ((idRead[3] >> 2) & 0x03)); + //_accelY0G = ((idRead[1] << 2) | ((idRead[3] >> 4) & 0x03)); + //_accelZ0G = ((idRead[2] << 2) | ((idRead[3] >> 6) & 0x03)); + // + //_accelX1G = ((idRead[4] << 2) | ((idRead[7] >> 2) & 0x03)); + //_accelY1G = ((idRead[5] << 2) | ((idRead[7] >> 4) & 0x03)); + //_accelZ1G = ((idRead[6] << 2) | ((idRead[7] >> 6) & 0x03)); + return true; + } + +#if WII_EXTENSION_DEBUG==true + //printf("Calibration:\n"); + //printf("X0G: %d\n", _accelX0G); + //printf("Y0G: %d\n", _accelY0G); + //printf("Z0G: %d\n", _accelZ0G); + //printf("X1G: %d\n", _accelX1G); + //printf("Y1G: %d\n", _accelY1G); + //printf("YZG: %d\n", _accelZ1G); + //printf("X Min: %d\n", _minX); + //printf("X Max: %d\n", _maxX); + //printf("X Center: %d\n", _cenX); + //printf("Y Min: %d\n", _minY); + //printf("Y Max: %d\n", _maxY); + //printf("Y Center: %d\n", _cenY); +#endif +#endif + return false; +} + +void NunchuckExtension::process(uint8_t *inputData) { + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = (inputData[0] & 0xFF); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = (inputData[1] & 0xFF); + + buttons[WiiButtons::WII_BUTTON_Z] = (!(inputData[5] & 0x01)); + buttons[WiiButtons::WII_BUTTON_C] = (!(inputData[5] & 0x02)); + + motionState[WiiMotions::WII_MOTION_X] = (((inputData[2] << 2) | ((inputData[5] >> 2) & 0x03))); + motionState[WiiMotions::WII_MOTION_Y] = (((inputData[3] << 2) | ((inputData[5] >> 4) & 0x03))); + motionState[WiiMotions::WII_MOTION_Z] = (((inputData[4] << 2) | ((inputData[5] >> 6) & 0x03))); + +#if WII_EXTENSION_DEBUG==true + //printf("Joy X=%4d Y=%4d Acc X=%4d Y=%4d Z=%4d Btn Z=%1d C=%1d\n", analogState[WiiAnalogs::ANALOG_LEFT_X], analogState[WiiAnalogs::ANALOG_LEFT_Y], motionState[WiiMotions::MOTION_X], motionState[WiiMotions::MOTION_Y], motionState[WiiMotions::MOTION_Z], buttons[WiiButtons::BUTTON_Z], buttons[WiiButtons::BUTTON_C]); +#endif +} \ No newline at end of file diff --git a/lib/WiiExtension/extensions/NunchuckExtension.h b/lib/WiiExtension/extensions/NunchuckExtension.h new file mode 100644 index 000000000..78939e7a0 --- /dev/null +++ b/lib/WiiExtension/extensions/NunchuckExtension.h @@ -0,0 +1,16 @@ +#ifndef _NUNCHUCKEXTENSION_H_ +#define _NUNCHUCKEXTENSION_H_ + +#include "ExtensionBase.h" + +#define WII_NUNCHUCK_GATE_SIZE 96 +#define WII_NUNCHUCK_GATE_CENTER 128 + +class NunchuckExtension : public ExtensionBase { + public: + void init(uint8_t dataType) override; + bool calibrate(uint8_t *calibrationData) override; + void process(uint8_t *inputData) override; +}; + +#endif \ No newline at end of file diff --git a/lib/WiiExtension/extensions/TaikoExtension.cpp b/lib/WiiExtension/extensions/TaikoExtension.cpp new file mode 100644 index 000000000..2d2cea55d --- /dev/null +++ b/lib/WiiExtension/extensions/TaikoExtension.cpp @@ -0,0 +1,37 @@ +#include "ExtensionBase.h" +#include "TaikoExtension.h" + +#include "WiiExtension.h" + +void TaikoExtension::process(uint8_t *inputData) { + if (getDataType() == WII_DATA_TYPE_1) { + buttons[TaikoButtons::TATA_DON_LEFT] = !((inputData[5] & 0x40) >> 6); + buttons[TaikoButtons::TATA_KAT_LEFT] = !((inputData[5] & 0x20) >> 5); + buttons[TaikoButtons::TATA_DON_RIGHT] = !((inputData[5] & 0x10) >> 4); + buttons[TaikoButtons::TATA_KAT_RIGHT] = !((inputData[5] & 0x08) >> 3); + } else if (getDataType() == WII_DATA_TYPE_2) { + buttons[TaikoButtons::TATA_DON_LEFT] = !((inputData[8] & 0x40) >> 6); + buttons[TaikoButtons::TATA_KAT_LEFT] = !((inputData[8] & 0x20) >> 5); + buttons[TaikoButtons::TATA_DON_RIGHT] = !((inputData[8] & 0x10) >> 4); + buttons[TaikoButtons::TATA_KAT_RIGHT] = !((inputData[8] & 0x08) >> 3); + } else if (getDataType() == WII_DATA_TYPE_3) { + buttons[TaikoButtons::TATA_DON_LEFT] = !((inputData[7] & 0x40) >> 6); + buttons[TaikoButtons::TATA_KAT_LEFT] = !((inputData[7] & 0x20) >> 5); + buttons[TaikoButtons::TATA_DON_RIGHT] = !((inputData[7] & 0x10) >> 4); + buttons[TaikoButtons::TATA_KAT_RIGHT] = !((inputData[7] & 0x08) >> 3); + } + +#if WII_EXTENSION_DEBUG==true +// //if (_lastRead[0] != regRead[0]) printf("Byte0 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[0])); +// //if (_lastRead[1] != regRead[1]) printf("Byte1 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[1])); +// //if (_lastRead[2] != regRead[2]) printf("Byte2 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[2])); +// //if (_lastRead[3] != regRead[3]) printf("Byte3 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[3])); +// //if (_lastRead[4] != regRead[4]) printf("Byte4 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[4])); +// //if (_lastRead[5] != regRead[5]) printf("Byte5 " BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(regRead[5])); +// // +// if (_lastRead[7] != regRead[7]) { +// printf("DL=%1d RL=%1d DR=%1d RR=%1d\n", drumLeft, rimLeft, drumRight, rimRight); +// } + printf("DL=%1d RL=%1d DR=%1d RR=%1d\n", buttons[TaikoButtons::TATA_DON_LEFT], buttons[TaikoButtons::TATA_KAT_LEFT], buttons[TaikoButtons::TATA_DON_RIGHT], buttons[TaikoButtons::TATA_KAT_RIGHT]); +#endif +} \ No newline at end of file diff --git a/lib/WiiExtension/extensions/TaikoExtension.h b/lib/WiiExtension/extensions/TaikoExtension.h new file mode 100644 index 000000000..743ba659b --- /dev/null +++ b/lib/WiiExtension/extensions/TaikoExtension.h @@ -0,0 +1,18 @@ +#ifndef _TAIKOEXTENSION_H_ +#define _TAIKOEXTENSION_H_ + +#include "ExtensionBase.h" + +enum TaikoButtons { + TATA_DON_LEFT = WiiButtons::WII_BUTTON_B, + TATA_KAT_LEFT = WiiButtons::WII_BUTTON_Y, + TATA_DON_RIGHT = WiiButtons::WII_BUTTON_A, + TATA_KAT_RIGHT = WiiButtons::WII_BUTTON_X +}; + +class TaikoExtension : public ExtensionBase { + public: + void process(uint8_t *inputData) override; +}; + +#endif \ No newline at end of file diff --git a/lib/WiiExtension/extensions/TurntableExtension.cpp b/lib/WiiExtension/extensions/TurntableExtension.cpp new file mode 100644 index 000000000..79ecde516 --- /dev/null +++ b/lib/WiiExtension/extensions/TurntableExtension.cpp @@ -0,0 +1,92 @@ +#include "ExtensionBase.h" +#include "TurntableExtension.h" + +#include "WiiExtension.h" + +void TurntableExtension::init(uint8_t dataType) { + ExtensionBase::init(dataType); + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_Y].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_X].destination = WII_ANALOG_PRECISION_3; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].origin = WII_ANALOG_PRECISION_1; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_Y].destination = WII_ANALOG_PRECISION_3; + + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].origin = WII_ANALOG_PRECISION_0; // 32 + _analogPrecision[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].origin = WII_ANALOG_PRECISION_0; // 32 + _analogPrecision[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].destination = WII_ANALOG_PRECISION_2; + + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].origin = WII_ANALOG_PRECISION_2; + _analogPrecision[WiiAnalogs::WII_ANALOG_CALIBRATION_PRECISION].destination = WII_ANALOG_PRECISION_3; + + + // preseed calibration data with max ranges + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].minimum = WII_TURNTABLE_ANALOG_GAP; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].center = WII_TURNTABLE_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_X].maximum = WII_TURNTABLE_GATE_CENTER+WII_TURNTABLE_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].minimum = WII_TURNTABLE_ANALOG_GAP; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].center = WII_TURNTABLE_GATE_CENTER; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_Y].maximum = WII_TURNTABLE_GATE_CENTER+WII_TURNTABLE_GATE_SIZE; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].minimum = 1; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].center = WII_TURNTABLE_TRIGGER_MAX*2; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].maximum = 256; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_X].useOffset = false; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].minimum = 1; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].center = WII_TURNTABLE_TRIGGER_MAX*2; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].maximum = 256; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_Y].useOffset = false; + + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].minimum = 1; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].center = WII_TURNTABLE_TRIGGER_MAX/2; + _analogCalibration[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER].maximum = WII_TURNTABLE_TRIGGER_MAX; + + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].minimum = 1; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].center = WII_TURNTABLE_TRIGGER_MAX/2; + _analogCalibration[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER].maximum = WII_TURNTABLE_TRIGGER_MAX; +} + +void TurntableExtension::process(uint8_t *inputData) { + // turntable accepts three data modes, but will only report as type 1, much like GHWT + analogState[WiiAnalogs::WII_ANALOG_LEFT_X] = (inputData[0] & 0x3F); + analogState[WiiAnalogs::WII_ANALOG_LEFT_Y] = (inputData[1] & 0x3F); + + analogState[TurntableAnalogs::TURNTABLE_LEFT] = (((inputData[4] & 0x00) << 5) | ((inputData[3] & 0x1F) >> 0)); + analogState[TurntableAnalogs::TURNTABLE_RIGHT] = (((inputData[0] & 0xC0) >> 3) | ((inputData[1] & 0xC0) >> 5) | ((inputData[2] & 0x80) >> 7)); + analogState[TurntableAnalogs::TURNTABLE_EFFECTS] = (((inputData[2] & 0x60) >> 2) | ((inputData[3] & 0xE0) >> 5)); + analogState[TurntableAnalogs::TURNTABLE_CROSSFADE] = ((inputData[2] & 0x1E) >> 1); + + // turntables report 0-5 for CW, 27-32 for CCW (as unsigned) + analogState[TurntableAnalogs::TURNTABLE_LEFT] = ((analogState[TurntableAnalogs::TURNTABLE_LEFT] < 15) ? WII_TURNTABLE_MAX_PRECISION-analogState[TurntableAnalogs::TURNTABLE_LEFT] : WII_TURNTABLE_MAX_PRECISION+(WII_TURNTABLE_MAX_PRECISION-analogState[TurntableAnalogs::TURNTABLE_LEFT])); + analogState[TurntableAnalogs::TURNTABLE_RIGHT] = ((analogState[TurntableAnalogs::TURNTABLE_RIGHT] < 15) ? WII_TURNTABLE_MAX_PRECISION-analogState[TurntableAnalogs::TURNTABLE_RIGHT] : WII_TURNTABLE_MAX_PRECISION+(WII_TURNTABLE_MAX_PRECISION-analogState[TurntableAnalogs::TURNTABLE_RIGHT])); + + buttons[WiiButtons::WII_BUTTON_MINUS] = !((inputData[4] & 0x10) >> 4); + buttons[WiiButtons::WII_BUTTON_PLUS] = !((inputData[4] & 0x04) >> 2); + + buttons[TurntableButtons::TURNTABLE_RIGHT_GREEN] = !((inputData[5] & 0x20) >> 5); + buttons[TurntableButtons::TURNTABLE_RIGHT_RED] = !((inputData[4] & 0x02) >> 1); + buttons[TurntableButtons::TURNTABLE_RIGHT_BLUE] = !((inputData[5] & 0x04) >> 2); + + buttons[TurntableButtons::TURNTABLE_EUPHORIA] = !((inputData[5] & 0x10) >> 4); + + buttons[TurntableButtons::TURNTABLE_LEFT_GREEN] = !((inputData[5] & 0x08) >> 3); + buttons[TurntableButtons::TURNTABLE_LEFT_RED] = !((inputData[4] & 0x20) >> 5); + buttons[TurntableButtons::TURNTABLE_LEFT_BLUE] = !((inputData[5] & 0x80) >> 7); + +#if WII_EXTENSION_DEBUG==true + //printf("LR=%1d LG=%1d LB=%1d\n", buttons[TurntableButtons::TURNTABLE_LEFT_RED], buttons[TurntableButtons::TURNTABLE_LEFT_GREEN], buttons[TurntableButtons::TURNTABLE_LEFT_BLUE]); + //printf("RR=%1d RG=%1d RB=%1d\n", buttons[TurntableButtons::TURNTABLE_RIGHT_RED], buttons[TurntableButtons::TURNTABLE_RIGHT_GREEN], buttons[TurntableButtons::TURNTABLE_RIGHT_BLUE]); + //printf("-=%1d EU=%1d +=%1d\n", buttons[WiiButtons::BUTTON_MINUS], buttons[TurntableButtons::TURNTABLE_EUPHORIA], buttons[WiiButtons::BUTTON_PLUS]); + //printf("LTT=%4d RTT=%4d CF=%4d ED=%4d\n", analogState[TurntableAnalogs::TURNTABLE_LEFT], analogState[TurntableAnalogs::TURNTABLE_RIGHT], analogState[TurntableAnalogs::TURNTABLE_CROSSFADE], analogState[TurntableAnalogs::TURNTABLE_EFFECTS]); + //printf("X=%4d Y=%4d\n", analogState[WiiAnalogs::WII_ANALOG_LEFT_X], analogState[WiiAnalogs::WII_ANALOG_LEFT_Y]); + + //for (int i = 0; i < result; ++i) { + // if (_lastRead[i] != inputData[i]) printf("Byte%2d " BYTE_TO_BINARY_PATTERN "\n", i, BYTE_TO_BINARY(inputData[i])); + //} +#endif +} \ No newline at end of file diff --git a/lib/WiiExtension/extensions/TurntableExtension.h b/lib/WiiExtension/extensions/TurntableExtension.h new file mode 100644 index 000000000..87d3fa883 --- /dev/null +++ b/lib/WiiExtension/extensions/TurntableExtension.h @@ -0,0 +1,40 @@ +#ifndef _TURNTABLEEXTENSION_H_ +#define _TURNTABLEEXTENSION_H_ + +#include "ExtensionBase.h" + +enum TurntableButtons { + TURNTABLE_RIGHT_GREEN = WiiButtons::WII_BUTTON_Y, + TURNTABLE_RIGHT_RED = WiiButtons::WII_BUTTON_X, + TURNTABLE_RIGHT_BLUE = WiiButtons::WII_BUTTON_A, + TURNTABLE_EUPHORIA = WiiButtons::WII_BUTTON_ZR, + TURNTABLE_LEFT_GREEN = WiiButtons::WII_BUTTON_LEFT, + TURNTABLE_LEFT_RED = WiiButtons::WII_BUTTON_UP, + TURNTABLE_LEFT_BLUE = WiiButtons::WII_BUTTON_RIGHT +}; + +enum TurntableAnalogs { + TURNTABLE_LEFT = WiiAnalogs::WII_ANALOG_RIGHT_Y, + TURNTABLE_RIGHT = WiiAnalogs::WII_ANALOG_RIGHT_X, + TURNTABLE_EFFECTS = WiiAnalogs::WII_ANALOG_LEFT_TRIGGER, + TURNTABLE_CROSSFADE = WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER +}; + +#define WII_TURNTABLE_GATE_SIZE 97 +#define WII_TURNTABLE_GATE_CENTER 128 +#define WII_TURNTABLE_TRIGGER_MAX 64 +#define WII_TURNTABLE_ANALOG_GAP (WII_TURNTABLE_GATE_CENTER-WII_TURNTABLE_GATE_SIZE) +#define WII_TURNTABLE_MAX_PRECISION WII_ANALOG_PRECISION_0 + +class TurntableExtension : public ExtensionBase { + private: + bool _ledState = false; + public: + void init(uint8_t dataType) override; + void process(uint8_t *inputData) override; + + void setLED(bool ledOn) {_ledState = ledOn;}; + bool getLED() {return _ledState;}; +}; + +#endif \ No newline at end of file diff --git a/proto/config.proto b/proto/config.proto index 4931d6f46..d38b87a21 100644 --- a/proto/config.proto +++ b/proto/config.proto @@ -433,11 +433,121 @@ message PSPassthroughOptions message WiiOptions { + message AnalogAxis + { + optional int32 axisType = 1; + optional int32 minRange = 2; + optional int32 maxRange = 3; + } + + message StickOptions + { + optional AnalogAxis x = 1; + optional AnalogAxis y = 2; + } + + message NunchukOptions + { + optional int32 buttonC = 1; + optional int32 buttonZ = 2; + optional StickOptions stick = 3; + } + + message ClassicOptions + { + optional int32 buttonA = 1; + optional int32 buttonB = 2; + optional int32 buttonX = 3; + optional int32 buttonY = 4; + optional int32 buttonL = 5; + optional int32 buttonZL = 6; + optional int32 buttonR = 7; + optional int32 buttonZR = 8; + optional int32 buttonMinus = 9; + optional int32 buttonPlus = 10; + optional int32 buttonHome = 11; + optional int32 buttonUp = 12; + optional int32 buttonDown = 13; + optional int32 buttonLeft = 14; + optional int32 buttonRight = 15; + optional StickOptions rightStick = 17; + optional StickOptions leftStick = 16; + optional AnalogAxis leftTrigger = 18; + optional AnalogAxis rightTrigger = 19; + } + + message TaikoOptions + { + optional int32 buttonKatLeft = 1; + optional int32 buttonKatRight = 2; + optional int32 buttonDonLeft = 3; + optional int32 buttonDonRight = 4; + } + + message GuitarOptions + { + optional int32 buttonRed = 1; + optional int32 buttonGreen = 2; + optional int32 buttonYellow = 3; + optional int32 buttonBlue = 4; + optional int32 buttonOrange = 5; + optional int32 buttonPedal = 6; + optional int32 buttonMinus = 7; + optional int32 buttonPlus = 8; + optional int32 strumUp = 9; + optional int32 strumDown = 10; + optional StickOptions stick = 11; + optional AnalogAxis whammyBar = 12; + } + + message DrumOptions + { + optional int32 buttonRed = 1; + optional int32 buttonGreen = 2; + optional int32 buttonYellow = 3; + optional int32 buttonBlue = 4; + optional int32 buttonOrange = 5; + optional int32 buttonPedal = 6; + optional int32 buttonMinus = 7; + optional int32 buttonPlus = 8; + optional StickOptions stick = 9; + } + + message TurntableOptions + { + optional int32 buttonLeftRed = 1; + optional int32 buttonLeftGreen = 2; + optional int32 buttonLeftBlue = 3; + optional int32 buttonRightRed = 4; + optional int32 buttonRightGreen = 5; + optional int32 buttonRightBlue = 6; + optional int32 buttonMinus = 7; + optional int32 buttonPlus = 8; + optional int32 buttonEuphoria = 9; + optional StickOptions stick = 10; + optional AnalogAxis leftTurntable = 11; + optional AnalogAxis rightTurntable = 12; + optional AnalogAxis effects = 13; + optional AnalogAxis fader = 14; + } + + message ControllerOptions + { + optional NunchukOptions nunchuk = 1; + optional ClassicOptions classic = 2; + optional TaikoOptions taiko = 3; + optional GuitarOptions guitar = 4; + optional DrumOptions drum = 5; + optional TurntableOptions turntable = 6; + } + optional bool enabled = 1; optional int32 i2cBlock = 2; optional int32 i2cSDAPin = 3; optional int32 i2cSCLPin = 4; optional int32 i2cSpeed = 5; + + optional ControllerOptions controllers = 6; } message SNESOptions diff --git a/src/addons/wiiext.cpp b/src/addons/wiiext.cpp index ee0097d0f..235e2ba53 100644 --- a/src/addons/wiiext.cpp +++ b/src/addons/wiiext.cpp @@ -20,6 +20,8 @@ void WiiExtensionInput::setup() { #endif uIntervalMS = 0; + + currentConfig = NULL; wii = new WiiExtension( options.i2cSDAPin, @@ -30,190 +32,501 @@ void WiiExtensionInput::setup() { wii->begin(); wii->start(); + reloadConfig(); + // Run during setup to catch boot selection mode wii->poll(); - if (wii->extensionType == WII_EXTENSION_NUNCHUCK) { - buttonZ = wii->buttonZ; - buttonC = wii->buttonC; - - leftX = map(wii->joy1X,0,1023,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - leftY = map(wii->joy1Y,1023,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - rightX = GAMEPAD_JOYSTICK_MID; - rightY = GAMEPAD_JOYSTICK_MID; - - triggerLeft = 0; - triggerRight = 0; - } else if ((wii->extensionType == WII_EXTENSION_CLASSIC) || (wii->extensionType == WII_EXTENSION_CLASSIC_PRO)) { - buttonA = wii->buttonA; - buttonB = wii->buttonB; - buttonX = wii->buttonX; - buttonY = wii->buttonY; - buttonL = wii->buttonZL; - buttonZL = wii->buttonLT; - buttonR = wii->buttonZR; - buttonZR = wii->buttonRT; - dpadUp = wii->directionUp; - dpadDown = wii->directionDown; - dpadLeft = wii->directionLeft; - dpadRight = wii->directionRight; - buttonSelect = wii->buttonMinus; - buttonStart = wii->buttonPlus; - buttonHome = wii->buttonHome; - - if (wii->extensionType == WII_EXTENSION_CLASSIC) { - triggerLeft = wii->triggerLeft; - triggerRight = wii->triggerRight; - } - - leftX = map(wii->joy1X,0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - leftY = map(wii->joy1Y,WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - rightX = map(wii->joy2X,0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - rightY = map(wii->joy2Y,WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - } else if (wii->extensionType == WII_EXTENSION_GUITAR) { - buttonSelect = wii->buttonMinus; - buttonStart = wii->buttonPlus; - - dpadUp = wii->directionUp; - dpadDown = wii->directionDown; - - buttonB = wii->fretGreen; - buttonA = wii->fretRed; - buttonX = wii->fretYellow; - buttonY = wii->fretBlue; - buttonL = wii->fretOrange; - - // whammy currently maps to Joy2X in addition to the raw whammy value - whammyBar = wii->whammyBar; - buttonR = wii->pedalButton; - - leftX = map(wii->joy1X,0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - leftY = map(wii->joy1Y,WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - rightX = map(wii->joy2X,0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - rightY = GAMEPAD_JOYSTICK_MID; - - triggerLeft = 0; - triggerRight = 0; - } else if (wii->extensionType == WII_EXTENSION_TAIKO) { - buttonL = wii->rimLeft; - buttonR = wii->rimRight; - - dpadLeft = wii->drumLeft; - buttonA = wii->drumRight; - } + update(); } void WiiExtensionInput::process() { if (nextTimer < getMillis()) { wii->poll(); - + + update(); + + nextTimer = getMillis() + uIntervalMS; + } + + if (currentConfig != NULL) { + queueAnalogChange(WiiAnalogs::WII_ANALOG_LEFT_X, leftX, lastLeftX); + queueAnalogChange(WiiAnalogs::WII_ANALOG_LEFT_Y, leftY, lastLeftY); + queueAnalogChange(WiiAnalogs::WII_ANALOG_RIGHT_X, rightX, lastRightX); + queueAnalogChange(WiiAnalogs::WII_ANALOG_RIGHT_Y, rightY, lastRightY); + queueAnalogChange(WiiAnalogs::WII_ANALOG_LEFT_TRIGGER, triggerLeft, lastTriggerLeft); + queueAnalogChange(WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER, triggerRight, lastTriggerRight); + updateAnalogState(); + + setButtonState(buttonC, WiiButtons::WII_BUTTON_C); + setButtonState(buttonZ, WiiButtons::WII_BUTTON_Z); + + setButtonState(buttonA, WiiButtons::WII_BUTTON_A); + setButtonState(buttonB, WiiButtons::WII_BUTTON_B); + setButtonState(buttonX, WiiButtons::WII_BUTTON_X); + setButtonState(buttonY, WiiButtons::WII_BUTTON_Y); + setButtonState(buttonL, WiiButtons::WII_BUTTON_L); + setButtonState(buttonZL, WiiButtons::WII_BUTTON_ZL); + setButtonState(buttonR, WiiButtons::WII_BUTTON_R); + setButtonState(buttonZR, WiiButtons::WII_BUTTON_ZR); + setButtonState(buttonSelect, WiiButtons::WII_BUTTON_MINUS); + setButtonState(buttonStart, WiiButtons::WII_BUTTON_PLUS); + setButtonState(buttonHome, WiiButtons::WII_BUTTON_HOME); + + setButtonState(dpadUp, WiiButtons::WII_BUTTON_UP); + setButtonState(dpadDown, WiiButtons::WII_BUTTON_DOWN); + setButtonState(dpadLeft, WiiButtons::WII_BUTTON_LEFT); + setButtonState(dpadRight, WiiButtons::WII_BUTTON_RIGHT); + + if (lastLeftX != leftX) lastLeftX = leftX; + if (lastLeftY != leftY) lastLeftY = leftY; + if (lastRightX != rightX) lastRightX = rightX; + if (lastRightY != rightY) lastRightY = rightY; + if (lastTriggerLeft != triggerLeft) lastTriggerLeft = triggerLeft; + if (lastTriggerRight != triggerRight) lastTriggerRight = triggerRight; + } +} + +uint16_t WiiExtensionInput::map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +uint16_t WiiExtensionInput::bounds(uint16_t x, uint16_t out_min, uint16_t out_max) { + if (x > out_max) x = out_max; + if (x < out_min) x = out_min; + return x; +} + +void WiiExtensionInput::update() { + if (wii->extensionType != WII_EXTENSION_NONE) { + currentConfig = &extensionConfigs[wii->extensionType]; + + //for (const auto& [extensionButton, value] : currentConfig->buttonMap) { + // WII_SET_MASK(buttonState, wii->getController()->buttons[extensionButton], value); + //} + if (wii->extensionType == WII_EXTENSION_NUNCHUCK) { - buttonZ = wii->buttonZ; - buttonC = wii->buttonC; + buttonZ = wii->getController()->buttons[WiiButtons::WII_BUTTON_Z]; + buttonC = wii->getController()->buttons[WiiButtons::WII_BUTTON_C]; - leftX = map(wii->joy1X,0,1023,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - leftY = map(wii->joy1Y,1023,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + leftX = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_X],0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + leftY = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_Y],WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); rightX = GAMEPAD_JOYSTICK_MID; rightY = GAMEPAD_JOYSTICK_MID; triggerLeft = 0; triggerRight = 0; } else if ((wii->extensionType == WII_EXTENSION_CLASSIC) || (wii->extensionType == WII_EXTENSION_CLASSIC_PRO)) { - buttonA = wii->buttonA; - buttonB = wii->buttonB; - buttonX = wii->buttonX; - buttonY = wii->buttonY; - buttonL = wii->buttonZL; - buttonZL = wii->buttonLT; - buttonR = wii->buttonZR; - buttonZR = wii->buttonRT; - dpadUp = wii->directionUp; - dpadDown = wii->directionDown; - dpadLeft = wii->directionLeft; - dpadRight = wii->directionRight; - buttonSelect = wii->buttonMinus; - buttonStart = wii->buttonPlus; - buttonHome = wii->buttonHome; + buttonA = wii->getController()->buttons[WiiButtons::WII_BUTTON_A]; + buttonB = wii->getController()->buttons[WiiButtons::WII_BUTTON_B]; + buttonX = wii->getController()->buttons[WiiButtons::WII_BUTTON_X]; + buttonY = wii->getController()->buttons[WiiButtons::WII_BUTTON_Y]; + buttonL = wii->getController()->buttons[WiiButtons::WII_BUTTON_L]; + buttonZL = wii->getController()->buttons[WiiButtons::WII_BUTTON_ZL]; + buttonR = wii->getController()->buttons[WiiButtons::WII_BUTTON_R]; + buttonZR = wii->getController()->buttons[WiiButtons::WII_BUTTON_ZR]; + buttonSelect = wii->getController()->buttons[WiiButtons::WII_BUTTON_MINUS]; + buttonStart = wii->getController()->buttons[WiiButtons::WII_BUTTON_PLUS]; + buttonHome = wii->getController()->buttons[WiiButtons::WII_BUTTON_HOME]; + dpadUp = wii->getController()->buttons[WiiButtons::WII_BUTTON_UP]; + dpadDown = wii->getController()->buttons[WiiButtons::WII_BUTTON_DOWN]; + dpadLeft = wii->getController()->buttons[WiiButtons::WII_BUTTON_LEFT]; + dpadRight = wii->getController()->buttons[WiiButtons::WII_BUTTON_RIGHT]; if (wii->extensionType == WII_EXTENSION_CLASSIC) { - triggerLeft = wii->triggerLeft; - triggerRight = wii->triggerRight; + triggerLeft = wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_TRIGGER]; + triggerRight = wii->getController()->analogState[WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER]; } - leftX = map(wii->joy1X,0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - leftY = map(wii->joy1Y,WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - rightX = map(wii->joy2X,0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - rightY = map(wii->joy2Y,WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + leftX = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_X],0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + leftY = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_Y],WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + rightX = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_RIGHT_X],0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + rightY = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_RIGHT_Y],WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); } else if (wii->extensionType == WII_EXTENSION_GUITAR) { - buttonSelect = wii->buttonMinus; - buttonStart = wii->buttonPlus; + buttonSelect = wii->getController()->buttons[WiiButtons::WII_BUTTON_MINUS]; + buttonStart = wii->getController()->buttons[WiiButtons::WII_BUTTON_PLUS]; - dpadUp = wii->directionUp; - dpadDown = wii->directionDown; + dpadUp = wii->getController()->buttons[WiiButtons::WII_BUTTON_UP]; + dpadDown = wii->getController()->buttons[WiiButtons::WII_BUTTON_DOWN]; - buttonB = wii->fretGreen; - buttonA = wii->fretRed; - buttonX = wii->fretYellow; - buttonY = wii->fretBlue; - buttonL = wii->fretOrange; + buttonB = wii->getController()->buttons[GuitarButtons::GUITAR_GREEN]; + buttonA = wii->getController()->buttons[GuitarButtons::GUITAR_RED]; + buttonX = wii->getController()->buttons[GuitarButtons::GUITAR_YELLOW]; + buttonY = wii->getController()->buttons[GuitarButtons::GUITAR_BLUE]; + buttonL = wii->getController()->buttons[GuitarButtons::GUITAR_ORANGE]; // whammy currently maps to Joy2X in addition to the raw whammy value - whammyBar = wii->whammyBar; - buttonR = wii->pedalButton; + whammyBar = wii->getController()->analogState[WiiAnalogs::WII_ANALOG_RIGHT_X]; + buttonR = wii->getController()->buttons[GuitarButtons::GUITAR_PEDAL]; - leftX = map(wii->joy1X,0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - leftY = map(wii->joy1Y,WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); - rightX = map(wii->joy2X,0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + leftX = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_X],0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + leftY = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_Y],WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + rightX = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_RIGHT_X],0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); rightY = GAMEPAD_JOYSTICK_MID; triggerLeft = 0; triggerRight = 0; } else if (wii->extensionType == WII_EXTENSION_TAIKO) { - buttonL = wii->rimLeft; - buttonR = wii->rimRight; + buttonL = wii->getController()->buttons[TaikoButtons::TATA_KAT_LEFT]; + buttonR = wii->getController()->buttons[TaikoButtons::TATA_KAT_RIGHT]; + + dpadLeft = wii->getController()->buttons[TaikoButtons::TATA_DON_LEFT]; + buttonA = wii->getController()->buttons[TaikoButtons::TATA_DON_RIGHT]; + } else if (wii->extensionType == WII_EXTENSION_DRUMS) { + buttonSelect = wii->getController()->buttons[WiiButtons::WII_BUTTON_MINUS]; + buttonStart = wii->getController()->buttons[WiiButtons::WII_BUTTON_PLUS]; + + buttonB = wii->getController()->buttons[DrumButtons::DRUM_RED]; + buttonA = wii->getController()->buttons[DrumButtons::DRUM_GREEN]; + buttonX = wii->getController()->buttons[DrumButtons::DRUM_YELLOW]; + buttonY = wii->getController()->buttons[DrumButtons::DRUM_BLUE]; + buttonL = wii->getController()->buttons[DrumButtons::DRUM_ORANGE]; + buttonZR = wii->getController()->buttons[DrumButtons::DRUM_PEDAL]; + + leftX = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_X],0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + leftY = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_Y],WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + rightX = GAMEPAD_JOYSTICK_MID; + rightY = GAMEPAD_JOYSTICK_MID; + + triggerLeft = 0; + triggerRight = 0; + } else if (wii->extensionType == WII_EXTENSION_TURNTABLE) { + buttonSelect = wii->getController()->buttons[WiiButtons::WII_BUTTON_MINUS]; + buttonStart = wii->getController()->buttons[WiiButtons::WII_BUTTON_PLUS]; + + dpadLeft = wii->getController()->buttons[TurntableButtons::TURNTABLE_LEFT_GREEN]; + dpadUp = wii->getController()->buttons[TurntableButtons::TURNTABLE_LEFT_RED]; + dpadRight = wii->getController()->buttons[TurntableButtons::TURNTABLE_LEFT_BLUE]; + + buttonY = wii->getController()->buttons[TurntableButtons::TURNTABLE_RIGHT_GREEN]; + buttonX = wii->getController()->buttons[TurntableButtons::TURNTABLE_RIGHT_RED]; + buttonA = wii->getController()->buttons[TurntableButtons::TURNTABLE_RIGHT_BLUE]; - dpadLeft = wii->drumLeft; - buttonA = wii->drumRight; + buttonZR = wii->getController()->buttons[TurntableButtons::TURNTABLE_EUPHORIA]; + + leftX = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_X],0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + leftY = map(wii->getController()->analogState[WiiAnalogs::WII_ANALOG_LEFT_Y],WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + rightX = map(wii->getController()->analogState[TurntableAnalogs::TURNTABLE_RIGHT],0,WII_ANALOG_PRECISION_3,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + rightY = map(wii->getController()->analogState[TurntableAnalogs::TURNTABLE_LEFT],WII_ANALOG_PRECISION_3,0,GAMEPAD_JOYSTICK_MIN,GAMEPAD_JOYSTICK_MAX); + + triggerLeft = wii->getController()->analogState[TurntableAnalogs::TURNTABLE_EFFECTS]; + triggerRight = wii->getController()->analogState[TurntableAnalogs::TURNTABLE_CROSSFADE]; } - - nextTimer = getMillis() + uIntervalMS; + } else { + currentConfig = NULL; } +} + +void WiiExtensionInput::setControllerButton(uint16_t controllerID, uint16_t buttonID, uint32_t buttonMask) { + extensionConfigs[controllerID].buttonMap[buttonID] = buttonMask; +} +void WiiExtensionInput::setControllerAnalog(uint16_t controllerID, uint16_t analogID, uint32_t axisType) { + extensionConfigs[controllerID].analogMap[analogID].axisType = axisType; +} + +void WiiExtensionInput::reloadConfig() { + const WiiOptions& wiiOptions = Storage::getInstance().getAddonOptions().wiiOptions; + + // digital mapping + setControllerButton(WII_EXTENSION_NUNCHUCK, WiiButtons::WII_BUTTON_C, wiiOptions.controllers.nunchuk.buttonC); + setControllerButton(WII_EXTENSION_NUNCHUCK, WiiButtons::WII_BUTTON_Z, wiiOptions.controllers.nunchuk.buttonZ); + + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_A, wiiOptions.controllers.classic.buttonA); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_B, wiiOptions.controllers.classic.buttonB); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_X, wiiOptions.controllers.classic.buttonX); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_Y, wiiOptions.controllers.classic.buttonY); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_L, wiiOptions.controllers.classic.buttonL); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_ZL, wiiOptions.controllers.classic.buttonZL); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_R, wiiOptions.controllers.classic.buttonR); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_ZR, wiiOptions.controllers.classic.buttonZR); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_MINUS, wiiOptions.controllers.classic.buttonMinus); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_PLUS, wiiOptions.controllers.classic.buttonPlus); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_HOME, wiiOptions.controllers.classic.buttonHome); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_UP, wiiOptions.controllers.classic.buttonUp); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_DOWN, wiiOptions.controllers.classic.buttonDown); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_LEFT, wiiOptions.controllers.classic.buttonLeft); + setControllerButton(WII_EXTENSION_CLASSIC, WiiButtons::WII_BUTTON_RIGHT, wiiOptions.controllers.classic.buttonRight); + + setControllerButton(WII_EXTENSION_TAIKO, TaikoButtons::TATA_KAT_LEFT, wiiOptions.controllers.taiko.buttonKatLeft); + setControllerButton(WII_EXTENSION_TAIKO, TaikoButtons::TATA_KAT_RIGHT, wiiOptions.controllers.taiko.buttonKatRight); + setControllerButton(WII_EXTENSION_TAIKO, TaikoButtons::TATA_DON_LEFT, wiiOptions.controllers.taiko.buttonDonLeft); + setControllerButton(WII_EXTENSION_TAIKO, TaikoButtons::TATA_DON_RIGHT, wiiOptions.controllers.taiko.buttonDonRight); + + setControllerButton(WII_EXTENSION_GUITAR, GuitarButtons::GUITAR_RED, wiiOptions.controllers.guitar.buttonRed); + setControllerButton(WII_EXTENSION_GUITAR, GuitarButtons::GUITAR_GREEN, wiiOptions.controllers.guitar.buttonGreen); + setControllerButton(WII_EXTENSION_GUITAR, GuitarButtons::GUITAR_YELLOW, wiiOptions.controllers.guitar.buttonYellow); + setControllerButton(WII_EXTENSION_GUITAR, GuitarButtons::GUITAR_BLUE, wiiOptions.controllers.guitar.buttonBlue); + setControllerButton(WII_EXTENSION_GUITAR, GuitarButtons::GUITAR_ORANGE, wiiOptions.controllers.guitar.buttonOrange); + setControllerButton(WII_EXTENSION_GUITAR, GuitarButtons::GUITAR_PEDAL, wiiOptions.controllers.guitar.buttonPedal); + setControllerButton(WII_EXTENSION_GUITAR, WiiButtons::WII_BUTTON_MINUS, wiiOptions.controllers.guitar.buttonMinus); + setControllerButton(WII_EXTENSION_GUITAR, WiiButtons::WII_BUTTON_PLUS, wiiOptions.controllers.guitar.buttonPlus); + setControllerButton(WII_EXTENSION_GUITAR, WiiButtons::WII_BUTTON_UP, wiiOptions.controllers.guitar.strumUp); + setControllerButton(WII_EXTENSION_GUITAR, WiiButtons::WII_BUTTON_DOWN, wiiOptions.controllers.guitar.strumDown); + + setControllerButton(WII_EXTENSION_DRUMS, DrumButtons::DRUM_RED, wiiOptions.controllers.drum.buttonRed); + setControllerButton(WII_EXTENSION_DRUMS, DrumButtons::DRUM_GREEN, wiiOptions.controllers.drum.buttonGreen); + setControllerButton(WII_EXTENSION_DRUMS, DrumButtons::DRUM_YELLOW, wiiOptions.controllers.drum.buttonYellow); + setControllerButton(WII_EXTENSION_DRUMS, DrumButtons::DRUM_BLUE, wiiOptions.controllers.drum.buttonBlue); + setControllerButton(WII_EXTENSION_DRUMS, DrumButtons::DRUM_ORANGE, wiiOptions.controllers.drum.buttonOrange); + setControllerButton(WII_EXTENSION_DRUMS, DrumButtons::DRUM_PEDAL, wiiOptions.controllers.drum.buttonPedal); + setControllerButton(WII_EXTENSION_DRUMS, WiiButtons::WII_BUTTON_MINUS, wiiOptions.controllers.drum.buttonMinus); + setControllerButton(WII_EXTENSION_DRUMS, WiiButtons::WII_BUTTON_PLUS, wiiOptions.controllers.drum.buttonPlus); + + setControllerButton(WII_EXTENSION_TURNTABLE, TurntableButtons::TURNTABLE_LEFT_RED, wiiOptions.controllers.turntable.buttonLeftRed); + setControllerButton(WII_EXTENSION_TURNTABLE, TurntableButtons::TURNTABLE_LEFT_GREEN, wiiOptions.controllers.turntable.buttonLeftGreen); + setControllerButton(WII_EXTENSION_TURNTABLE, TurntableButtons::TURNTABLE_LEFT_BLUE, wiiOptions.controllers.turntable.buttonLeftBlue); + setControllerButton(WII_EXTENSION_TURNTABLE, TurntableButtons::TURNTABLE_RIGHT_RED, wiiOptions.controllers.turntable.buttonRightRed); + setControllerButton(WII_EXTENSION_TURNTABLE, TurntableButtons::TURNTABLE_RIGHT_GREEN, wiiOptions.controllers.turntable.buttonRightGreen); + setControllerButton(WII_EXTENSION_TURNTABLE, TurntableButtons::TURNTABLE_RIGHT_BLUE, wiiOptions.controllers.turntable.buttonRightBlue); + setControllerButton(WII_EXTENSION_TURNTABLE, TurntableButtons::TURNTABLE_EUPHORIA, wiiOptions.controllers.turntable.buttonEuphoria); + setControllerButton(WII_EXTENSION_TURNTABLE, WiiButtons::WII_BUTTON_MINUS, wiiOptions.controllers.turntable.buttonMinus); + setControllerButton(WII_EXTENSION_TURNTABLE, WiiButtons::WII_BUTTON_PLUS, wiiOptions.controllers.turntable.buttonPlus); + + // analog mapping + setControllerAnalog(WII_EXTENSION_NUNCHUCK, WiiAnalogs::WII_ANALOG_LEFT_X, wiiOptions.controllers.nunchuk.stick.x.axisType); + setControllerAnalog(WII_EXTENSION_NUNCHUCK, WiiAnalogs::WII_ANALOG_LEFT_Y, wiiOptions.controllers.nunchuk.stick.y.axisType); + + setControllerAnalog(WII_EXTENSION_CLASSIC, WiiAnalogs::WII_ANALOG_LEFT_X, wiiOptions.controllers.classic.leftStick.x.axisType); + setControllerAnalog(WII_EXTENSION_CLASSIC, WiiAnalogs::WII_ANALOG_LEFT_Y, wiiOptions.controllers.classic.leftStick.y.axisType); + setControllerAnalog(WII_EXTENSION_CLASSIC, WiiAnalogs::WII_ANALOG_RIGHT_X, wiiOptions.controllers.classic.rightStick.x.axisType); + setControllerAnalog(WII_EXTENSION_CLASSIC, WiiAnalogs::WII_ANALOG_RIGHT_Y, wiiOptions.controllers.classic.rightStick.y.axisType); + setControllerAnalog(WII_EXTENSION_CLASSIC, WiiAnalogs::WII_ANALOG_LEFT_TRIGGER, wiiOptions.controllers.classic.leftTrigger.axisType); + setControllerAnalog(WII_EXTENSION_CLASSIC, WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER, wiiOptions.controllers.classic.rightTrigger.axisType); + + setControllerAnalog(WII_EXTENSION_GUITAR, WiiAnalogs::WII_ANALOG_LEFT_X, wiiOptions.controllers.guitar.stick.x.axisType); + setControllerAnalog(WII_EXTENSION_GUITAR, WiiAnalogs::WII_ANALOG_LEFT_Y, wiiOptions.controllers.guitar.stick.y.axisType); + setControllerAnalog(WII_EXTENSION_GUITAR, WiiAnalogs::WII_ANALOG_RIGHT_X, wiiOptions.controllers.guitar.whammyBar.axisType); + + setControllerAnalog(WII_EXTENSION_DRUMS, WiiAnalogs::WII_ANALOG_LEFT_X, wiiOptions.controllers.drum.stick.x.axisType); + setControllerAnalog(WII_EXTENSION_DRUMS, WiiAnalogs::WII_ANALOG_LEFT_Y, wiiOptions.controllers.drum.stick.y.axisType); + + setControllerAnalog(WII_EXTENSION_TURNTABLE, WiiAnalogs::WII_ANALOG_LEFT_X, wiiOptions.controllers.turntable.stick.x.axisType); + setControllerAnalog(WII_EXTENSION_TURNTABLE, WiiAnalogs::WII_ANALOG_LEFT_Y, wiiOptions.controllers.turntable.stick.y.axisType); + setControllerAnalog(WII_EXTENSION_TURNTABLE, WiiAnalogs::WII_ANALOG_RIGHT_X, wiiOptions.controllers.turntable.leftTurntable.axisType); + setControllerAnalog(WII_EXTENSION_TURNTABLE, WiiAnalogs::WII_ANALOG_RIGHT_Y, wiiOptions.controllers.turntable.rightTurntable.axisType); + setControllerAnalog(WII_EXTENSION_TURNTABLE, WiiAnalogs::WII_ANALOG_LEFT_TRIGGER, wiiOptions.controllers.turntable.effects.axisType); + setControllerAnalog(WII_EXTENSION_TURNTABLE, WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER, wiiOptions.controllers.turntable.fader.axisType); +} + +void WiiExtensionInput::setButtonState(bool buttonState, uint16_t buttonMask) { Gamepad * gamepad = Storage::getInstance().GetGamepad(); - gamepad->state.lx = leftX; - gamepad->state.ly = leftY; - gamepad->state.rx = rightX; - gamepad->state.ry = rightY; + if (buttonState) { + if (currentConfig->buttonMap[buttonMask] > GAMEPAD_MASK_A2) { + if (((currentConfig->buttonMap[buttonMask] >> 16) & GAMEPAD_MASK_UP) == GAMEPAD_MASK_UP) gamepad->state.dpad |= ((currentConfig->buttonMap[buttonMask] >> 16) & GAMEPAD_MASK_UP); + if (((currentConfig->buttonMap[buttonMask] >> 16) & GAMEPAD_MASK_DOWN) == GAMEPAD_MASK_DOWN) gamepad->state.dpad |= ((currentConfig->buttonMap[buttonMask] >> 16) & GAMEPAD_MASK_DOWN); + if (((currentConfig->buttonMap[buttonMask] >> 16) & GAMEPAD_MASK_LEFT) == GAMEPAD_MASK_LEFT) gamepad->state.dpad |= ((currentConfig->buttonMap[buttonMask] >> 16) & GAMEPAD_MASK_LEFT); + if (((currentConfig->buttonMap[buttonMask] >> 16) & GAMEPAD_MASK_RIGHT) == GAMEPAD_MASK_RIGHT) gamepad->state.dpad |= ((currentConfig->buttonMap[buttonMask] >> 16) & GAMEPAD_MASK_RIGHT); + } else { + gamepad->state.buttons |= currentConfig->buttonMap[buttonMask]; + } + } +} - if (wii->extensionType == WII_EXTENSION_CLASSIC) { - gamepad->hasAnalogTriggers = true; - gamepad->state.lt = triggerLeft; - gamepad->state.rt = triggerRight; - } else { - gamepad->hasAnalogTriggers = false; +void WiiExtensionInput::queueAnalogChange(uint16_t analogInput, uint16_t analogValue, uint16_t lastAnalogValue) { + if (analogInput != lastAnalogValue) analogChanges[currentConfig->analogMap[analogInput].axisType].push_back({analogInput, analogValue}); +} + +void WiiExtensionInput::updateAnalogState() { + Gamepad * gamepad = Storage::getInstance().GetGamepad(); + gamepad->hasAnalogTriggers = true; + + uint16_t axisType; + uint16_t analogInput; + uint16_t analogValue; + + uint16_t axisToChange; + uint16_t adjustedValue; + + uint16_t minValue = GAMEPAD_JOYSTICK_MIN; + uint16_t midValue = GAMEPAD_JOYSTICK_MID; + uint16_t maxValue = GAMEPAD_JOYSTICK_MAX; + + std::map> axesOfChange = { + {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_LEFT_TRIGGER,{}}, + {WII_ANALOG_TYPE_RIGHT_TRIGGER,{}} + }; + + for (auto currChange = analogChanges.begin(); currChange != analogChanges.end(); ++currChange) { + if (!currChange->second.empty()) { + // this analog type has changes. get the last one, use it, and clear the list. + axisType = currChange->first; + analogInput = currChange->second.front().analogInput; + analogValue = getAverage(currChange->second); + currChange->second.clear(); + + axisToChange = WII_ANALOG_TYPE_NONE; + adjustedValue = 0; + + // define ranges + switch (analogInput) { + case WiiAnalogs::WII_ANALOG_LEFT_X: + case WiiAnalogs::WII_ANALOG_LEFT_Y: + case WiiAnalogs::WII_ANALOG_RIGHT_X: + case WiiAnalogs::WII_ANALOG_RIGHT_Y: + minValue = GAMEPAD_JOYSTICK_MIN; + midValue = GAMEPAD_JOYSTICK_MID; + maxValue = GAMEPAD_JOYSTICK_MAX; + break; + case WiiAnalogs::WII_ANALOG_LEFT_TRIGGER: + case WiiAnalogs::WII_ANALOG_RIGHT_TRIGGER: + minValue = GAMEPAD_TRIGGER_MIN; + midValue = GAMEPAD_TRIGGER_MID; + maxValue = GAMEPAD_TRIGGER_MAX; + break; + } + + switch (axisType) { + case WII_ANALOG_TYPE_LEFT_STICK_X: + axisToChange = WII_ANALOG_TYPE_LEFT_STICK_X; + adjustedValue = bounds(analogValue,minValue,maxValue); + break; + case WII_ANALOG_TYPE_LEFT_STICK_Y: + axisToChange = WII_ANALOG_TYPE_LEFT_STICK_Y; + adjustedValue = bounds(analogValue,minValue,maxValue); + break; + case WII_ANALOG_TYPE_RIGHT_STICK_X: + axisToChange = WII_ANALOG_TYPE_RIGHT_STICK_X; + adjustedValue = bounds(analogValue,minValue,maxValue); + break; + case WII_ANALOG_TYPE_RIGHT_STICK_Y: + axisToChange = WII_ANALOG_TYPE_RIGHT_STICK_Y; + adjustedValue = bounds(analogValue,minValue,maxValue); + break; + case WII_ANALOG_TYPE_DPAD_X: + if (analogValue < midValue/2) gamepad->state.dpad |= GAMEPAD_MASK_LEFT; + if (analogValue > midValue+(midValue/2)) gamepad->state.dpad |= GAMEPAD_MASK_RIGHT; + break; + case WII_ANALOG_TYPE_DPAD_Y: + if (analogValue < midValue/2) gamepad->state.dpad |= GAMEPAD_MASK_UP; + if (analogValue > midValue+(midValue/2)) gamepad->state.dpad |= GAMEPAD_MASK_DOWN; + break; + case WII_ANALOG_TYPE_LEFT_TRIGGER: + axisToChange = WII_ANALOG_TYPE_LEFT_TRIGGER; + adjustedValue = bounds(analogValue,minValue,maxValue); + break; + case WII_ANALOG_TYPE_RIGHT_TRIGGER: + axisToChange = WII_ANALOG_TYPE_RIGHT_TRIGGER; + adjustedValue = bounds(analogValue,minValue,maxValue); + break; + // advanced types + case WII_ANALOG_TYPE_LEFT_STICK_X_PLUS: + axisToChange = WII_ANALOG_TYPE_LEFT_STICK_X; + adjustedValue = map(analogValue,minValue,maxValue,GAMEPAD_JOYSTICK_MID,GAMEPAD_JOYSTICK_MAX); + minValue = GAMEPAD_JOYSTICK_MID; + maxValue = GAMEPAD_JOYSTICK_MAX; + break; + case WII_ANALOG_TYPE_LEFT_STICK_X_MINUS: + axisToChange = WII_ANALOG_TYPE_LEFT_STICK_X; + adjustedValue = map(analogValue,minValue,maxValue,GAMEPAD_JOYSTICK_MID,GAMEPAD_JOYSTICK_MIN); + minValue = GAMEPAD_JOYSTICK_MIN; + maxValue = GAMEPAD_JOYSTICK_MID; + break; + case WII_ANALOG_TYPE_LEFT_STICK_Y_PLUS: + axisToChange = WII_ANALOG_TYPE_LEFT_STICK_Y; + adjustedValue = map(analogValue,minValue,maxValue,GAMEPAD_JOYSTICK_MID,GAMEPAD_JOYSTICK_MAX); + minValue = GAMEPAD_JOYSTICK_MID; + maxValue = GAMEPAD_JOYSTICK_MAX; + break; + case WII_ANALOG_TYPE_LEFT_STICK_Y_MINUS: + axisToChange = WII_ANALOG_TYPE_LEFT_STICK_Y; + adjustedValue = map(analogValue,minValue,maxValue,GAMEPAD_JOYSTICK_MID,GAMEPAD_JOYSTICK_MIN); + minValue = GAMEPAD_JOYSTICK_MIN; + maxValue = GAMEPAD_JOYSTICK_MID; + break; + case WII_ANALOG_TYPE_RIGHT_STICK_X_PLUS: + axisToChange = WII_ANALOG_TYPE_RIGHT_STICK_X; + adjustedValue = map(analogValue,minValue,maxValue,GAMEPAD_JOYSTICK_MID,GAMEPAD_JOYSTICK_MAX); + minValue = GAMEPAD_JOYSTICK_MID; + maxValue = GAMEPAD_JOYSTICK_MAX; + break; + case WII_ANALOG_TYPE_RIGHT_STICK_X_MINUS: + axisToChange = WII_ANALOG_TYPE_RIGHT_STICK_X; + adjustedValue = map(analogValue,minValue,maxValue,GAMEPAD_JOYSTICK_MID,GAMEPAD_JOYSTICK_MIN); + minValue = GAMEPAD_JOYSTICK_MIN; + maxValue = GAMEPAD_JOYSTICK_MID; + break; + case WII_ANALOG_TYPE_RIGHT_STICK_Y_PLUS: + axisToChange = WII_ANALOG_TYPE_RIGHT_STICK_Y; + adjustedValue = map(analogValue,minValue,maxValue,GAMEPAD_JOYSTICK_MID,GAMEPAD_JOYSTICK_MAX); + minValue = GAMEPAD_JOYSTICK_MID; + maxValue = GAMEPAD_JOYSTICK_MAX; + break; + case WII_ANALOG_TYPE_RIGHT_STICK_Y_MINUS: + axisToChange = WII_ANALOG_TYPE_RIGHT_STICK_Y; + adjustedValue = map(analogValue,minValue,maxValue,GAMEPAD_JOYSTICK_MID,GAMEPAD_JOYSTICK_MIN); + minValue = GAMEPAD_JOYSTICK_MIN; + maxValue = GAMEPAD_JOYSTICK_MID; + break; + } + + if (axisToChange != WII_ANALOG_TYPE_NONE) axesOfChange[axisToChange].push_back(bounds(adjustedValue,minValue,maxValue)); + } } - if (buttonC) gamepad->state.buttons |= GAMEPAD_MASK_B1; - if (buttonZ) gamepad->state.buttons |= GAMEPAD_MASK_B2; - - if (buttonA) gamepad->state.buttons |= GAMEPAD_MASK_B2; - if (buttonB) gamepad->state.buttons |= GAMEPAD_MASK_B1; - if (buttonX) gamepad->state.buttons |= GAMEPAD_MASK_B4; - if (buttonY) gamepad->state.buttons |= GAMEPAD_MASK_B3; - if (buttonL) gamepad->state.buttons |= GAMEPAD_MASK_L1; - if (buttonZL) gamepad->state.buttons |= GAMEPAD_MASK_L2; - if (buttonR) gamepad->state.buttons |= GAMEPAD_MASK_R1; - if (buttonZR) gamepad->state.buttons |= GAMEPAD_MASK_R2; - if (buttonSelect) gamepad->state.buttons |= GAMEPAD_MASK_S1; - if (buttonStart) gamepad->state.buttons |= GAMEPAD_MASK_S2; - if (buttonHome) gamepad->state.buttons |= GAMEPAD_MASK_A1; - if (dpadUp) gamepad->state.dpad |= GAMEPAD_MASK_UP; - if (dpadDown) gamepad->state.dpad |= GAMEPAD_MASK_DOWN; - if (dpadLeft) gamepad->state.dpad |= GAMEPAD_MASK_LEFT; - if (dpadRight) gamepad->state.dpad |= GAMEPAD_MASK_RIGHT; + for (auto currAxis = axesOfChange.begin(); currAxis != axesOfChange.end(); ++currAxis) { + if (!currAxis->second.empty()) { + axisType = currAxis->first; + + switch (axisType) { + case WII_ANALOG_TYPE_LEFT_STICK_X: + gamepad->state.lx = getDelta(currAxis->second, GAMEPAD_JOYSTICK_MID); + break; + case WII_ANALOG_TYPE_LEFT_STICK_Y: + gamepad->state.ly = getDelta(currAxis->second, GAMEPAD_JOYSTICK_MID); + break; + case WII_ANALOG_TYPE_RIGHT_STICK_X: + gamepad->state.rx = getDelta(currAxis->second, GAMEPAD_JOYSTICK_MID); + break; + case WII_ANALOG_TYPE_RIGHT_STICK_Y: + gamepad->state.ry = getDelta(currAxis->second, GAMEPAD_JOYSTICK_MID); + break; + case WII_ANALOG_TYPE_LEFT_TRIGGER: + gamepad->state.lt = getDelta(currAxis->second, GAMEPAD_TRIGGER_MID); + break; + case WII_ANALOG_TYPE_RIGHT_TRIGGER: + gamepad->state.rt = getDelta(currAxis->second, GAMEPAD_TRIGGER_MID); + break; + } + } + } } -uint16_t WiiExtensionInput::map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +uint16_t WiiExtensionInput::getAverage(std::vector const& changes) { + uint16_t values = 0; + + if (changes.empty()) { + return 0; + } + + for (auto currVal = changes.begin(); currVal != changes.end(); ++currVal) { + values += currVal->analogValue; + } + + return values / changes.size(); } + +uint16_t WiiExtensionInput::getDelta(std::vector const& changes, uint16_t baseValue) { + uint16_t value = baseValue; + + if (changes.empty()) { + return baseValue; + } + + for (auto currVal = changes.begin(); currVal != changes.end(); ++currVal) { + if (*currVal != baseValue) { + if (*currVal < baseValue) { + value -= (baseValue - *currVal); + } else if (*currVal > baseValue) { + value += (*currVal - baseValue); + } + } + } + + return value; +} \ No newline at end of file diff --git a/src/configs/webconfig.cpp b/src/configs/webconfig.cpp index 28a8393a0..eedfd6c16 100644 --- a/src/configs/webconfig.cpp +++ b/src/configs/webconfig.cpp @@ -1211,6 +1211,170 @@ std::string setPS4Options() return "{\"success\":true}"; } +std::string setWiiControls() +{ + DynamicJsonDocument doc = get_post_data(); + WiiOptions& wiiOptions = Storage::getInstance().getAddonOptions().wiiOptions; + + readDoc(wiiOptions.controllers.nunchuk.buttonC, doc, "nunchuk.buttonC"); + readDoc(wiiOptions.controllers.nunchuk.buttonZ, doc, "nunchuk.buttonZ"); + readDoc(wiiOptions.controllers.nunchuk.stick.x.axisType, doc, "nunchuk.analogStick.x.axisType"); + readDoc(wiiOptions.controllers.nunchuk.stick.y.axisType, doc, "nunchuk.analogStick.y.axisType"); + + readDoc(wiiOptions.controllers.classic.buttonA, doc, "classic.buttonA"); + readDoc(wiiOptions.controllers.classic.buttonB, doc, "classic.buttonB"); + readDoc(wiiOptions.controllers.classic.buttonX, doc, "classic.buttonX"); + readDoc(wiiOptions.controllers.classic.buttonY, doc, "classic.buttonY"); + readDoc(wiiOptions.controllers.classic.buttonL, doc, "classic.buttonL"); + readDoc(wiiOptions.controllers.classic.buttonZL, doc, "classic.buttonZL"); + readDoc(wiiOptions.controllers.classic.buttonR, doc, "classic.buttonR"); + readDoc(wiiOptions.controllers.classic.buttonZR, doc, "classic.buttonZR"); + readDoc(wiiOptions.controllers.classic.buttonMinus, doc, "classic.buttonMinus"); + readDoc(wiiOptions.controllers.classic.buttonPlus, doc, "classic.buttonPlus"); + readDoc(wiiOptions.controllers.classic.buttonHome, doc, "classic.buttonHome"); + readDoc(wiiOptions.controllers.classic.buttonUp, doc, "classic.buttonUp"); + readDoc(wiiOptions.controllers.classic.buttonDown, doc, "classic.buttonDown"); + readDoc(wiiOptions.controllers.classic.buttonLeft, doc, "classic.buttonLeft"); + readDoc(wiiOptions.controllers.classic.buttonRight, doc, "classic.buttonRight"); + readDoc(wiiOptions.controllers.classic.leftStick.x.axisType, doc, "classic.analogLeftStick.x.axisType"); + readDoc(wiiOptions.controllers.classic.leftStick.y.axisType, doc, "classic.analogLeftStick.y.axisType"); + readDoc(wiiOptions.controllers.classic.rightStick.x.axisType, doc, "classic.analogRightStick.x.axisType"); + readDoc(wiiOptions.controllers.classic.rightStick.y.axisType, doc, "classic.analogRightStick.y.axisType"); + readDoc(wiiOptions.controllers.classic.leftTrigger.axisType, doc, "classic.analogLeftTrigger.axisType"); + readDoc(wiiOptions.controllers.classic.rightTrigger.axisType, doc, "classic.analogRightTrigger.axisType"); + + readDoc(wiiOptions.controllers.taiko.buttonKatLeft, doc, "taiko.buttonKatLeft"); + readDoc(wiiOptions.controllers.taiko.buttonKatRight, doc, "taiko.buttonKatRight"); + readDoc(wiiOptions.controllers.taiko.buttonDonLeft, doc, "taiko.buttonDonLeft"); + readDoc(wiiOptions.controllers.taiko.buttonDonRight, doc, "taiko.buttonDonRight"); + + readDoc(wiiOptions.controllers.guitar.buttonRed, doc, "guitar.buttonRed"); + readDoc(wiiOptions.controllers.guitar.buttonGreen, doc, "guitar.buttonGreen"); + readDoc(wiiOptions.controllers.guitar.buttonYellow, doc, "guitar.buttonYellow"); + readDoc(wiiOptions.controllers.guitar.buttonBlue, doc, "guitar.buttonBlue"); + readDoc(wiiOptions.controllers.guitar.buttonOrange, doc, "guitar.buttonOrange"); + readDoc(wiiOptions.controllers.guitar.buttonPedal, doc, "guitar.buttonPedal"); + readDoc(wiiOptions.controllers.guitar.buttonMinus, doc, "guitar.buttonMinus"); + readDoc(wiiOptions.controllers.guitar.buttonPlus, doc, "guitar.buttonPlus"); + readDoc(wiiOptions.controllers.guitar.strumUp, doc, "guitar.strumUp"); + readDoc(wiiOptions.controllers.guitar.strumDown, doc, "guitar.strumDown"); + readDoc(wiiOptions.controllers.guitar.stick.x.axisType, doc, "guitar.analogStick.x.axisType"); + readDoc(wiiOptions.controllers.guitar.stick.y.axisType, doc, "guitar.analogStick.y.axisType"); + readDoc(wiiOptions.controllers.guitar.whammyBar.axisType, doc, "guitar.analogWhammyBar.axisType"); + + readDoc(wiiOptions.controllers.drum.buttonRed, doc, "drum.buttonRed"); + readDoc(wiiOptions.controllers.drum.buttonGreen, doc, "drum.buttonGreen"); + readDoc(wiiOptions.controllers.drum.buttonYellow, doc, "drum.buttonYellow"); + readDoc(wiiOptions.controllers.drum.buttonBlue, doc, "drum.buttonBlue"); + readDoc(wiiOptions.controllers.drum.buttonOrange, doc, "drum.buttonOrange"); + readDoc(wiiOptions.controllers.drum.buttonPedal, doc, "drum.buttonPedal"); + readDoc(wiiOptions.controllers.drum.buttonMinus, doc, "drum.buttonMinus"); + readDoc(wiiOptions.controllers.drum.buttonPlus, doc, "drum.buttonPlus"); + readDoc(wiiOptions.controllers.drum.stick.x.axisType, doc, "drum.analogStick.x.axisType"); + readDoc(wiiOptions.controllers.drum.stick.y.axisType, doc, "drum.analogStick.y.axisType"); + + readDoc(wiiOptions.controllers.turntable.buttonLeftRed, doc, "turntable.buttonLeftRed"); + readDoc(wiiOptions.controllers.turntable.buttonLeftGreen, doc, "turntable.buttonLeftGreen"); + readDoc(wiiOptions.controllers.turntable.buttonLeftBlue, doc, "turntable.buttonLeftBlue"); + readDoc(wiiOptions.controllers.turntable.buttonRightRed, doc, "turntable.buttonRightRed"); + readDoc(wiiOptions.controllers.turntable.buttonRightGreen, doc, "turntable.buttonRightGreen"); + readDoc(wiiOptions.controllers.turntable.buttonRightBlue, doc, "turntable.buttonRightBlue"); + readDoc(wiiOptions.controllers.turntable.buttonMinus, doc, "turntable.buttonMinus"); + readDoc(wiiOptions.controllers.turntable.buttonPlus, doc, "turntable.buttonPlus"); + readDoc(wiiOptions.controllers.turntable.buttonEuphoria, doc, "turntable.buttonEuphoria"); + readDoc(wiiOptions.controllers.turntable.stick.x.axisType, doc, "turntable.analogStick.x.axisType"); + readDoc(wiiOptions.controllers.turntable.stick.y.axisType, doc, "turntable.analogStick.y.axisType"); + readDoc(wiiOptions.controllers.turntable.leftTurntable.axisType, doc, "turntable.analogLeftTurntable.axisType"); + readDoc(wiiOptions.controllers.turntable.rightTurntable.axisType, doc, "turntable.analogRightTurntable.axisType"); + readDoc(wiiOptions.controllers.turntable.effects.axisType, doc, "turntable.analogEffects.axisType"); + readDoc(wiiOptions.controllers.turntable.fader.axisType, doc, "turntable.analogFader.axisType"); + + Storage::getInstance().save(); + + return "{\"success\":true}"; +} + +std::string getWiiControls() +{ + DynamicJsonDocument doc(LWIP_HTTPD_POST_MAX_PAYLOAD_LEN); + WiiOptions& wiiOptions = Storage::getInstance().getAddonOptions().wiiOptions; + + writeDoc(doc, "nunchuk.buttonC", wiiOptions.controllers.nunchuk.buttonC); + writeDoc(doc, "nunchuk.buttonZ", wiiOptions.controllers.nunchuk.buttonZ); + writeDoc(doc, "nunchuk.analogStick.x.axisType", wiiOptions.controllers.nunchuk.stick.x.axisType); + writeDoc(doc, "nunchuk.analogStick.y.axisType", wiiOptions.controllers.nunchuk.stick.y.axisType); + + writeDoc(doc, "classic.buttonA", wiiOptions.controllers.classic.buttonA); + writeDoc(doc, "classic.buttonB", wiiOptions.controllers.classic.buttonB); + writeDoc(doc, "classic.buttonX", wiiOptions.controllers.classic.buttonX); + writeDoc(doc, "classic.buttonY", wiiOptions.controllers.classic.buttonY); + writeDoc(doc, "classic.buttonL", wiiOptions.controllers.classic.buttonL); + writeDoc(doc, "classic.buttonZL", wiiOptions.controllers.classic.buttonZL); + writeDoc(doc, "classic.buttonR", wiiOptions.controllers.classic.buttonR); + writeDoc(doc, "classic.buttonZR", wiiOptions.controllers.classic.buttonZR); + writeDoc(doc, "classic.buttonMinus", wiiOptions.controllers.classic.buttonMinus); + writeDoc(doc, "classic.buttonPlus", wiiOptions.controllers.classic.buttonPlus); + writeDoc(doc, "classic.buttonHome", wiiOptions.controllers.classic.buttonHome); + writeDoc(doc, "classic.buttonUp", wiiOptions.controllers.classic.buttonUp); + writeDoc(doc, "classic.buttonDown", wiiOptions.controllers.classic.buttonDown); + writeDoc(doc, "classic.buttonLeft", wiiOptions.controllers.classic.buttonLeft); + writeDoc(doc, "classic.buttonRight", wiiOptions.controllers.classic.buttonRight); + writeDoc(doc, "classic.analogLeftStick.x.axisType", wiiOptions.controllers.classic.leftStick.x.axisType); + writeDoc(doc, "classic.analogLeftStick.y.axisType", wiiOptions.controllers.classic.leftStick.y.axisType); + writeDoc(doc, "classic.analogRightStick.x.axisType", wiiOptions.controllers.classic.rightStick.x.axisType); + writeDoc(doc, "classic.analogRightStick.y.axisType", wiiOptions.controllers.classic.rightStick.y.axisType); + writeDoc(doc, "classic.analogLeftTrigger.axisType", wiiOptions.controllers.classic.leftTrigger.axisType); + writeDoc(doc, "classic.analogRightTrigger.axisType", wiiOptions.controllers.classic.rightTrigger.axisType); + + writeDoc(doc, "taiko.buttonKatLeft", wiiOptions.controllers.taiko.buttonKatLeft); + writeDoc(doc, "taiko.buttonKatRight", wiiOptions.controllers.taiko.buttonKatRight); + writeDoc(doc, "taiko.buttonDonLeft", wiiOptions.controllers.taiko.buttonDonLeft); + writeDoc(doc, "taiko.buttonDonRight", wiiOptions.controllers.taiko.buttonDonRight); + + writeDoc(doc, "guitar.buttonRed", wiiOptions.controllers.guitar.buttonRed); + writeDoc(doc, "guitar.buttonGreen", wiiOptions.controllers.guitar.buttonGreen); + writeDoc(doc, "guitar.buttonYellow", wiiOptions.controllers.guitar.buttonYellow); + writeDoc(doc, "guitar.buttonBlue", wiiOptions.controllers.guitar.buttonBlue); + writeDoc(doc, "guitar.buttonOrange", wiiOptions.controllers.guitar.buttonOrange); + writeDoc(doc, "guitar.buttonPedal", wiiOptions.controllers.guitar.buttonPedal); + writeDoc(doc, "guitar.buttonMinus", wiiOptions.controllers.guitar.buttonMinus); + writeDoc(doc, "guitar.buttonPlus", wiiOptions.controllers.guitar.buttonPlus); + writeDoc(doc, "guitar.strumUp", wiiOptions.controllers.guitar.strumUp); + writeDoc(doc, "guitar.strumDown", wiiOptions.controllers.guitar.strumDown); + writeDoc(doc, "guitar.analogStick.x.axisType", wiiOptions.controllers.guitar.stick.x.axisType); + writeDoc(doc, "guitar.analogStick.y.axisType", wiiOptions.controllers.guitar.stick.y.axisType); + writeDoc(doc, "guitar.analogWhammyBar.axisType", wiiOptions.controllers.guitar.whammyBar.axisType); + + writeDoc(doc, "drum.buttonRed", wiiOptions.controllers.drum.buttonRed); + writeDoc(doc, "drum.buttonGreen", wiiOptions.controllers.drum.buttonGreen); + writeDoc(doc, "drum.buttonYellow", wiiOptions.controllers.drum.buttonYellow); + writeDoc(doc, "drum.buttonBlue", wiiOptions.controllers.drum.buttonBlue); + writeDoc(doc, "drum.buttonOrange", wiiOptions.controllers.drum.buttonOrange); + writeDoc(doc, "drum.buttonPedal", wiiOptions.controllers.drum.buttonPedal); + writeDoc(doc, "drum.buttonMinus", wiiOptions.controllers.drum.buttonMinus); + writeDoc(doc, "drum.buttonPlus", wiiOptions.controllers.drum.buttonPlus); + writeDoc(doc, "drum.analogStick.x.axisType", wiiOptions.controllers.drum.stick.x.axisType); + writeDoc(doc, "drum.analogStick.y.axisType", wiiOptions.controllers.drum.stick.y.axisType); + + writeDoc(doc, "turntable.buttonLeftRed", wiiOptions.controllers.turntable.buttonLeftRed); + writeDoc(doc, "turntable.buttonLeftGreen", wiiOptions.controllers.turntable.buttonLeftGreen); + writeDoc(doc, "turntable.buttonLeftBlue", wiiOptions.controllers.turntable.buttonLeftBlue); + writeDoc(doc, "turntable.buttonRightRed", wiiOptions.controllers.turntable.buttonRightRed); + writeDoc(doc, "turntable.buttonRightGreen", wiiOptions.controllers.turntable.buttonRightGreen); + writeDoc(doc, "turntable.buttonRightBlue", wiiOptions.controllers.turntable.buttonRightBlue); + writeDoc(doc, "turntable.buttonMinus", wiiOptions.controllers.turntable.buttonMinus); + writeDoc(doc, "turntable.buttonPlus", wiiOptions.controllers.turntable.buttonPlus); + writeDoc(doc, "turntable.buttonEuphoria", wiiOptions.controllers.turntable.buttonEuphoria); + writeDoc(doc, "turntable.analogStick.x.axisType", wiiOptions.controllers.turntable.stick.x.axisType); + writeDoc(doc, "turntable.analogStick.x.axisType", wiiOptions.controllers.turntable.stick.y.axisType); + writeDoc(doc, "turntable.analogLeftTurntable.axisType", wiiOptions.controllers.turntable.leftTurntable.axisType); + writeDoc(doc, "turntable.analogRightTurntable.axisType", wiiOptions.controllers.turntable.rightTurntable.axisType); + writeDoc(doc, "turntable.analogEffects.axisType", wiiOptions.controllers.turntable.effects.axisType); + writeDoc(doc, "turntable.analogFader.axisType", wiiOptions.controllers.turntable.fader.axisType); + + return serialize_json(doc); +} + std::string getAddonOptions() { DynamicJsonDocument doc(LWIP_HTTPD_POST_MAX_PAYLOAD_LEN); @@ -1561,6 +1725,7 @@ static const std::pair handlerFuncs[] = { "/api/setKeyMappings", setKeyMappings }, { "/api/setAddonsOptions", setAddonOptions }, { "/api/setPS4Options", setPS4Options }, + { "/api/setWiiControls", setWiiControls }, { "/api/setSplashImage", setSplashImage }, { "/api/reboot", reboot }, { "/api/getDisplayOptions", getDisplayOptions }, @@ -1570,6 +1735,7 @@ static const std::pair handlerFuncs[] = { "/api/getProfileOptions", getProfileOptions }, { "/api/getKeyMappings", getKeyMappings }, { "/api/getAddonsOptions", getAddonOptions }, + { "/api/getWiiControls", getWiiControls }, { "/api/resetSettings", resetSettings }, { "/api/getSplashImage", getSplashImage }, { "/api/getFirmwareVersion", getFirmwareVersion }, diff --git a/www/server/app.js b/www/server/app.js index 79f3f3933..d7180153f 100644 --- a/www/server/app.js +++ b/www/server/app.js @@ -228,6 +228,78 @@ app.get('/api/getKeyMappings', (req, res) => res.send(mapValues(DEFAULT_KEYBOARD_MAPPING)), ); +app.get('/api/getWiiControls', (req, res) => + res.send({ + "nunchuk.analogStick.x.axisType": 1, + "nunchuk.analogStick.y.axisType": 2, + "nunchuk.buttonC": 1, + "nunchuk.buttonZ": 2, + "classic.analogLeftStick.x.axisType": 1, + "classic.analogLeftStick.y.axisType": 2, + "classic.analogRightStick.x.axisType": 3, + "classic.analogRightStick.y.axisType": 4, + "classic.analogLeftTrigger.axisType": 7, + "classic.analogRightTrigger.axisType": 8, + "classic.buttonA": 2, + "classic.buttonB": 1, + "classic.buttonX": 8, + "classic.buttonY": 4, + "classic.buttonL": 64, + "classic.buttonR": 128, + "classic.buttonZL": 16, + "classic.buttonZR": 32, + "classic.buttonMinus": 256, + "classic.buttonHome": 4096, + "classic.buttonPlus": 512, + "classic.buttonUp": 65536, + "classic.buttonDown": 131072, + "classic.buttonLeft": 262144, + "classic.buttonRight": 524288, + "guitar.analogStick.x.axisType": 1, + "guitar.analogStick.y.axisType": 2, + "guitar.analogWhammyBar.axisType": 14, + "guitar.buttonOrange": 64, + "guitar.buttonRed": 2, + "guitar.buttonBlue": 4, + "guitar.buttonGreen": 1, + "guitar.buttonYellow": 8, + "guitar.buttonPedal": 128, + "guitar.buttonMinus": 256, + "guitar.buttonPlus": 512, + "guitar.buttonStrumUp": 65536, + "guitar.buttonStrumDown": 131072, + "drum.analogStick.x.axisType": 1, + "drum.analogStick.y.axisType": 2, + "drum.buttonOrange": 64, + "drum.buttonRed": 2, + "drum.buttonBlue": 8, + "drum.buttonGreen": 1, + "drum.buttonYellow": 4, + "drum.buttonPedal": 128, + "drum.buttonMinus": 256, + "drum.buttonPlus": 512, + "turntable.analogStick.x.axisType": 1, + "turntable.analogStick.y.axisType": 2, + "turntable.analogLeftTurntable.axisType": 13, + "turntable.analogRightTurntable.axisType": 15, + "turntable.analogFader.axisType": 7, + "turntable.analogEffects.axisType": 8, + "turntable.buttonLeftGreen": 262144, + "turntable.buttonLeftRed": 65536, + "turntable.buttonLeftBlue": 524288, + "turntable.buttonRightGreen": 4, + "turntable.buttonRightRed": 8, + "turntable.buttonRightBlue": 2, + "turntable.buttonEuphoria": 32, + "turntable.buttonMinus": 256, + "turntable.buttonPlus": 512, + "taiko.buttonDonLeft": 262144, + "taiko.buttonKatLeft": 64, + "taiko.buttonDonRight": 1, + "taiko.buttonKatRight": 128, + }), +); + app.get('/api/getProfileOptions', (req, res) => { return res.send({ alternativePinMappings: [ diff --git a/www/src/Addons/Wii.tsx b/www/src/Addons/Wii.tsx index 32f25dc62..7eb14278c 100644 --- a/www/src/Addons/Wii.tsx +++ b/www/src/Addons/Wii.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import { AppContext } from '../Contexts/AppContext'; +import React, { useContext, useEffect, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; -import { FormCheck, Row } from 'react-bootstrap'; +import { Button, Form, Row, FormCheck, Tab, Tabs } from 'react-bootstrap'; import * as yup from 'yup'; import Section from '../Components/Section'; @@ -8,6 +9,9 @@ import Section from '../Components/Section'; import FormControl from '../Components/FormControl'; import FormSelect from '../Components/FormSelect'; import { I2C_BLOCKS } from '../Data/Addons'; +import { BUTTON_MASKS } from '../Data/Buttons'; + +import WebApi, { baseWiiControls } from '../Services/WebApi'; export const wiiScheme = { WiiExtensionAddonEnabled: yup @@ -43,91 +47,273 @@ export const wiiState = { wiiExtensionSpeed: 400000, }; +const WII_EXTENSION_CONTROLS = [ + { id: 'Nunchuk', value: 0, inputs: { analog: [ { id: 'Stick', axes: [ { id: 'X', axis: 0 }, { id: 'Y', axis: 1 } ] } ], digital: [ { id: 'C' }, { id: 'Z' } ] } }, + { id: 'Classic', value: 1, inputs: { analog: [ { id: 'LeftStick', axes: [ { id: 'X', axis: 0 }, { id: 'Y', axis: 1 } ] }, { id: 'RightStick', axes: [ { id: 'X', axis: 2 }, { id: 'Y', axis: 3 } ] }, { id: 'LeftTrigger', axes: [ { id: 'Trigger', axis: 4 } ] }, { id: 'RightTrigger', axes: [ { id : 'Trigger', axis: 5 } ] } ], digital: [ { id: 'A' }, { id: 'B' }, { id: 'X' }, { id: 'Y' }, { id: 'L' }, { id: 'R' }, { id: 'ZL' }, { id: 'ZR' }, { id: 'Minus' }, { id: 'Home' }, { id: 'Plus' }, { id: 'Up' }, { id: 'Down' }, { id: 'Left' }, { id: 'Right' } ] } }, + { id: 'Guitar', value: 3, inputs: { analog: [ { id: 'Stick', axes: [ { id: 'X', axis: 0 }, { id: 'Y', axis: 1 } ] }, { id: 'WhammyBar', axes: [ { id: 'Trigger', axis: 4 } ] } ], digital: [ { id: 'Orange' }, { id: 'Red' }, { id: 'Blue' }, { id: 'Green' }, { id: 'Yellow' }, { id: 'Pedal' }, { id: 'Minus' }, { id: 'Plus' }, { id: 'StrumUp' }, { id: 'StrumDown' } ] } }, + { id: 'Drum', value: 4, inputs: { analog: [ { id: 'Stick', axes: [ { id: 'X', axis: 0 }, { id: 'Y', axis: 1 } ] } ], digital: [ { id: 'Orange' }, { id: 'Red' }, { id: 'Blue' }, { id: 'Green' }, { id: 'Yellow' }, { id: 'Pedal' }, { id: 'Minus' }, { id: 'Plus' } ] } }, + { id: 'Turntable', value: 5, inputs: { analog: [ { id: 'Stick', axes: [ { id: 'X', axis: 0 }, { id: 'Y', axis: 1 } ] }, { id: 'LeftTurntable', axes: [ { id: 'Trigger', axis: 0 } ] }, { id: 'RightTurntable', axes: [ { id: 'Trigger', axis: 2 } ] }, { id: 'Fader', axes: [ { id: 'Trigger', axis: 4 } ] }, { id: 'Effects', axes: [ { id: 'Trigger', axis: 5 } ] } ], digital: [ { id: 'LeftGreen' }, { id: 'LeftRed' }, { id: 'LeftBlue' }, { id: 'RightGreen' }, { id: 'RightRed' }, { id: 'RightBlue' }, { id: 'Euphoria' }, { id: 'Minus' }, { id: 'Plus' } ] } }, + { id: 'Taiko', value: 6, inputs: { analog: [], digital: [ { id: 'DonLeft' }, { id: 'KatLeft' }, { id: 'DonRight' }, { id: 'KatRight' } ] } }, +]; + +const WII_JOYSTICK_MODES = [ + { label: 'None', value: 0, options: {'x': 0, 'y': 0} }, + { label: 'Left Analog', value: 1, options: {'x': 1, 'y': 2} }, + { label: 'Right Analog', value: 2, options: {'x': 3, 'y': 4} }, + { label: 'D-Pad', value: 3, options: {'x': 5, 'y': 6} }, +]; + const Wii = ({ values, errors, handleChange, handleCheckbox }) => { const { t } = useTranslation(); + const [wiiControls, setWiiControls] = useState(baseWiiControls); + const [selectedControls] = useState(baseWiiControls); + const { setLoading } = useContext(AppContext); + + useEffect(() => { + async function fetchData() { + let wc = await WebApi.getWiiControls(setLoading); + setWiiControls(wc); + } + + fetchData(); + }, [setWiiControls, selectedControls]); + + const ANALOG_SINGLE_AXIS_MODES = [ + { label: 'None', value: 0 }, + { label: 'Left Trigger', value: 7 }, + { label: 'Right Trigger', value: 8 }, + { label: 'Left Analog X+ Axis', value: 9 }, + { label: 'Left Analog X- Axis', value: 10 }, + { label: 'Left Analog Y+ Axis', value: 11 }, + { label: 'Left Analog Y- Axis', value: 12 }, + { label: 'Right Analog X+ Axis', value: 13 }, + { label: 'Right Analog X- Axis', value: 14 }, + { label: 'Right Analog Y+ Axis', value: 15 }, + { label: 'Right Analog Y- Axis', value: 16 }, + ]; + + const saveWiiOptions = async () => { + let wiiButtonsMap = Array.from(document.querySelectorAll('#WiiExtensionAddonOptions .wii-buttons')); + let wiiMap = wiiButtonsMap + .reduce( + (o, i) => Object.assign(o, { [i.getAttribute('controlid')+'.button'+i.getAttribute('buttonid')]: parseInt(i.value) }), {}); + + let wiiAnalogMap = Array.from(document.querySelectorAll('#WiiExtensionAddonOptions .wii-analogs')); + wiiMap = wiiAnalogMap + .reduce( + (o, i) => { + let modeID = i.value; + let joyMode = getJoystickMode(modeID); + if (joyMode && joyMode.options) { + let r = o; + Object.keys(joyMode.options).forEach(key => { + Object.assign(r, { [i.getAttribute('controlid')+'.analog'+i.getAttribute('analogid')+'.'+key+'.axisType']: joyMode.options[key] }); + }); + o = r; + } else { + o = Object.assign(o, { [i.getAttribute('controlid')+'.analog'+i.getAttribute('analogid')+'.axisType']: parseInt(i.value) }); + } + return o; + }, wiiMap); + + try { + let success = await WebApi.setWiiControls(wiiMap); + + if (success) { + + } else { + + } + } catch (e) { + } + }; + + const getJoystickMode = (searchValue: number) => WII_JOYSTICK_MODES.find(({ value }) => parseInt(value) === parseInt(searchValue)); + + const setWiiAnalogEntry = (controlID,analogID,e) => { + let analogEntry = {}; + let modeID = e.target.value; + let joyMode = getJoystickMode(modeID); + if (joyMode && joyMode.options) { + let r = analogEntry; + Object.keys(joyMode.options).forEach(key => { + Object.assign(r, { [controlID.toLowerCase()+'.analog'+analogID+'.'+key+'.axisType']: joyMode.options[key] }); + }); + analogEntry = r; + } else { + analogEntry[`${controlID.toLowerCase()}.analog${analogID}.axisType`] = e.target.value; + } + + setWiiControls(controls => ({ + ...wiiControls, + ...analogEntry + })); + }; + + const getJoystickModeValue = (controlObj, analogObj) => { + let joystickMode = 0; + let foundOpt = false; + WII_JOYSTICK_MODES.forEach(mode => { + if (!foundOpt) { + Object.keys(mode.options).forEach(opt => { + if (!foundOpt) { + let modeEntry = mode.options[opt]; + let entryID = controlObj.id.toLowerCase()+'.analog'+analogObj.id+'.'+opt+'.axisType'; + let entry = wiiControls[entryID]; + if (wiiControls[entryID] == modeEntry) { + foundOpt = true; + joystickMode = mode.value; + } + } + }); + } + }); + return joystickMode; + }; + return ( -
- - + + Note: If the Display is enabled at the same time, this Addon will be disabled.', + 'sda-pin-label': 'I2C SDA Pin', + 'scl-pin-label': 'I2C SCL Pin', + 'block-label': 'I2C Block', + 'speed-label': 'I2C Speed', + 'section-digital': 'Digital', + 'section-analog': 'Analog', + 'option-simple': 'Simple', + 'option-advanced': 'Advanced', + 'controller-nunchuk': 'Nunchuk', + 'controller-classic': 'Classic', + 'controller-taiko': 'Taiko', + 'controller-guitar': 'Guitar', + 'controller-drum': 'Drums', + 'controller-turntable': 'Turntable', + 'controller-button-a': 'A', + 'controller-button-b': 'B', + 'controller-button-c': 'C', + 'controller-button-x': 'X', + 'controller-button-y': 'Y', + 'controller-button-z': 'Z', + 'controller-button-l': 'L', + 'controller-button-r': 'R', + 'controller-button-zl': 'ZL', + 'controller-button-zr': 'ZR', + 'controller-button-minus': 'Minus', + 'controller-button-home': 'Home', + 'controller-button-plus': 'Plus', + 'controller-button-up': 'Up', + 'controller-button-down': 'Down', + 'controller-button-left': 'Left', + 'controller-button-right': 'Right', + 'controller-button-euphoria': 'Euphoria', + 'controller-button-leftgreen': 'Left Green', + 'controller-button-leftred': 'Left Red', + 'controller-button-leftblue': 'Left Blue', + 'controller-button-rightgreen': 'Right Green', + 'controller-button-rightred': 'Right Red', + 'controller-button-rightblue': 'Right Blue', + 'controller-button-orange': 'Orange', + 'controller-button-red': 'Red', + 'controller-button-blue': 'Blue', + 'controller-button-green': 'Green', + 'controller-button-yellow': 'Yellow', + 'controller-button-pedal': 'Pedal', + 'controller-button-strumup': 'Strum Up', + 'controller-button-strumdown': 'Strum Down', + 'controller-button-donleft': 'Don Left', + 'controller-button-katleft': 'Kat Left', + 'controller-button-donright': 'Don Right', + 'controller-button-katright': 'Kat Right', + 'controller-analog-stick': 'Stick', + 'controller-analog-leftstick': 'Left Stick', + 'controller-analog-rightstick': 'Right Stick', + 'controller-analog-lefttrigger': 'L', + 'controller-analog-righttrigger': 'R', + 'controller-analog-leftturntable': 'Turntable Left', + 'controller-analog-rightturntable': 'Turntable Right', + 'controller-analog-fader': 'Fader', + 'controller-analog-effects': 'Effects Dial', + 'controller-analog-whammybar': 'Whammy Bar', + 'controller-analog-axis-x': 'X +/- Axis', + 'controller-analog-axis-y': 'Y +/- Axis', + 'controller-analog-axis-trigger': 'Trigger', + 'analog-axis-mode-trigger': '<0>The full range of values will be sent to the interface.', + 'analog-axis-mode-button': '<0>Acts as a digital switch, setting a "pressed" state after a defined threshold.', + 'analog-axis-mode-normal-direction': '<0>The full range of values will be translated to an axis of a joystick, where the lowest value is assumed the negative edge, and maximum is the positive edge.', + 'analog-axis-mode-invert-direction': '<0>The full range of values will be translated to an axis of a joystick, where the lowest value is assumed the positive edge, and maximum is the negative edge.', + 'button-save': 'Save Controllers', +}; diff --git a/www/src/Locales/en/AddonsConfig.jsx b/www/src/Locales/en/AddonsConfig.jsx index 558d84a06..fda777416 100644 --- a/www/src/Locales/en/AddonsConfig.jsx +++ b/www/src/Locales/en/AddonsConfig.jsx @@ -115,13 +115,6 @@ export default { 'ps4-mode-private-key-label': 'Private Key (PEM)', 'ps4-mode-serial-number-label': 'Serial Number (16 Bytes in Hex Ascii)', 'ps4-mode-signature-label': 'Signature (256 Bytes in Binary)', - 'wii-extension-header-text': 'Wii Extension', - 'wii-extension-sub-header-text': - '<0>Note: If the Display is enabled at the same time, this Addon will be disabled. <1>Currently Supported Controllers <0>Classic/Classic Pro: Both Analogs and D-Pad Supported. B = B1, A = B2, Y = B3, X = B4, L = L1, ZL = L2, R = R1, ZR = R2, Minus = S1, Plus = S2, Home = A1 <0>Nunchuck: Analog Stick Supported. C = B1, Z = B2 <0>Guitar Hero Guitar: Analog Stick Supported. Green = B1, Red = B2, Blue = B3, Yellow = B4, Orange = L1, Strum Up = Up, Strum Down = Down, Minus = S1, Plus = S2', - 'wii-extension-sda-pin-label': 'I2C SDA Pin', - 'wii-extension-scl-pin-label': 'I2C SCL Pin', - 'wii-extension-block-label': 'I2C Block', - 'wii-extension-speed-label': 'I2C Speed', 'snes-extension-header-text': 'SNES Extension Configuration', 'snes-extension-sub-header-text': '<0>Note: If the Display is enabled at the same time, this Addon will be disabled. <1>Currently Supported Controllers <0>SNES pad: D-Pad Supported. B = B1, A = B2, Y = B3, X = B4, L = L1, R = R1, Select = S1, Start = S2 <0>SNES mouse: Analog Stick Supported. Left Click = B1, Right Click = B2 <0>NES: D-Pad Supported. B = B1, A = B2, Select = S1, Start = S2', diff --git a/www/src/Locales/en/Index.jsx b/www/src/Locales/en/Index.jsx index 4729059aa..cc7194333 100644 --- a/www/src/Locales/en/Index.jsx +++ b/www/src/Locales/en/Index.jsx @@ -13,6 +13,7 @@ import BackupPage from './BackupPage'; import DisplayConfig from './DisplayConfig'; import AddonsConfig from './AddonsConfig'; import CaptureButton from './CaptureButton'; +import WiiAddon from './Addons/WiiAddon'; export default { Common, @@ -30,4 +31,5 @@ export default { DisplayConfig, AddonsConfig, CaptureButton, + WiiAddon, }; diff --git a/www/src/Services/WebApi.js b/www/src/Services/WebApi.js index c4ab94c32..ee85c5af3 100644 --- a/www/src/Services/WebApi.js +++ b/www/src/Services/WebApi.js @@ -73,6 +73,75 @@ export const baseProfileOptions = { ], }; +export const baseWiiControls = { + "nunchuk.analogStick.axisType": 1, + "nunchuk.buttonC": 1, + "nunchuk.buttonZ": 2, + "classic.analogLeftStick.x.axisType": 1, + "classic.analogLeftStick.y.axisType": 2, + "classic.analogRightStick.x.axisType": 3, + "classic.analogRightStick.y.axisType": 4, + "classic.analogLeftTrigger.axisType": 7, + "classic.analogRightTrigger.axisType": 8, + "classic.buttonA": 2, + "classic.buttonB": 1, + "classic.buttonX": 8, + "classic.buttonY": 4, + "classic.buttonL": 64, + "classic.buttonR": 128, + "classic.buttonZL": 16, + "classic.buttonZR": 32, + "classic.buttonMinus": 256, + "classic.buttonHome": 4096, + "classic.buttonPlus": 512, + "classic.buttonUp": 65536, + "classic.buttonDown": 131072, + "classic.buttonLeft": 262144, + "classic.buttonRight": 524288, + "guitar.analogStick.x.axisType": 1, + "guitar.analogStick.y.axisType": 2, + "guitar.analogWhammyBar.axisType": 14, + "guitar.buttonOrange": 64, + "guitar.buttonRed": 2, + "guitar.buttonBlue": 4, + "guitar.buttonGreen": 1, + "guitar.buttonYellow": 8, + "guitar.buttonPedal": 128, + "guitar.buttonMinus": 256, + "guitar.buttonPlus": 512, + "guitar.buttonStrumUp": 65536, + "guitar.buttonStrumDown": 131072, + "drum.analogStick.x.axisType": 1, + "drum.analogStick.y.axisType": 2, + "drum.buttonOrange": 64, + "drum.buttonRed": 2, + "drum.buttonBlue": 8, + "drum.buttonGreen": 1, + "drum.buttonYellow": 4, + "drum.buttonPedal": 128, + "drum.buttonMinus": 256, + "drum.buttonPlus": 512, + "turntable.analogStick.x.axisType": 1, + "turntable.analogStick.y.axisType": 2, + "turntable.analogLeftTurntable.axisType": 13, + "turntable.analogRightTurntable.axisType": 15, + "turntable.analogFader.axisType": 7, + "turntable.analogEffects.axisType": 8, + "turntable.buttonLeftGreen": 262144, + "turntable.buttonLeftRed": 65536, + "turntable.buttonLeftBlue": 524288, + "turntable.buttonRightGreen": 4, + "turntable.buttonRightRed": 8, + "turntable.buttonRightBlue": 2, + "turntable.buttonEuphoria": 32, + "turntable.buttonMinus": 256, + "turntable.buttonPlus": 512, + "taiko.buttonDonLeft": 262144, + "taiko.buttonKatLeft": 64, + "taiko.buttonDonRight": 1, + "taiko.buttonKatRight": 128, +}; + async function resetSettings() { return axios .get(`${baseUrl}/api/resetSettings`) @@ -434,6 +503,36 @@ async function setPS4Options(options) { }); } +async function getWiiControls(setLoading) { + setLoading(true); + + try { + const response = await axios.get(`${baseUrl}/api/getWiiControls`); + setLoading(false); + + let mappings = { ...baseWiiControls, ...response.data }; + return mappings; + } catch (error) { + setLoading(false); + console.error(error); + } +} + +async function setWiiControls(mappings) { + console.dir(mappings); + + return axios + .post(`${baseUrl}/api/setWiiControls`, sanitizeRequest(mappings)) + .then((response) => { + console.log(response.data); + return true; + }) + .catch((err) => { + console.error(err); + return false; + }); +} + async function getFirmwareVersion(setLoading) { setLoading(true); @@ -534,6 +633,8 @@ const WebApi = { getAddonsOptions, setAddonsOptions, setPS4Options, + getWiiControls, + setWiiControls, getSplashImage, setSplashImage, getFirmwareVersion,