Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions examples/BasicGamepad/BasicGamepad.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Project Teensy XInput Library
* @author David Madison
* @link github.com/dmadison/TeensyXInput
* @license MIT - Copyright (c) 2018 David Madison
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Example: BasicGamepad
* Description: Sets up a basic NES-style gamepad using the XInput library,
* and shows how to use the class functions.
*
*/

#include <XInput.h>

// Directional Pad Pins
const int Pin_DpadUp = 0;
const int Pin_DpadDown = 1;
const int Pin_DpadLeft = 2;
const int Pin_DpadRight = 3;

// Button Pins
const int Pin_ButtonA = 4;
const int Pin_ButtonB = 5;

// Note: Buttons should be connected from the sensor pin (above) to ground
// when pressed

void setup() {
// Set buttons as inputs, using internal pull-up resistors
pinMode(Pin_DpadUp, INPUT_PULLUP);
pinMode(Pin_DpadDown, INPUT_PULLUP);
pinMode(Pin_DpadLeft, INPUT_PULLUP);
pinMode(Pin_DpadRight, INPUT_PULLUP);

pinMode(Pin_ButtonA, INPUT_PULLUP);
pinMode(Pin_ButtonB, INPUT_PULLUP);
}

void loop() {
// Read pin values and store in variables
// (Note the "!" to invert the state, because LOW = pressed)
boolean dpadUp = !digitalRead(Pin_DpadUp);
boolean dpadDown = !digitalRead(Pin_DpadDown);
boolean dpadLeft = !digitalRead(Pin_DpadLeft);
boolean dpadRight = !digitalRead(Pin_DpadRight);

boolean buttonA = !digitalRead(Pin_ButtonA);
boolean buttonB = !digitalRead(Pin_ButtonB);

// Set XInput DPAD values
XInput.setDpad(dpadUp, dpadDown, dpadLeft, dpadRight);

// Set XInput buttons
XInput.setButton(BUTTON_A, buttonA);
XInput.setButton(BUTTON_B, buttonB);

// Send control data to the computer
XInput.send();

// Receive data (player number, rumble motors, etc.)
XInput.receive();
}
45 changes: 45 additions & 0 deletions examples/Blink/Blink.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Project Teensy XInput Library
* @author David Madison
* @link github.com/dmadison/TeensyXInput
* @license MIT - Copyright (c) 2018 David Madison
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Example: Blink
* Description: Using XInput, presses and then releases the "A" button
* every two seconds. Good for testing that the XInput
* library is working correctly.
*/

#include <XInput.h>

void setup() {

}

void loop() {
XInput.press(BUTTON_A);
XInput.send();
delay(1000);

XInput.release(BUTTON_A);
XInput.send();
delay(1000);
}
141 changes: 141 additions & 0 deletions examples/TestAll/TestAll.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Project Teensy XInput Library
* @author David Madison
* @link github.com/dmadison/TeensyXInput
* @license MIT - Copyright (c) 2018 David Madison
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Example: TestAll
* Description: Automatically activate all possible XInput controls.
* Useful to test that everything is functioning properly.
*
* WARNING: This will spam inputs! Ground pin '0' to stop.
*
*/

#include <XInput.h>

// Config Settings
const unsigned long CycleTime = 5000; // ms
const int SafetyPin = 0; // Ground this pin to prevent inputs

// Button Setup
const int NumButtons = 10;
const int Buttons[NumButtons] = {
BUTTON_A,
BUTTON_B,
BUTTON_X,
BUTTON_Y,
BUTTON_LB,
BUTTON_RB,
BUTTON_BACK,
BUTTON_START,
BUTTON_L3,
BUTTON_R3,
};
const unsigned long ButtonDuration = CycleTime / NumButtons;
unsigned long buttonTimeLast = 0;
int buttonID = 0;

// DPad Setup
const int NumDirections = 4;
const unsigned long DPadDuration = CycleTime / NumDirections;
unsigned long dpadTimeLast = 0;
int dpadPosition = 0;

// Triggers
const int TriggerMax = 255; // uint8_t max
const unsigned long TriggerDuration = CycleTime / (TriggerMax * 2); // Go up and down
unsigned long triggerTimeLast = 0;
uint8_t triggerVal = 0;
boolean triggerDirection = 0;

// Joystick Setup
const int JoyMax = 32767; // int16_t max
const double angle_precision = (2 * PI) / (CycleTime / 4); // 4 because 250 Hz update rate
double angle = 0.0;

void setup() {
pinMode(SafetyPin, INPUT_PULLUP);
}

void loop() {
if (digitalRead(SafetyPin) == LOW) {
return;
}

unsigned long t = millis(); // Get timestamp for comparison

// DPad
if (t - dpadTimeLast >= DPadDuration) { // If enough time has passed, change the dpad
XInput.setDpad(dpadPosition == 0, dpadPosition == 1, dpadPosition == 2, dpadPosition == 3);

dpadPosition++; // Increment the dpad counter
if (dpadPosition >= NumDirections) dpadPosition = 0; // Go back to 0 if we hit the limit
dpadTimeLast = t; // Save time we last did this
}

// Buttons
if (t - buttonTimeLast >= ButtonDuration) { // If enough time has passed, change the button pressed
for (int i = 0; i < NumButtons; i++) {
XInput.release((XInputControl)Buttons[i]); // Relase all buttons
}

XInput.press((XInputControl)Buttons[buttonID]); // Press the next button
buttonID++; // Increment the button counter
if (buttonID >= NumButtons) buttonID = 0; // Go back to 0 if we hit the limit

buttonTimeLast = t; // Save time we last did this
}

// Triggers
if (t - triggerTimeLast >= TriggerDuration) { // If enough time has passed, update the triggers
XInput.setTrigger(TRIGGER_LEFT, triggerVal);
XInput.setTrigger(TRIGGER_RIGHT, ~triggerVal); // Inverse

// Increment trigger value based on direction
if (triggerDirection == 0) { triggerVal++; }
else { triggerVal--; }

if (triggerVal == TriggerMax || triggerVal == 0) { // If we've hit the edge of the range
triggerDirection = !triggerDirection; // Reverse direction
}

triggerTimeLast = t; // Save time we last did this
}

// Calculate joystick x/y values using trig
int axis_x = sin(angle) * JoyMax;
int axis_y = cos(angle) * JoyMax;

angle += angle_precision;
if (angle >= 360) {
angle -= 360;
}

XInput.setJoystick(JOY_LEFT, axis_x, axis_y); // Clockwise
XInput.setJoystick(JOY_RIGHT, -axis_x, axis_y); // Counter-clockwise

// Send values to PC
XInput.send();

// Receive data from PC
XInput.receive();
}
75 changes: 75 additions & 0 deletions examples/WiiClassicController/WiiClassicController.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Project Teensy XInput Library
* @author David Madison
* @link github.com/dmadison/TeensyXInput
* @license MIT - Copyright (c) 2018 David Madison
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Example: WiiClassicController
* Description: Maps the inputs from a Wii Classic Controller to an emulated
* Xbox 360 gamepad using XInput. Requires using the
* NintendoExtensionCtrl library and an extension adapter.
*/

#include <XInput.h>
#include <NintendoExtensionCtrl.h> // Library for the Wii controller communication

ClassicController classic;

void setup() {
classic.begin();

while (!classic.connect()) {
delay(1000); // Controller not connected
}
}

void loop() {
if(classic.update()) { // Get new data!
XInput.setJoystick(JOY_LEFT, map((classic.leftJoyX() << 2), 0, 255, -32768, 32767), map((classic.leftJoyY() << 2), 0, 255, -32768, 32767));
XInput.setJoystick(JOY_RIGHT, map((classic.rightJoyX() << 3), 0, 255, -32768, 32767), map((classic.rightJoyY() << 3), 0, 255, -32768, 32767));

XInput.setButton(BUTTON_A, classic.buttonB());
XInput.setButton(BUTTON_B, classic.buttonA());
XInput.setButton(BUTTON_X, classic.buttonY());
XInput.setButton(BUTTON_Y, classic.buttonX());

XInput.setButton(BUTTON_START, classic.buttonPlus());
XInput.setButton(BUTTON_BACK, classic.buttonMinus());
XInput.setButton(BUTTON_LOGO, classic.buttonHome());

XInput.setDpad(classic.dpadUp(), classic.dpadDown(), classic.dpadLeft(), classic.dpadRight());

XInput.setTrigger(TRIGGER_LEFT, classic.triggerL() << 3);
XInput.setTrigger(TRIGGER_RIGHT, classic.triggerR() << 3);

XInput.setButton(BUTTON_LB, classic.buttonZL());
XInput.setButton(BUTTON_RB, classic.buttonZR());

// XInput.setButton(BUTTON_L3, classic.buttonZL()); // The Classic Controller doesn't have L3 and R3
// XInput.setButton(BUTTON_R3, classic.buttonZR()); // but you can uncomment these to check that they work

XInput.send();
XInput.receive();
}
else { // Data is bad :(
classic.reconnect();
}
}