Multiplayer Bluetooth controllers adapter for retro video game consoles

Public Chat
Similar projects worth following
BlueRetro is a multiplayer Bluetooth controllers adapter for various retro game consoles. Lost or broken controllers? Reproduction too expensive? Need those rare and obscure accessories? Just use the Bluetooth devices you already got! The project is open source hardware & software under the CERN-OHL-P-2.0 & Apache-2.0 licenses respectively. It's built for the popular ESP32 chip. All processing for Bluetooth and HID input decoding is done on the first core which makes it easy for other projects to use the Bluetooth stack within their own project by using the 2nd core. Wii, Switch, PS3, PS4, PS5, Xbox One & generic HID Bluetooth devices are supported. Parallel 1P (NeoGeo, Supergun, JAMMA, etc), Parallel 2P (Atari 2600/7800, Master System), NES, PCE / TG16, Mega Drive / Genesis, SNES, CD-i, 3DO, Jaguar, Saturn, PSX, PC-FX, JVS (Arcade), N64, Dreamcast, PS2 & GameCube are supported with simultaneous 4+ players using a single adapter.

Project documentation

General documentation


There are various ways available to enjoy retro gaming. Those of us that prefer playing with the original systems face various challenges regarding the controllers. Controllers are the part that degrades the most and often with old console not all of your original controllers (if any) are in good working condition. If you have more than one console, it can quickly get expensive to buy NOS or replica controllers. Adapters for USB & Bluetooth exist on the market but are compatible with one or two systems only.

When it comes to 4+ retro multiplayer party, it’s hard to have enough working controller and it quickly becomes a cable mess if you end up playing more than one console. Most systems included only 2 ports and 3+ players games required a multitap accessories that are now often hard to find and expensive. Existing adapters solutions are all limited for single player use, one need to buy multiple adapters for each player.

Some early games got really awkward control style by today's standard and it is often not even possible to edit the buttons mapping. Even when possible, it's often too much trouble doing so while your friends are waiting to play. Controllers & adapters including configurability are not simple enough to be used in a party.

Mouse, trackball & keyboards are often rare and expensive to get accessories for most systems. And let not forget that some controller design got questionable ergonomic! Very few, if any, adaptive option existed back in the day for people with limited mobility.


Across all current and last generation console and PC accessories, we already own a large quantity of Bluetooth HID devices. BlueRetro is a Bluetooth controller adapter for retro video game consoles that enable to use all those devices. Any Bluetooth HID (BR/EDR/BLE) devices can be connected and used including gamepad, mouse, keyboard, trackball, etc. This includes the Xbox adaptive controller.

The BlueRetro core can be used with every retro gaming system supported. This has the benefits of not requiring to repair your Bluetooth controllers between different system uses. No reconfiguration is required since the adapter auto detect the system it is plug on. Only the cable adapter need switched between system.

Up to 7 controllers can be connected simultaneously on a single adapter for multiplayer games. This means the adapter also emulate the multitap accessory for most systems. Rumble accessories/function is supported. Keyboard, trackball & mouse console accessories are supported too.

The adapter is highly configurable via a Web Bluetooth (BLE) interface for mobile & desktop. Buttons and axes can be mapped to any buttons or axis direction (Ex. mapping axis direction to a button, buttons on an axis direction, inverting an axis direction, trigger to axis, buttons to trigger, etc.). Various scaling and response curve options is available for axes and trigger. Presets configuration for various games are available. Using presets, you can change every player mapping at once with a few clicks on your mobile phone.

A secondary objective is for the code to be easily used on other ESP32 project to add Bluetooth HID device input.

To help this the Bluetooth and HID decoding is all done within...

Read more »

  • Playing Half-Life 1 Dreamcast w/ Valve's Steam controller

    Jacques Gagnon10/10/2021 at 23:57 0 comments

  • 2021-10-02 - v1.0 release

    Jacques Gagnon10/02/2021 at 20:45 0 comments

    New #BlueRetro update v1.0 is available!


    • Add support for BLE generic HID gamepad, mouse & keyboard
    • Add support for Xbox Series X|S controller
    • Add workaround for PowerA switch controller stopping report after inquiry stop


    • Improve Generic HID gamepad default mapping
    • Introduce default mapping quirks for inverted and rotated face buttons (8bitdo, PowerA GC)


    • Add version string attribute (Displayed in OTA page logs)

  • OTA FW update via Web-Bluetooth interface

    Jacques Gagnon07/07/2021 at 00:09 0 comments

    I added OTA FW update with v0.19 release. You got to update to that version first using the USB serial cable method first but when next version is out you will be able to update simply wirelessly via the web-bluetooth interface.

    See wiki for more info.

  • A few UX improvement

    Jacques Gagnon06/24/2021 at 21:09 0 comments

    I redesigned how the LED and BOOT switch are used, holding it 3 sec start inquiry scan (and LED start to pulse), short press while inquiry scan is on cancel it (and LED stop glowing), one short press outside of inquiry scan kick out all controllers as before. The LED being solid on still indicate that an error occurred. Holding the switch 10 sec will factory reset the adapter to default config and clear the Bluetooth keys.

    I also added the option to disable the automatic inquiry while no controller present via the web config.

    See v0.18 release.

  • 2021-06-06 - Atari Jaguar support

    Jacques Gagnon06/06/2021 at 14:43 0 comments

    I added Atari Jaguar support with version v0.17! Regular pad, 6D controller & TeamTap up to 4 players are supported. Refer to wiki for cable schematic and config documentation.

    I wrote my own testing application with JagStudio this time around to test BlueRetro with my GameDrive (especially the 6D controller support). Source and ROM available on GitHub.

    My reverse engineering notes are available on the GitHub wiki.

  • 2021-04-30 - PC Engine and TurboGrafx16 support

    Jacques Gagnon04/30/2021 at 13:08 1 comment

    I added PC Engine / TG16 support with version v0.16! Regular pad, 6 buttons pad, mouse & multitap up to 5 players are supported. Refer to wiki for cable schematic and config documentation.

    My reverse engineering notes are available on the GitHub wiki.

  • Moving project update to GitHub discussions?

    Jacques Gagnon04/20/2021 at 17:15 1 comment is nice but the more content I add the harder it is to find the older content. You got to click view all project logs and then click next page forever.

    Also while it's possible to comment on the log entry, that feature looks to be universally not used here. Also you can't like a log.

    So I'm seriously thinking about posting next status update on the GitHub discussions forum:

    This way everything would be centralized in one place. The reply form is more obvious and you can like/love/etc.

    Also I'm thinking of moving a few of the documentation logs to a GitHub wiki page.

    What you guys think?

  • CD-i interface

    Jacques Gagnon04/12/2021 at 17:22 0 comments

    I added CD-i support with version v0.15! Regular pad, mouse & keyboards (K, X & T type) are supported. Any mix of devices is supported for up to 2 players! Refer to wiki for cable schematic and config documentation.

    The low level protocol is UART based. It is well documented in various specifications but the most up-to-date one is contained in Chapter 9. Input devices of the Technical Documentation for CDI 605 / 605T Users that can be found on ICDIA.

    CD-i pinout for dual interface front port

    The spec defines RTS and RXD pin as standard RS-232 levels: 

    - logical 1: -15V < signal level < +0.8V
    - logical 0: +2.4V < signal level < + 15V

    But from what I saw in various schematics the logical 1 level is always 0V and the logical 0 is 5V. So when interfacing with a CD-i interface level shifters are enough (no need for MAX232) as long the UART is configured to be inverted.

    Pointing devices like gamepad and mouse defined speed of 1200 & 9600 baud in the original spec but only 1200 devices ever got released. Newer CD-i players dropped 9600 support on the front ports and the latest spec actually removed 9600 as a possible baud rate for mouse and gamepad.

    For mouse, gamepad & type 'T' keyboard data signaling is 7 bits with 2 stop bits LSB first. For type 'K' & 'X' keyboards signaling is 8 bits with 1 stop bit LSB first.

    Unlike most other game system the CD-i inputs are not polled. As long the RTS line is released devices are free to send data when state change.

    Devices are identified once at boot time by holding the RTS line low. Once RTS line is released devices are required to send their 1 byte identification followed by their initial status data.

    T is also used for 3rd keyboard type.

    This was a problem for BlueRetro as devices per CD-i spec are required to answer the ID request within 500 ms. However BlueRetro take around 700 ms to read its configuration at boot. To work around this BlueRetro need to be powered externally and powered before powering the CD-i. This give the extra time required to load the config and to be ready to answer the ID request.

    IDs request at boot for gamepad and 'K' keyboard.
    IDs request at boot for mouse and 'T' keyboard.

    Controller & Mouse

    Status update sent on buttons press and release.
    On axes movements update are continuously sent if value is not neutral (0).

    'K' & 'X' type keyboards

    Key A pressed and released
    Key A pressed and released while holding shift key
    Caps Lock press followed by Key A press and release

    'T' type keyboard

    Later CD-i model like my CD-i 450 only had a single physical front port including 2 serial port. Only the secondary port was compatible with 8 bits UART configuration that keyboards (K & X) and modem required. This posed a problem for CD online application as this made impossible to use the previous keyboard simultaneously with the modem. To answer this issue Philips defined the 'T' keyboard spec that piggy back on the tablet 'T' ID and redefine the data format to include the same data as the 'K' type keyboard.

  • PC-FX interface

    Jacques Gagnon04/02/2021 at 20:52 0 comments

    I added PC-FX support with version v0.14! Regular pad and mouse are supported. Any mix of devices is supported for up to 2 players! Refer to wiki for cable schematic and config documentation.

    The low level protocol is pretty much like SPI mode 0 for clock and data line. You got the /LATCH line that can be inverted to be use as a CS. An /OE signal can mute the output from the peripheral when high. The console poll the peripherals 5 times in a row every frame. This look like how PC Engine controllers are polled as well for the multitap. Maybe a multitap was plan for the PC-FX as well?

    Sequential 2P polling with 5 consecutive poll each

    Data line is inverted and LSB is sent first. Clock may sometimes cycle while LATCH is held low, these cycle must be ignored.

    Controller poll

    The two controllers are often polled simultaneously.

    Simultaneous 2P polling

    Getting the ESP32 SPI timing was a bit tricky, In my mind this should be SPI Mode 2 but somehow that was very unreliable. Using Mode 0 timing is rock solid however.

    Regular controller

    RX: FFFFFF0F (LSB first)
        ││││  ├┘
        ││││  └ ID?
        │││└ Left, Down, Right, Up
        ││└ 1, Mode2, 1, Mode1
        │└ IV, III, II, I
        └ Run, Select, VI, V


    RX: FFFFFF2F (LSB first)
        ├┘├┘ │├┘
        │ │  │└ ID?
        │ │  └ Buttons (1, 1, Right, Left)
        │ └ X axis (8 bits) (Left: -, Right: +, Two's complement, inverted, LSB first)
        └ Y axis (8 bits) (Up: -, Down: +, Two's complement, inverted, LSB first)

  • 3DO interface

    Jacques Gagnon03/29/2021 at 00:45 0 comments

    I just added 3DO support with version v0.13! Regular pad, flightstick and mouse are supported. Any mix of devices is supported for up to 8 players! Refer to wiki for cable schematic and config documentation.

    The 3DO interface is quite unique as 8 players are supported via a single port! 3DO peripherals for the most part include an input port on them allowing to daisy-chain controller back to back. No extra port on console or multitap are required!

    The low level protocol is pretty much like SPI mode 3. You got the CLK, a data output and a data input. Base on my test the console data output is not used by the controller. The big difference with SPI is that there is no chip select signal. Frame start is signaled by holding the CLK line high for 500 us.

    Data from daisy-chained peripherals are simply appended to the transmission back to back, first controller transmitted first. 3DO BIOS and some games will always query for 200 bytes of data. Some games only query what they need. Extra read data is always 0xFF.

    This is one of the easiest systems to implement in BlueRetro. The only challenge was to generate a chip select signal for the ESP32 SPI hardware. The ESP32 SPI slave hardware is unfortunately not very flexible. I loop back my generated CS GPIO output into the ESP32 SPI CS input.

    See generated CS signal in yellow base on CLK signal Start

    Regular controller

    RX: 8000
        │││└ R, L , 0, 0
        ││└ B, C, P, X
        │└ Up, Right, Left, A
        └ 8, 0, 0, Down


            ┌ Y axis (10 bits) (Up: -, Down: +, Two's complement)
    RX: 49000000
        ├┘│  └┬┘
        │ │   └ X axis (10 bits) (Left: -, Right: +, Two's complement)
        │ └ Buttons (Left, Middle, Right, 0)
        └ ID


    I didn't RE this one my self, base on:

               ┌ X axis (10 bits) (Left: -, Right: +, Two's complement)
    RX: 017B08802008020000
        └┬───┘  └┬┘└┬┘│││
         └ IDs?  │  │ ││└ P, X, L, R
                 │  │ │└ Up, Down, Right, Left
                 │  │ └ Trigger, A, B, C
                 │  └ Z axis (10 bits) (Two's complement)
                 └ Y axis (10 bits) (Up: -, Down: +, Two's complement)

View all 55 project logs

View all 3 instructions

Enjoy this project?



amilton mendes bastos wrote 09/19/2021 at 14:59 point

Where do I find the components for me to assemble mine? The pcb you sell?

  Are you sure? yes | no

Alisson Anderson wrote 08/04/2021 at 05:11 point

Hello dear friend. I live in Brazil and projects in electronics are so hard to complete, and the dollar costs 5x the value of my currency. I would like to know if you would sell me one of these adapters, as it would be more practical, and less expensive for me.

  Are you sure? yes | no

BBsan wrote 09/05/2020 at 07:22 point


This is a really great project!!

I‘m trying to build some kind of a „lite“ Version using a Devkit v4 without SD card for use only with my Gamecube.  Unfortunately I wasn‘t able to find any documentation about how to pair my PS3 Controller... Could you briefly explain it somewhere? Thanks!!!😊 

  Are you sure? yes | no

Jacques Gagnon wrote 09/07/2020 at 15:54 point

Sorry missed your message, at boot on the serial console the log will display your ESP32 BDADDR (MAC). Search for line "local_bdaddr". Then connect the PS3 ctrl to a PC via USB and use a tool call "sixaxis pair tool" to set the ESP32 Address. Drop by the  chat ( if you need more help! Thanks for giving BlueRetro a try!!

  Are you sure? yes | no

BBsan wrote 09/07/2020 at 17:28 point

Thanks a lot! This worked really well 😊 I just have two problems now with my SIXAXIS:

1. Once it starts vibrating it doesn't stop anymore.

2. R2 doesn't seems the be mapped on GC output as it seems.

But wow - what a nice project!!! 😊😊 

  Are you sure? yes | no

Jacques Gagnon wrote 09/07/2020 at 16:48 point

  Are you sure? yes | no

Arnaldo Pirrone wrote 07/26/2020 at 10:18 point

Hi there,

Is the support for original Xbox planned? (maybe using the same original gamepads)

  Are you sure? yes | no

Jacques Gagnon wrote 07/26/2020 at 11:15 point

Yes but it's very far on my list, it's an USB interface so it will require a special adapter cable with some uC with a USB PHY.

  Are you sure? yes | no

PixJuan wrote 07/24/2020 at 10:23 point

I was wondering if you know of any 3d model of joystick connector, because it would hurt me to cut one from a 30 year old Joystick :-(

  Are you sure? yes | no

Jacques Gagnon wrote 07/24/2020 at 10:27 point

Just buy cord extension on AliExpress they are around 1 to 3$ each.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates