Reviving Retro Gaming: Atari Classics with a Modern Twist
Concept:
This project aims to breathe new life into classic Atari games by reimagining them with interactive physical controls and a unique display using flip-dot technology. The initial implementation features two iconic games, Tetris and Snake, with the potential for future expansion.
The IM Showcase Documentation & Video:
Implementation:
– Arduino Uno
– Buttons
– Wires
– Resistors
– Flip-dots
Interaction Design:
– Buttons are connected to the Arduino and act as input devices for controlling the games.
– The Arduino communicates with the Processing program via serial communication, sending button press information.
– Processing handles game logic and generates the visuals displayed on the flip-dots.
– Another serial communication channel is established between Processing and the flip-dots to send display data.
Arduino Code:
– The Arduino code reads the button states and sends them to Processing via serial communication.
// Arduino Sketch
void setup() {
Serial.begin(9600); // Start serial communication at 9600 baud rate
pinMode(3, INPUT_PULLUP); // Set pin 3 as an input with an internal pull-up resistor
pinMode(4, INPUT_PULLUP); // Set pin 4 as an input with an internal pull-up resistor
pinMode(5, INPUT_PULLUP); // Set pin 5 as an input with an internal pull-up resistor
pinMode(6, INPUT_PULLUP); // Set pin 6 as an input with an internal pull-up resistor
}
void loop() {
// Read the state of the buttons
int buttonState3 = digitalRead(3);
int buttonState4 = digitalRead(4);
int buttonState5 = digitalRead(5);
int buttonState6 = digitalRead(6);
// Send the button states over serial, separated by commas
Serial.print(buttonState3);
Serial.print(",");
Serial.print(buttonState4);
Serial.print(",");
Serial.print(buttonState5);
Serial.print(",");
Serial.println(buttonState6); // 'println' for a new line at the end
delay(100); // Delay for a short period to avoid sending too much data
}
Processing Code:
The Processing code performs several key tasks:
– Game Logic: Manages game mechanics, including player movement, collision detection, and game state.
– Visuals: Generates the graphics for each game to be displayed on the flip-dots.
– Serial Communication: Receives button input data from the Arduino and sends display data to the flip-dots.
Casting to Flip–dots:
The Processing code utilizes a custom library to communicate with the flip–dots and send the display data.
import processing.net.*;
import processing.serial.*;
void cast_setup() {
if (!config_cast) return;
if (castOver == 1) {
for (int i = 0; i < netAdapters.length; i++) {
String[] adapterAddress = split(netAdapters[i], ':');
adaptersNet[i] = new Client(this, adapterAddress[0], int(adapterAddress[1]));
}
}
else if (castOver == 2) {
// printArray(Serial.list());
for (int i = 0; i < serialAdapters.length; i++) {
String[] adapterAddress = split(serialAdapters[i], ':');
adaptersSerial[i] = new Serial(this, adapterAddress[0], int(adapterAddress[1]));
}
}
}
void cast_broadcast() {
if (!config_cast) return;
int adapterCount = netAdapters.length;
if (castOver == 2) {
adapterCount = serialAdapters.length;
}
for (int adapter = 0; adapter < adapterCount; adapter++) {
for (int i = 0; i < panels.length; i++) {
if (panels[i].adapter != adapter) continue;
cast_write(adapter, 0x80);
cast_write(adapter, (config_video_sync) ? 0x84 : 0x83);
cast_write(adapter, panels[i].id);
cast_write(adapter, panels[i].buffer);
cast_write(adapter, 0x8F);
}
}
if (config_video_sync) {
for (int adapter = 0; adapter < adapterCount; adapter++) {
cast_write(adapter, 0x80);
cast_write(adapter, 0x82);
cast_write(adapter, 0x8F);
}
}
}
void cast_write(int adapter, int data) {
if (castOver == 1) {
adaptersNet[adapter].write(data);
}
else if(castOver == 2) {
adaptersSerial[adapter].write(data);
}
}
void cast_write(int adapter, byte data) {
cast_write(adapter, data);
}
void cast_write(int adapter, byte[] data) {
if (castOver == 1) {
adaptersNet[adapter].write(data);
}
else if(castOver == 2) {
adaptersSerial[adapter].write(data);
}
}
Challenges and Solutions:
Initially, the project aimed to use p5.js to handle the game logic and visuals. However, challenges arose in establishing reliable communication and sending data to the flip-dots. To overcome this, the decision was made to switch to Processing, which provided a more stable environment for serial communication and flip-dot control.
Proud Achievements:
Successful Integration of Hardware and Software: The project combines Arduino, buttons, and flip-dots with Processing to create a unique gaming experience.
Retro Games with a Modern Twist: Classic Atari games are revitalized with physical controls and a visually appealing flip-dot display.
Future Improvements:
Expand Game Library: Add more classic Atari games or even explore the possibility of creating new games specifically designed for this platform.
Enhance Visuals: Experiment with different animation techniques and graphical styles to further enhance the visual appeal of the games on the flip-dot display.
Refine User Interface: Explore additional input methods or create a more intuitive menu system for navigating between games.
Explore p5.js Integration: Revisit the possibility of using p5.js in the future if more robust libraries or solutions for flip-dot communication become available.
Instructions

Check the full code on GitHub: https://github.com/pavlyhalim/Atari
