/Tetris-Duel

Multiplayer Tetris for Raspberry Pi (in bare metal assembly)

Primary LanguageAssemblyMIT LicenseMIT

Tetris Duel

Note: This project has never been tested with the new Raspberry Pi 2.

As an experiment on basic game networking in bare metal assembly, we created a multiplayer Tetris game for Raspberry Pi. Watch our game demo here: http://youtu.be/hTqKRdcKZ9k

Our source code features:

  • 4000 lines of documented ARM assembly code
  • Asynchronous networking for two Pis connected via GPIO
  • Optimized driver (60 μs duty cycle) for a single NES controller
  • Rendering logic for HDMI output with double buffering
  • Custom ARMv6 assembler written from scratch in C (released as binary only)

We completed this project in 3 weeks, amidst exams and normal school work, as an extension to Imperial College London's first year computing project.

Setup Guide

Prerequisites

Single Player

  1. Male - Male jumper wires x5
  2. Female - Male jumper wires x5
  3. 260 ohm resistors x3
  4. Breadboard x1
  5. NES controller x1
  6. Raspberry Pi rev 2, SD card, power cable x1
  7. Screen and HDMI cable x1

Multiplayer

  1. Single player prerequisites x2
  2. Female - Male jumper wires x14
  3. 10k ohm resistors x6
  4. Breadboard x1

Software Setup

  1. Format your SD card with Raspbian OS following the image installation guide

  2. Assemble the game with the provided assembler (or the official ARM assembler)

    on mac:

     ./assemble_mac tetris.s kernel.img
    

    on linux:

     ./assemble_linux tetris.s kernel.img
    
  3. Copy the generated kernel.img to your SD card, replacing existing file

  4. (Optional) Repeat step 1-3 on second Pi for multiplayer gameplay

  5. Before playing, ensure every component is wired correctly as described in Hardware Setup

Hardware Setup

NES Controller

Connect your NES controller to the GPIO pins as shown in the following table.

NES Controller Pin GPIO Pin
Power 1
Latch 11
Clock 12
Data 13
Ground 14
          +----> Power  (white)
          |
  +---------+    
  | x  x  o   \     
  | o  o  o  o |    
  +------------+
    |  |  |  |
    |  |  |  +-> Ground (red)
    |  |  +----> Clock  (black)
    |  +-------> Latch  (yellow)
    +----------> Data   (green)

gpio header pins

Note: latch, clock, and data pins should be connected using 260 ohm resistors as shown in our demo setup:

![NES controller](doc/NES\ controller.jpg)

Networking (Multiplayer)

Connect a second Pi running the same kernel using the following GPIO pins.

P1 Pin Name P1 Pin No. P2 Pin No. P2 Pin Name
Data in 15 16 Data out
Data out 16 15 Data in
Status in 18 22 Status out
Status out 22 18 Status in
Game in 21 23 Game out
Game out 23 21 Game in
Ground 20 20 Ground

Note: all pins (except ground) should be connected using 10k ohm resistors as shown in our demo setup:

![Networking](doc/Networking\ and\ controllers.jpg)

FAQ

  1. Where is tetrisToProcess.s?

We have removed our custom preprocessor (as described in our final report) from github release for a cleaner repository. tetris.s now contains all code in tetrisToProcess.s with only variable names replaced by actual values.

  1. Why do you have all the code in only one file?

We do understand the importance of writing modular code. However, as part of the requirement of our school project, we must assemble our entire game using our custom assembler which, due to time constraint, was not made to support generating ELF headers for linker scripts.

That said, we have taken great care to separate our code into different sections within the file using comments and we have also refactored as many reusable routines as we can.

Team

Acknowledgement

This is a university project intended for educational purposes and not for commercial use. The tile images were taken from Tetris Battle, which also inspired our game logic.