Close

Attempt 1 - C Code

A project log for Pong in AVR

Final project of the AVR Architecture Course

paulson-k-antonyPaulson K Antony 03/01/2021 at 11:190 Comments

I coded the whole thing in C to make sure my logic is sound. 

Hit a few bumps in interfacing SPI with the MAX7219 LED Matrix but it worked eventually

Implemented a simple ballChase algorithm for the computer's paddle to make things easier for me while coding in assembly. The downside is you can never win against the computer :P

#include <SPI.h>

#define CLK_PIN   13
#define DATA_PIN  11 
#define CS_PIN    10 
#define LB 7         
#define RB 6         

#define lo8(x) ((x)&0xff)
#define hi8(x) ((x)>>8)

int playerPaddle = 2;
int compPaddle = 2;
int compDirection = 1;
int ballx = 6;
int bally = 4;
int speedx = 1;
int speedy = -1;
boolean gameOver = false;

uint16_t buffer = 0 ; 

void refresh(){
  for(int i=1;i<=8;++i)
  {
    if(i==(playerPaddle-1)|i==(playerPaddle)|i==(playerPaddle+1))
      bitSet(buffer,0);
    if(i==(compPaddle-1)|i==(compPaddle)|i==(compPaddle+1))
      bitSet(buffer,15);
    if(i==bally)
      bitSet(buffer,ballx);

    digitalWrite(CS_PIN, LOW);
    SPI.transfer(i);
    SPI.transfer(lo8(buffer));
    SPI.transfer(i);
    SPI.transfer(hi8(buffer));
    digitalWrite(CS_PIN, HIGH);
    
    buffer=0;
  }
}

void updateBall()
{
  // Reverse direction When hitting the bat
  if ((ballx > 13) & (speedx == 1) & (bally <= (compPaddle + 1)) & (bally >= (compPaddle -1)))
    speedx = -1;
  else
    if ((ballx >14) & (speedx == 1))
    {
      speedx=0;
      speedy=0;
      gameOver = true;
    }
  
  if ((ballx < 2) & (speedx == -1) & (bally <= (playerPaddle + 1)) & (bally >= (playerPaddle -1)))
    speedx = 1;
  else
    if ((ballx < 1) & (speedx == -1))
    {
      speedx=0;
      speedy=0;
      gameOver = true;
    }
  if (bally == 8) 
    speedy = -1;
  if (bally == 1) 
    speedy = 1;

  ballx += speedx;
  bally += speedy;

}

void ballChaser()
{
  if((compPaddle + 1) < bally)
    ++compPaddle;
  if((compPaddle - 1) > bally)
    --compPaddle;
}

void lose()
{
  while(true)
  {
    clearDisplays();
    delay(500);
    refresh();
    delay(500);
  }
}


void movePaddleLeft(){
  if(playerPaddle!=2)
    --playerPaddle;
}

void movePaddleRight(){
  if(playerPaddle!=7)
    ++playerPaddle;
}

void sendAll(int registerIndex, int value) {
  digitalWrite(CS_PIN, LOW);
  for (int i = 0; i < 2; i++) {
    SPI.transfer(registerIndex);
    SPI.transfer(value);
  }
  digitalWrite(CS_PIN, HIGH);
}

void clearDisplays() {
  for (int row = 1; row <= 8; row++) {
    sendAll(row, 0);
  }
}

void setup() {
  SPI.begin();
  sendAll(0xf, 0); // Disable test mode
  sendAll(0xb, 7); // Set scanlines to 8
  clearDisplays();
  sendAll(0xc, 1); // Enable display

  pinMode(LB, INPUT_PULLUP);
  pinMode(RB, INPUT_PULLUP);

}


void loop() {
  updateBall();
  if(gameOver)
    lose();

  ballChaser();
  
  if(!digitalRead(LB))
    movePaddleLeft();
  if(!digitalRead(RB))
    movePaddleRight();
  
  delay(100);
  refresh();
}

Setup initializes all the pins required for SPI and the buttons

Loop calls the following functions -

Discussions