Adapt various input devices to various output devices.
https://github.com/OpenRetroPad/OpenRetroPad
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
4.2 KiB
170 lines
4.2 KiB
/* |
|
Wii Nunchuck/Wii Classic/SNES+NES Classic: |
|
LOOKING AT THE PLUG ON FRONT OF CONSOLE/BACK OF WIIMOTE (not coming from controller) |
|
|
|
|---------------| |
|
| 1 3 5 | |
|
| o o o | |
|
| o o o | |
|
| 2 4 6 | |
|
| |-------| | |
|
|---| |---| |
|
|
|
PIN # USAGE (colors from my extension cable, check your own) |
|
|
|
1: VCC 3.3V ONLY - white |
|
2: SCL - yellow |
|
3: 3.3V SENSE, unused - red |
|
4: unused - |
|
5: SDA - green |
|
6: GND - black |
|
*/ |
|
|
|
#include <Arduino.h> |
|
|
|
// we only support 1 pad here |
|
#define GAMEPAD_COUNT 1 |
|
|
|
#define AXIS_CENTER_IN 126 |
|
#define AXIS_MAX_IN 230 |
|
#define AXIS_MIN_IN 15 |
|
|
|
#define TRIGGER_MAX_IN 255 |
|
#define TRIGGER_MIN_IN 40 |
|
|
|
#include <NintendoExtensionCtrl.h> |
|
|
|
#include "gamepad/Gamepad.h" |
|
#include "util.cpp" |
|
|
|
GAMEPAD_CLASS gamepad; |
|
|
|
ExtensionPort port; // Port for communicating with extension controllers |
|
|
|
Nunchuk::Shared nchuk(port); // Read Nunchuk formatted data from the port |
|
ClassicController::Shared classic(port); // Read Classic Controller formatted data from the port |
|
|
|
ExtensionController* controllers[] = { |
|
// Array of available controllers, for controller-specific init |
|
&nchuk, |
|
&classic, |
|
}; |
|
|
|
const int NumControllers = sizeof(controllers) / sizeof(ExtensionController*); // # of controllers, auto-generated |
|
|
|
void (*controllerChanged)(); |
|
|
|
const uint8_t c = 0; // for now just do 1 pad |
|
|
|
void nunchuckChanged() { |
|
//nchuk.printDebug(); return; |
|
gamepad.buttons(c, 0); |
|
if (nchuk.buttonC()) { |
|
gamepad.press(c, BUTTON_A); |
|
} |
|
if (nchuk.buttonZ()) { |
|
gamepad.press(c, BUTTON_B); |
|
} |
|
// todo: anything with roll/pitch/accel ? |
|
gamepad.setAxis(c, translateAxis(nchuk.joyX()), -translateAxis(nchuk.joyY()), 0, 0, 0, 0, DPAD_CENTER); |
|
} |
|
|
|
void classicChanged() { |
|
//classic.printDebug(); return; |
|
gamepad.buttons(c, 0); |
|
if (classic.buttonA()) { |
|
gamepad.press(c, BUTTON_A); |
|
} |
|
if (classic.buttonB()) { |
|
gamepad.press(c, BUTTON_B); |
|
} |
|
if (classic.buttonY()) { |
|
gamepad.press(c, BUTTON_Y); |
|
} |
|
if (classic.buttonX()) { |
|
gamepad.press(c, BUTTON_X); |
|
} |
|
if (classic.buttonZL()) { |
|
gamepad.press(c, BUTTON_L); |
|
} |
|
if (classic.buttonZR()) { |
|
gamepad.press(c, BUTTON_R); |
|
} |
|
if (classic.buttonL()) { |
|
gamepad.press(c, BUTTON_TL2); |
|
} |
|
if (classic.buttonR()) { |
|
gamepad.press(c, BUTTON_TR2); |
|
} |
|
if (classic.buttonPlus()) { |
|
gamepad.press(c, BUTTON_PLUS); |
|
} |
|
if (classic.buttonMinus()) { |
|
gamepad.press(c, BUTTON_MINUS); |
|
} |
|
if (classic.buttonHome()) { |
|
gamepad.press(c, BUTTON_HOME); |
|
} |
|
auto hat = calculateDpadDirection(classic.dpadUp(), classic.dpadDown(), classic.dpadLeft(), classic.dpadRight()); |
|
gamepad.setAxis(c, |
|
translateAxis(classic.leftJoyX()), |
|
-translateAxis(classic.leftJoyY()), |
|
translateAxis(classic.rightJoyX()), |
|
-translateAxis(classic.rightJoyY()), |
|
translateTrigger(classic.triggerL()), |
|
translateTrigger(classic.triggerR()), |
|
hat); |
|
} |
|
|
|
boolean connectController() { |
|
boolean connected = port.connect(); // Connect to the controller |
|
|
|
if (connected == true) { |
|
for (int i = 0; i < NumControllers; i++) { |
|
if (controllers[i]->controllerTypeMatches()) { // If this controller is connected... |
|
connected = controllers[i]->specificInit(); // ...run the controller-specific initialization |
|
if (connected == true) { |
|
ExtensionType conType = port.getControllerType(); |
|
switch (conType) { |
|
case (ExtensionType::Nunchuk): |
|
controllerChanged = nunchuckChanged; |
|
break; |
|
case (ExtensionType::ClassicController): |
|
controllerChanged = classicChanged; |
|
break; |
|
default: |
|
//Serial.println("Other controller connected!"); |
|
return false; |
|
} |
|
return true; |
|
} |
|
} |
|
} |
|
} |
|
|
|
return connected; |
|
} |
|
|
|
void setup() { |
|
gamepad.begin(); |
|
port.begin(); // init I2C |
|
|
|
while (!connectController()) { |
|
//Serial.println("No controller found!"); |
|
delay(1000); |
|
} |
|
} |
|
|
|
void loop() { |
|
boolean success = port.update(); // Get new data from the controller |
|
|
|
if (success == true) { // We've got data! |
|
// todo: only call this if data changed? |
|
controllerChanged(); |
|
} else { // Data is bad :( |
|
while (!connectController()) { |
|
//Serial.println("Controller Disconnected!"); |
|
delay(1000); |
|
} |
|
} |
|
}
|
|
|