May 15, 2026
Description
Do you have a Cheap Yellow Display lying about? Perhaps something you purchased thinking I'll make something cool out of this someday? Well today is the day!
First see Till Harbaum's work https://github.com/harbaum/galagino as there you will find the inspiration for this model, and nearly all the software. Thanks Till!
Mini arcade cabinets are a nice throwback but wanted something in a late '80s portable form factor and came up with this. It is very part specific, and honestly the extra parts will cost you as much or more than the CYD you started with. The electronics in this build differ from what Till used and were chosen to be simple to deal with and also fit into a portable cabinet.
There is little soldering outside connecting wires together so it's a pretty simple build. The Nintendo Wii nunchuck and adaptor are replaced with an Adafruit Mini I2C Gamepad. By substituting the Nunchuck.h with the file below and crafting a cross over cable you will be good to go for game play.
Did not find a need for an audio amp for my CYD with the specified speaker. My CYD had the "fix" for poor audio quality and expect anything purchased now would also have it. The 1000mAh battery gives 4+ hours of play, and the USBc charger PCB handles both charging and boosting to 5v for the CYD.
Getting it together:
Print the top and back parts of the case, no supports. You will need 2 of the triangle buttons and 4 of the square buttons. Cycle those buttons a few times before you put the case together and make sure they slide, not crunch or drift.
There are two holes on the front and one on the back for DIY light pipes to carry the internal LEDs to the outside. Cleave with a utility knife come clear filament and poke through the hole to reach the LED. There is also a hole inside the back case along side the upside down mounted charger PCB. Put a length of filament through that hole and across the charger PCB to keep it from floating up when a USBc cable is plugged in.
Hopefully the picture of the open case reveals what goes where. Power is going to the connector next to the CYD USB port, leaving the middle 2 pins of TX/RX unused. Connector CN1 uses all 4 pins for the gamepad connection. Expect cable harness colors will differ, so make sure pin positions carry through not so much just color matching the wires.
Parts used:
ESP32-2432S028R - amazon.com/dp/B0DDPXD415
Adafruit Gamepad - adafruit.com/product/5743 get the cable too!
Speaker - amazon.com/dp/B0DZBLPHNS
LiPo Battery - amazon.com/dp/B0FZSR8MQY
On/Off Button - amazon.com/dp/B0BHHCS3K2
Charger PCB - amazon.com/dp/B0D7Z92K51
Single 2 pin and two 4 pin JST cables - amazon.com/dp/B091GCWJF8
Qty 9 m2.5 x 6mm screws - amazon.com/gp/product/B0DKXQBZXL
Supports are not required on any of the models and were printed at a 0.24 layer height
// Nunchuck.h
// Last modified 2/26/2026 - edl
// Swapped NintendoExtensionCtrl for Adafruit_seesaw, original commented out
// Original github.com/harbaum/galagino/blob/main/galagino/Nunchuck.h
// Thanks to forums.adafruit.com and Michael for the gamepad seesaw I2C setup
#ifndef _NUNCHUCK_H_
#define _NUNCHUCK_H_
// ----------------------------
// Standard Libraries
// ----------------------------
#include <Wire.h>
// ----------------------------
// Additional Libraries - one of these will need to be installed.
// ----------------------------
// This library is for interfacing with the Nunchuck
//#include <NintendoExtensionCtrl.h>
//Nunchuk nchuk;
//Adafruit Seesaw GamePad Support instead
#include "Adafruit_seesaw.h"
Adafruit_seesaw *ss;
// ----------------------------
#define BTN_LEFT 2
#define BTN_RIGHT 5
#define BTN_DOWN 1
#define BTN_UP 6
#define BTN_SELECT 0
#define BTN_START 16
uint32_t button_mask = (1UL << BTN_UP) | (1UL << BTN_LEFT) | (1UL << BTN_START) |
(1UL << BTN_RIGHT) | (1UL << BTN_DOWN) | (1UL << BTN_SELECT);
void nunchuckSetup() {
/*
Wire.begin(NUNCHUCK_SDA, NUNCHUCK_SCL);
if (!nchuk.connect()) {
Serial.println("Nunchuk on bus #1 not detected!");
delay(1000);
}
*/
Wire1.begin(NUNCHUCK_SDA, NUNCHUCK_SCL, 400000);
delay(100);
ss = new Adafruit_seesaw(&Wire1);
if(!ss->begin(0x50)){
Serial.println("GamePad NOT found!");
while(1) delay(1);
} else {
Serial.println("GamePad");
}
ss->pinModeBulk(button_mask, INPUT_PULLUP);
ss->setGPIOInterrupts(button_mask, 1);
}
int last_x = 0, last_y = 0;
unsigned char getNunchuckInput() {
// Reverse x/y values to match joystick orientation
int x = 1023 - ss->analogRead(14);
int y = 1023 - ss->analogRead(15);
if ( (abs(x - last_x) > 3) || (abs(y - last_y) > 3)) {
//Serial.print("x: "); Serial.print(x); Serial.print(", "); Serial.print("y: "); Serial.println(y);
last_x = x;
last_y = y;
}
uint32_t buttons = ss->digitalReadBulk(button_mask);
//Serial.println(buttons, BIN);
/*
if (! (buttons & (1UL << BTN_RIGHT))) {
Serial.println("Button A pressed");
}
if (! (buttons & (1UL << BTN_DOWN))) {
Serial.println("Button B pressed");
}
if (! (buttons & (1UL << BTN_LEFT))) {
Serial.println("Button Y pressed");
}
if (! (buttons & (1UL << BTN_UP))) {
Serial.println("Button X pressed");
} */
if (! (buttons & (1UL << BTN_START))) {
Serial.println("Button START pressed");
}
if (! (buttons & (1UL << BTN_SELECT))) {
Serial.println("Button SELECT pressed");
}
/*
boolean success = nchuk.update(); // Get new data from the controller
if (!success) { // Ruh roh
Serial.println("Nunchuck disconnected!");
return 0;
}
else {
// Read a joystick axis (0-255, X and Y)
// Roughly 127 will be the axis centered
int joyY = nchuk.joyY();
int joyX = nchuk.joyX();
return ((joyX < 127 - NUNCHUCK_MOVE_THRESHOLD) ? BUTTON_LEFT : 0) | //Move Left
((joyX > 127 + NUNCHUCK_MOVE_THRESHOLD) ? BUTTON_RIGHT : 0) | //Move Right
((joyY > 127 + NUNCHUCK_MOVE_THRESHOLD) ? BUTTON_UP : 0) | //Move Up
((joyY < 127 - NUNCHUCK_MOVE_THRESHOLD) ? BUTTON_DOWN : 0) | //Move Down
(nchuk.buttonZ() ? BUTTON_FIRE : 0) |
(nchuk.buttonC() ? BUTTON_EXTRA : 0) ;
*/
// Read a joystick axis (0-1024, X and Y)
// Roughly 512 will be the axis centered
int joyY = y;
int joyX = x;
return ((joyX < 512 - NUNCHUCK_MOVE_THRESHOLD) ? BUTTON_LEFT : 0) | //Move Left
((joyX > 512 + NUNCHUCK_MOVE_THRESHOLD) ? BUTTON_RIGHT : 0) | //Move Right
((joyY > 512 + NUNCHUCK_MOVE_THRESHOLD) ? BUTTON_UP : 0) | //Move Up
((joyY < 512 - NUNCHUCK_MOVE_THRESHOLD) ? BUTTON_DOWN : 0) | //Move Down
((! (buttons & (1UL << BTN_UP))) ? BUTTON_FIRE : 0) | // FIRE
((! (buttons & (1UL << BTN_DOWN))) ? BUTTON_FIRE : 0) | // FIRE
((! (buttons & (1UL << BTN_LEFT))) ? BUTTON_FIRE : 0) | // FIRE
((! (buttons & (1UL << BTN_RIGHT))) ? BUTTON_FIRE : 0) | // FIRE
((! (buttons & (1UL << BTN_SELECT))) ? BUTTON_EXTRA : 0) | // Start
((! (buttons & (1UL << BTN_START))) ? BUTTON_EXTRA : 0); // Start
/*}*/
}
#endif //_NUNCHUCK_H_License:
Creative Commons — Attribution — Noncommercial