├── ClassicJoyStick_USB └── ClassicJoyStick_USB.ino ├── LICENSE ├── README.md ├── SegaMasterSystem_GamePad_USB └── SegaMasterSystem_GamePad_USB.ino ├── SegaMegaDrive_GamePad_USB └── SegaMegaDrive_GamePad_USB.ino └── SuperNintendoEntertainmentSystem_GamePad_USB └── SuperNintendoEntertainmentSystem_GamePad_USB.ino /ClassicJoyStick_USB/ClassicJoyStick_USB.ino: -------------------------------------------------------------------------------- 1 | /* Commodore 64/Amiga, Atari 2600/XL/ST, ZX Spectrum, Amstrad CPC, MSX and many others compatible Joystick to USB 2 | * Auth: John Milner / jfrmilner 3 | * Blog Post URL: https://jfrmilner.wordpress.com/2016/07/17/arduino-project-commodore-64amiga-atari-2600xlst-zx-spectrum-joystick-to-windowslinux-retropie-usb/ 4 | * 5 | * Version 6 | * 1.0 7 | * 8 | * Date 9 | * May 2016 10 | * 11 | * Hardware 12 | * ATmega32u4 based Arduino (Arduino Leonardo/Micro) 13 | * Competition Pro 5000 - http://www.vesalia.de/e_comp5000.htm (example) 14 | * 15 | * Software 16 | * Arduino IDE 1.6.8 17 | * Arduino Joystick Library 1.0.1 - https://github.com/MHeironimus/ArduinoJoystickLibrary 18 | * 19 | * Works with.. 20 | * OS (plug and play): Windows 10 / Linux RetroPie 3.8.1 21 | * VICE (C64 Emulator) - http://vice-emu.sourceforge.net/ 22 | * 23 | * Pinout Reference (C64) - http://old.pinouts.ru/Inputs/ControlPortC64_pinout.shtml 24 | * 25 | * DE9 female plug on end view: 26 | * 5 4 3 2 1 27 | * 9 8 7 6 28 | * pin 1: JOY_UP 29 | * pin 2: JOY_DOWN 30 | * pin 3: JOY_LEFT 31 | * pin 4: JOY_RIGHT 32 | * pin 5: No Connection 33 | * pin 6: JOY_BUTTON 34 | * pin 7: No Connection 35 | * pin 8: Ground 36 | * pin 9: No Connection 37 | * 38 | */ 39 | 40 | #include 41 | 42 | // Arduino Controller input Pins 43 | const int JOY_UP = 2; 44 | const int JOY_DOWN = 3; 45 | const int JOY_LEFT = 4; 46 | const int JOY_RIGHT = 5; 47 | const int JOY_BUTTON = 6; 48 | 49 | void setup() 50 | { 51 | pinMode(JOY_UP, INPUT_PULLUP); 52 | pinMode(JOY_DOWN, INPUT_PULLUP); 53 | pinMode(JOY_LEFT, INPUT_PULLUP); 54 | pinMode(JOY_RIGHT, INPUT_PULLUP); 55 | pinMode(JOY_BUTTON, INPUT_PULLUP); 56 | 57 | // Initialize Joystick Library 58 | Joystick.begin(false); 59 | } 60 | 61 | void loop() 62 | { 63 | // button 64 | !digitalRead(JOY_BUTTON) ? Joystick.pressButton(0) : Joystick.releaseButton(0); 65 | 66 | // digital xy axis 67 | Joystick.setXAxis(0); 68 | Joystick.setYAxis(0); 69 | if (!digitalRead(JOY_UP)) Joystick.setYAxis(-127); 70 | if (!digitalRead(JOY_DOWN)) Joystick.setYAxis(127); 71 | if (!digitalRead(JOY_LEFT)) Joystick.setXAxis(-127); 72 | if (!digitalRead(JOY_RIGHT)) Joystick.setXAxis(127); 73 | 74 | Joystick.sendState(); 75 | 76 | delay(50); 77 | } 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino-USBRetroGamingControllers 2 | 3 | Improve your retro gaming emulation experience by using the systems original controller. 4 | This project provides code so you can bring back to life your old controller with native plug-and-play support for Microsoft Windows 7+ and Linux/RetroPie using an ATmega32u4 based Arduino. 5 | 6 | ### Further Information: 7 | 8 | Commodore 64/Amiga, Atari 2600/XL/ST, ZX Spectrum, Amstrad CPC, MSX and many others compatible Joystick to USB - 9 | https://jfrmilner.wordpress.com/2016/07/17/arduino-project-commodore-64amiga-atari-2600xlst-zx-spectrum-joystick-to-windowslinux-retropie-usb 10 | 11 | Sega Master System (SMS) Control Pad to USB - 12 | https://jfrmilner.wordpress.com/2016/07/17/arduino-project-sega-master-system-sms-control-pad-to-windowslinux-retropie-usb/ 13 | 14 | Sega MegaDrive/Genesis controller to USB - 15 | https://jfrmilner.wordpress.com/2016/07/17/arduino-project-sega-megadrivegenesis-controller-to-windowslinux-retropie-usb/ 16 | 17 | Super Nintendo Entertainment System (SNES) Controller/Gamepad to USB - 18 | https://jfrmilner.wordpress.com/2016/07/17/arduino-project-super-nintendo-entertainment-system-snes-controllergamepad-to-windowslinux-retropie-usb/ 19 | 20 | --- 21 | 22 | ## Multijoy Retro Gaming System 23 | With the above experience, I designed a circuit board and selector system so multiple controllers could all be connected and used on one system. The circuit board acts as a shield for an Arduino Micro that expands the available pins to make this possible. I created a quick demo of me playing popular games on this console with each controller. Check it out by clicking the below image.. 24 | 25 | youtube video: 26 | [![Alt text](https://img.youtube.com/vi/LYXYafwz_CY/0.jpg)](https://www.youtube.com/watch?v=LYXYafwz_CY) 27 | 28 | If you'd like to know more please check out my Blog -https://jfrmilner.wordpress.com/2017/10/16/retro-gaming-system/ 29 | -------------------------------------------------------------------------------- /SegaMasterSystem_GamePad_USB/SegaMasterSystem_GamePad_USB.ino: -------------------------------------------------------------------------------- 1 | /* Sega Master System (SMS) Control Pad to USB 2 | * Auth: John Milner / jfrmilner 3 | * Blog Post URL: https://jfrmilner.wordpress.com/2016/07/17/arduino-project-sega-master-system-sms-control-pad-to-windowslinux-retropie-usb/ 4 | * 5 | * Date 6 | * July 2016 7 | * 8 | * Hardware 9 | * ATmega32u4 based Arduino (Arduino Leonardo/Micro) 10 | * Sega Master System Control Pad - http://segaretro.org/Control_Pad_(Master_System) 11 | * 12 | * Software 13 | * Arduino IDE 1.6.8 14 | * Arduino Joystick Library 1.0.1 - https://github.com/MHeironimus/ArduinoJoystickLibrary 15 | * 16 | * Works with.. 17 | * OS (plug and play): Windows 10 / Linux RetroPie 3.8.1 18 | * Fusion Emulator for Sega Systems (fusion364) 19 | * 20 | * Pinout - http://pinouts.ru/Game/sega_ms_joy_pinout.shtml 21 | * 22 | * DE9 female plug on end view: 23 | * 5 4 3 2 1 24 | * 9 8 7 6 25 | * pin 1: CONTROL_PAD_UP 26 | * pin 2: CONTROL_PAD_DOWN 27 | * pin 3: CONTROL_PAD_LEFT 28 | * pin 4: CONTROL_PAD_RIGHT 29 | * pin 5: No Connection 30 | * pin 6: CONTROL_PAD_B1 31 | * pin 7: No Connection 32 | * pin 8: Ground 33 | * pin 9: CONTROL_PAD_B2 34 | * 35 | */ 36 | 37 | #include 38 | 39 | // Arduino Controller input Pins 40 | const int CONTROL_PAD_UP = 2; 41 | const int CONTROL_PAD_DOWN = 3; 42 | const int CONTROL_PAD_LEFT = 4; 43 | const int CONTROL_PAD_RIGHT = 5; 44 | const int CONTROL_PAD_B1 = 6; 45 | const int CONTROL_PAD_B2 = 7; 46 | 47 | void setup() { 48 | Joystick.begin(false); 49 | 50 | pinMode(CONTROL_PAD_UP, INPUT_PULLUP); 51 | pinMode(CONTROL_PAD_DOWN, INPUT_PULLUP); 52 | pinMode(CONTROL_PAD_LEFT, INPUT_PULLUP); 53 | pinMode(CONTROL_PAD_RIGHT, INPUT_PULLUP); 54 | pinMode(CONTROL_PAD_B1, INPUT_PULLUP); 55 | pinMode(CONTROL_PAD_B2, INPUT_PULLUP); 56 | 57 | } 58 | 59 | void loop() { 60 | !digitalRead(CONTROL_PAD_UP) ? Joystick.pressButton(0) : Joystick.releaseButton(0); 61 | !digitalRead(CONTROL_PAD_DOWN) ? Joystick.pressButton(1) : Joystick.releaseButton(1); 62 | !digitalRead(CONTROL_PAD_LEFT) ? Joystick.pressButton(2) : Joystick.releaseButton(2); 63 | !digitalRead(CONTROL_PAD_RIGHT) ? Joystick.pressButton(3) : Joystick.releaseButton(3); 64 | !digitalRead(CONTROL_PAD_B1) ? Joystick.pressButton(4) : Joystick.releaseButton(4); 65 | !digitalRead(CONTROL_PAD_B2) ? Joystick.pressButton(5) : Joystick.releaseButton(5); 66 | 67 | Joystick.sendState(); 68 | delay(25); 69 | } 70 | -------------------------------------------------------------------------------- /SegaMegaDrive_GamePad_USB/SegaMegaDrive_GamePad_USB.ino: -------------------------------------------------------------------------------- 1 | /* Sega MegaDrive/Genesis controller to USB 2 | * 3 | * Version: 1.1 Date: 9/29/2014 Author: Jon Thysell 4 | * Reads buttons presses from Sega Genesis 3/6 button controllers 5 | * and reports their state via keyboard button presses. Handles hot 6 | * swapping of controllers and auto-switches between 3 and 6 button 7 | * polling patterns. 8 | * Blog Post URL: https://jonthysell.com/2014/09/29/sega-genesis-controllers-and-arduino-revisited/ 9 | * 10 | * Version: 1.1.1 Date: July/2016 Author: John Milner / jfrmilner 11 | * Modified to use https://github.com/MHeironimus/ArduinoJoystickLibrary instead of keyboard. 12 | * Blog Post URL: https://jfrmilner.wordpress.com/2016/07/17/arduino-project-sega-megadrivegenesis-controller-to-windowslinux-retropie-usb/ 13 | * 14 | * Hardware 15 | * ATmega32u4 based Arduino (Arduino Leonardo/Micro) 16 | * Competition Pro 5000 - http://www.vesalia.de/e_comp5000.htm (example) 17 | * 18 | * Software 19 | * Arduino IDE 1.6.8 20 | * Arduino Joystick Library 1.0.1 - https://github.com/MHeironimus/ArduinoJoystickLibrary 21 | * 22 | * Works with.. 23 | * OS (plug and play): Windows 10 / Linux RetroPie 3.8.1 24 | * Fusion Emulator for Sega Systems (fusion364) 25 | * 26 | * Pinout Reference - http://pinouts.ru/Game/genesiscontroller_pinout.shtml 27 | * 28 | * DE9 female plug on end view (Player0): 29 | * 5 4 3 2 1 30 | * 9 8 7 6 31 | * pin 1: UP/Z 32 | * pin 2: DOWN/Y 33 | * pin 3: LEFT/X 34 | * pin 4: RIGHT/MODE 35 | * pin 5: +5v 36 | * pin 6: A/B 37 | * pin 7: SELECT[] 38 | * pin 8: Ground 39 | * pin 9: START/C 40 | * 41 | */ 42 | 43 | #include 44 | const int PLAYERS = 2; 45 | 46 | // Controller Button Flags 47 | const int ON = 1; 48 | const int UP = 2; 49 | const int DOWN = 4; 50 | const int LEFT = 8; 51 | const int RIGHT = 16; 52 | const int START = 32; 53 | const int A = 64; 54 | const int B = 128; 55 | const int C = 256; 56 | const int X = 512; 57 | const int Y = 1024; 58 | const int Z = 2048; 59 | const int MODE = 4096; 60 | 61 | // Controller DB9 Pin 7 Mappings. Controller 0,1 62 | const int SELECT[] = { 8, 9 }; 63 | 64 | typedef struct 65 | { 66 | int player; 67 | int pin; 68 | int lowFlag; 69 | int highFlag; 70 | int pulse3Flag; 71 | } input; 72 | 73 | // Controller DB9 Pin to Button Flag Mappings 74 | // First column is the controller index, second column 75 | // is the Arduino pin that the controller's DB9 pin is 76 | // attached to 77 | input inputMap[] = { 78 | { 0, 2, UP, UP, Z }, // P0 DB9 Pin 1 79 | { 0, 3, DOWN, DOWN, Y }, // P0 DB9 Pin 2 80 | { 0, 4, ON, LEFT, X }, // P0 DB9 Pin 3 81 | { 0, 5, ON, RIGHT, MODE }, // P0 DB9 Pin 4 82 | { 0, 6, A, B, 0 }, // P0 DB9 Pin 6 83 | { 0, 7, START, C, 0 }, // P0 DB9 Pin 9 84 | { 1, A0, UP, UP, Z }, // P1 DB9 Pin 1 85 | { 1, A1, DOWN, DOWN, Y }, // P1 DB9 Pin 2 86 | { 1, A2, ON, LEFT, X }, // P1 DB9 Pin 3 87 | { 1, A3, ON, RIGHT, MODE }, // P1 DB9 Pin 4 88 | { 1, A4, A, B, 0 }, // P1 DB9 Pin 6 89 | { 1, A5, START, C, 0 } // P1 DB9 Pin 9 90 | }; 91 | 92 | typedef struct 93 | { 94 | int player; 95 | int flag; 96 | char key; 97 | } output; 98 | 99 | // Controller Button Flag to Keyboard Mappings 100 | // First column is the controller index, second column 101 | // is the button flag, third is joystick button 102 | output outputMap[] = { 103 | { 0, UP, 0 }, 104 | { 0, DOWN, 1 }, 105 | { 0, LEFT, 2 }, 106 | { 0, RIGHT, 3 }, 107 | { 0, START, 4 }, 108 | { 0, A, 5 }, 109 | { 0, B, 6 }, 110 | { 0, C, 7 }, 111 | { 0, X, 8 }, 112 | { 0, Y, 9 }, 113 | { 0, Z, 10 }, 114 | { 0, MODE, 11 }, 115 | { 1, UP, 12 }, 116 | { 1, DOWN, 13 }, 117 | { 1, LEFT, 14 }, 118 | { 1, RIGHT, 15 }, 119 | { 1, START, 16 }, 120 | { 1, A, 17 }, 121 | { 1, B, 18 }, 122 | { 1, C, 19 }, 123 | { 1, X, 20 }, 124 | { 1, Y, 21 }, 125 | { 1, Z, 22 }, 126 | { 1, MODE, 23 } 127 | }; 128 | 129 | 130 | // Controller State 131 | int currentState[] = { 0, 0 }; 132 | int lastState[] = { -1, -1 }; 133 | 134 | // Default to three-button mode until six-button connects 135 | boolean sixButtonMode[] = { false, false }; 136 | 137 | void setup() 138 | { 139 | // Setup input pins 140 | for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++) 141 | { 142 | pinMode(inputMap[i].pin, INPUT); 143 | digitalWrite(inputMap[i].pin, HIGH); 144 | } 145 | 146 | // Setup select pins 147 | for (int i = 0; i < PLAYERS; i++) 148 | { 149 | pinMode(SELECT[i], OUTPUT); 150 | digitalWrite(SELECT[i], HIGH); 151 | } 152 | 153 | // Initialize Joystick Library 154 | Joystick.begin(false); 155 | } 156 | 157 | void loop() 158 | { 159 | readButtons(); 160 | sendStates(); 161 | } 162 | 163 | void readButtons() 164 | { 165 | for (int i = 0; i < PLAYERS; i++) 166 | { 167 | resetState(i); 168 | if (sixButtonMode[i]) 169 | { 170 | read6buttons(i); 171 | } 172 | else 173 | { 174 | read3buttons(i); 175 | } 176 | } 177 | } 178 | 179 | void resetState(int player) 180 | { 181 | currentState[player] = 0; 182 | } 183 | 184 | void read3buttons(int player) 185 | { 186 | // Set SELECT LOW and read lowFlag 187 | digitalWrite(SELECT[player], LOW); 188 | 189 | delayMicroseconds(20); 190 | 191 | for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++) 192 | { 193 | if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW) 194 | { 195 | currentState[player] |= inputMap[i].lowFlag; 196 | } 197 | } 198 | 199 | // Set SELECT HIGH and read highFlag 200 | digitalWrite(SELECT[player], HIGH); 201 | 202 | delayMicroseconds(20); 203 | 204 | for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++) 205 | { 206 | if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW) 207 | { 208 | currentState[player] |= inputMap[i].highFlag; 209 | } 210 | } 211 | 212 | // When a six-button first connects, it'll spam UP and DOWN, 213 | // which signals the game to switch to 6-button polling 214 | if (currentState[player] == (ON | UP | DOWN)) 215 | { 216 | sixButtonMode[player] = true; 217 | } 218 | // When a controller disconnects, revert to three-button polling 219 | else if ((currentState[player] & ON) == 0) 220 | { 221 | sixButtonMode[player] = false; 222 | } 223 | 224 | delayMicroseconds(20); 225 | } 226 | 227 | void read6buttons(int player) 228 | { 229 | // Poll for three-button states twice 230 | read3buttons(player); 231 | read3buttons(player); 232 | 233 | // After two three-button polls, pulse the SELECT line 234 | // so the six-button reports the higher button states 235 | digitalWrite(SELECT[player], LOW); 236 | delayMicroseconds(20); 237 | digitalWrite(SELECT[player], HIGH); 238 | 239 | for(int i = 0; i < sizeof(inputMap) / sizeof(input); i++) 240 | { 241 | if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW) 242 | { 243 | currentState[player] |= inputMap[i].pulse3Flag; 244 | } 245 | } 246 | 247 | delayMicroseconds(1360); // Increased from 1000 for Sega Mega Drive original Arcade 6 Button Pad Controller MK-1653-50 248 | } 249 | 250 | void sendStates() 251 | { 252 | for (int i = 0; i < sizeof(outputMap) / sizeof(output); i++) 253 | { 254 | int last = (lastState[outputMap[i].player] & outputMap[i].flag); 255 | int current = (currentState[outputMap[i].player] & outputMap[i].flag); 256 | 257 | if (last != current) 258 | { 259 | if (current == outputMap[i].flag) 260 | { 261 | Joystick.pressButton(outputMap[i].key); 262 | } 263 | else 264 | { 265 | Joystick.releaseButton(outputMap[i].key); 266 | } 267 | } 268 | } 269 | 270 | for (int i = 0; i < PLAYERS; i++) 271 | { 272 | lastState[i] = currentState[i]; 273 | } 274 | Joystick.sendState(); 275 | } 276 | -------------------------------------------------------------------------------- /SuperNintendoEntertainmentSystem_GamePad_USB/SuperNintendoEntertainmentSystem_GamePad_USB.ino: -------------------------------------------------------------------------------- 1 | /* Super Nintendo Entertainment System (SNES) Controller/Gamepad to USB 2 | * Auth: John Milner / jfrmilner 3 | * Blog Post URL: https://jfrmilner.wordpress.com/2016/07/17/arduino-project-super-nintendo-entertainment-system-snes-controllergamepad-to-windowslinux-retropie-usb/ 4 | * 5 | * Version 6 | * 1.0 7 | * 8 | * Date 9 | * July 2016 10 | * 11 | * Hardware 12 | * ATmega32u4 based Arduino (Arduino Leonardo/Micro) 13 | * Super Nintendo Entertainment System Controller 14 | * 15 | * Software 16 | * Arduino IDE 1.6.8 17 | * Arduino Joystick Library 1.0.1 - https://github.com/MHeironimus/ArduinoJoystickLibrary 18 | * 19 | * Works with.. 20 | * OS (plug and play): Windows 10 / Linux RetroPie 3.8.1 21 | * Snes9x (SNES Emulator) - http://www.snes9x.com/ / https://tcrf.net/SNES_Test_Program 22 | * 23 | * Pinout - http://pinoutsguide.com/Game/snescontroller_pinout.shtml 24 | * 25 | * 7 pin SNES proprietary female connector view: 26 | * -----------------\ 27 | * | 1 2 3 4 | 5 6 7 | 28 | * -----------------/ 29 | * pin 1: +5v 30 | * pin 2: Data Clock 31 | * pin 3: Data Latch 32 | * pin 4: Serial Data 33 | * pin 5: No Connection 34 | * pin 6: No Connection 35 | * pin 7: Ground 36 | * 37 | */ 38 | 39 | #include 40 | 41 | // Controller Buttons 42 | #define SNES_B 1 //000000000001 43 | #define SNES_Y 2 //000000000010 44 | #define SNES_SELECT 4 //000000000100 45 | #define SNES_START 8 //000000001000 46 | #define SNES_UP 16 //000000010000 47 | #define SNES_DOWN 32 //000000100000 48 | #define SNES_LEFT 64 //000001000000 49 | #define SNES_RIGHT 128 //000010000000 50 | #define SNES_A 256 //000100000000 51 | #define SNES_X 512 //001000000000 52 | #define SNES_L 1024 //010000000000 53 | #define SNES_R 2048 //100000000000 54 | 55 | const int PIN_CLOCK = 6; 56 | const int PIN_LATCH = 7; 57 | const int PIN_DATA = 12; 58 | 59 | void setup(){ 60 | Joystick.begin(false); 61 | 62 | pinMode(PIN_CLOCK, OUTPUT); 63 | digitalWrite(PIN_CLOCK, HIGH); 64 | pinMode(PIN_LATCH, OUTPUT); 65 | digitalWrite(PIN_LATCH, LOW); 66 | pinMode(PIN_DATA, INPUT_PULLUP); 67 | } 68 | 69 | void loop(){ 70 | uint16_t state = 0; 71 | // 12us latch 72 | digitalWrite(PIN_LATCH, HIGH); 73 | delayMicroseconds(12); 74 | digitalWrite(PIN_LATCH, LOW); 75 | delayMicroseconds(6); 76 | // Retrieve 4021s sixteen bits of data 77 | for(int i = 0; i < 16; i++){ 78 | digitalWrite(PIN_CLOCK, LOW); 79 | delayMicroseconds(6); 80 | state |= digitalRead(PIN_DATA) << i; 81 | digitalWrite(PIN_CLOCK, HIGH); 82 | delayMicroseconds(6); 83 | } 84 | 85 | // buttons 86 | SNES_B & ~state ? Joystick.pressButton(0) : Joystick.releaseButton(0); 87 | SNES_Y & ~state ? Joystick.pressButton(1) : Joystick.releaseButton(1); 88 | SNES_SELECT & ~state ? Joystick.pressButton(2) : Joystick.releaseButton(2); 89 | SNES_START & ~state ? Joystick.pressButton(3) : Joystick.releaseButton(3); 90 | SNES_A & ~state ? Joystick.pressButton(4) : Joystick.releaseButton(4); 91 | SNES_X & ~state ? Joystick.pressButton(5) : Joystick.releaseButton(5); 92 | SNES_L & ~state ? Joystick.pressButton(6) : Joystick.releaseButton(6); 93 | SNES_R & ~state ? Joystick.pressButton(7) : Joystick.releaseButton(7); 94 | 95 | // 360° Hat Switch 0 96 | Joystick.setHatSwitch(0, -1); // release 97 | if (SNES_UP & ~state) Joystick.setHatSwitch(0, 0); 98 | if (SNES_RIGHT & ~state) Joystick.setHatSwitch(0, 90); 99 | if (SNES_DOWN & ~state) Joystick.setHatSwitch(0, 180); 100 | if (SNES_LEFT & ~state) Joystick.setHatSwitch(0, 270); 101 | if (SNES_UP & ~state && SNES_RIGHT & ~state) Joystick.setHatSwitch(0, 45); 102 | if (SNES_DOWN & ~state && SNES_RIGHT & ~state) Joystick.setHatSwitch(0, 135); 103 | if (SNES_DOWN & ~state && SNES_LEFT & ~state) Joystick.setHatSwitch(0, 225); 104 | if (SNES_UP & ~state && SNES_LEFT & ~state) Joystick.setHatSwitch(0, 315); 105 | 106 | Joystick.sendState(); 107 | delay(25); 108 | } 109 | 110 | --------------------------------------------------------------------------------