MetaView
Published © MIT

Let your Arduino Uno play against itself on VGA Monitor

An Arduino Uno plays a kind of shooting game against itself on an old VGA monitor. No additional hardware or library was used.

IntermediateFull instructions provided1 hour471
Let your Arduino Uno play against itself on VGA Monitor

Things used in this project

Story

Read more

Schematics

schematics_88wNFk9LWf.png

Code

Shooting game

Arduino
/**
 * Pink, Ligh Blue, White (thick core): RGB Pin 2
 * Green (thick core): H-Sync Pin 3
 * Blue (thin core): V-Sync Pin 10
 * 
 * 
 */




#define nop __asm__("nop \n")


#define SCREEN_W 40
#define SCREEN_H 30

char PXL_DATA [SCREEN_H][SCREEN_W]; 
int  lineCounter;
char skipLine;
char PXL_OUT;
char colP1 = (SCREEN_W-3) / 2;
char dirP1 = 1;
char rowP1 = 27;
char colP2 = (SCREEN_W-3) / 2;
char dirP2 = -1;
char rowP2 = 3;
bool bulletP1Fired = 0;
char bulletP1X = 0;
char bulletP1Y = 0;
char dyP1;
bool bulletP2Fired = 0;
char bulletP2X = 0;
char bulletP2Y = 0;
char dyP2;

char scoreP1;
char scoreP2;

ISR(TIMER1_OVF_vect)
  {lineCounter = 0;}


ISR(TIMER2_OVF_vect)
  {
    sei();
    __asm__("sleep \n");
  }



ISR(TIMER2_COMPB_vect)
{
  register char  columnCounter;
  register char* rowPtr;

  switch (PXL_OUT){
    case 1:
    rowPtr = &(PXL_DATA[(lineCounter - 35)>>4][0]);
    columnCounter = SCREEN_W;

    while(columnCounter--){
      PORTD = (*(rowPtr++)<<PD2);
      nop;
    }
    nop;
    nop;
    nop;
    PORTD = 0;
    break;
  }

  lineCounter++;
  skipLine = !skipLine;

  if ( skipLine && (lineCounter >= 35) && (lineCounter < 515) ){
    PXL_OUT = 1;
  }
  else{
    PXL_OUT = 0;
  }
}


void setup() {
  cli();                   //DISABLE INTERRUPTS
  PORTD = 0;
  pinMode(10, OUTPUT);    
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
  
  //pinMode(A0,INPUT);
  //pinMode(12, INPUT);
 
  TCCR1A = 0b00100011;     //PIN D10 OUTPUT, FAST PWM MODE 
  TCCR1B = 0b00011101;     //FAST PWM, PRESCALER OF 1024
  TIMSK1 = 0b00000001;     //OVERFLOW INTERRUPT ENABLE
  TIFR1  = 0b00000001;     //CLEAR OVERFLOW FLAG
  //TCNT1  = 0;            //rst t1
  TCCR2A = 0b00100011;     //PIN D3 OUTPUT, FAST PWM MODE
  TCCR2B = 0b00001010;     //FAST PWM, PRESCALER OF 8
  TIMSK2 = 0b00000101;     //OVERFLOW INTERRUPT ENABLE
  TIFR2  = 0b00000101;     //CLEAR OVERFLOW FLAG
  //TCNT2  = 0;            //rst t2 
  OCR1A  = 259;            //SET FREQ OF T1
  OCR1B  = 0;              //VSYNC PULSE DURATION
  OCR2A  = 63;             //SET FREQ OF T2
  OCR2B  = 7;              //HSYNC PULSE DURATUIN
  SMCR = bit(SE);
  memset(PXL_DATA, 0, sizeof(PXL_DATA));
  lineCounter = 0;
  scoreP1 = 0;
  scoreP2 = 0;
  sei();
}

void gameCode(){  
}

void loop()
{
	bool shootP1 = (bulletP1Fired == 0) && (random(0, 100) > 90);
	bool shootP2 = (bulletP2Fired == 0) && (random(0, 100) > 90);

	colP1 = colP1 + dirP1;
	if (colP1 < 0)
	{
		colP1 = 0;
		dirP1 = 1;
	}
	else if (colP1 > (SCREEN_W-3))
	{
		colP1 = SCREEN_W-3;
		dirP1 = -1;
	}
	else
	{
		if (random(0, 10) > 8)
			dirP1 = -1 * dirP1;
	}
	colP2 = colP2 + dirP2;
	if (colP2 < 0)
	{
		colP2 = 0;
		dirP2 = 1;
	}
	else if (colP2 > (SCREEN_W-3))
	{
		colP2 = SCREEN_W-3;
		dirP2 = -1;
	}
	else
	{
		if (random(0, 10) > 8)
			dirP2 = -1 * dirP2;
	}
  
  
	if (shootP1 == 1)
	{
		bulletP1Fired = 1;
		dyP1 = 0.0;  
		bulletP1X = colP1;
		bulletP1Y = rowP1;
	}
	if ((bulletP1Fired == 1) && (dyP1 < SCREEN_H))
	{
		bulletP1Y = rowP1 - dyP1;
		dyP1 = dyP1 + 1;
	}
	if (dyP1 >= SCREEN_H)
	{
		bulletP1Fired = 0;
		bulletP1Y = SCREEN_H;
	}
	if ((bulletP1Fired == 1) && (bulletP1X >= (colP2-1)) && (bulletP1X <= (colP2+1)) && (bulletP1Y == rowP2))
	{
		colP2 = random(1, 36);
		bulletP1Fired = 0;
		dyP1 = SCREEN_H;
		scoreP1 = scoreP1 + 4;
		if (scoreP1 >= 37)
		{
			scoreP1 = 0;
		}
	}
  

	if (shootP2 == 1)
	{
		bulletP2Fired = 1;
		dyP2 = 0.0;  
		bulletP2X = colP2;
		bulletP2Y = rowP2;
	}
	if ((bulletP2Fired == 1) && (dyP2 < SCREEN_H))
	{
		bulletP2Y = rowP2 + dyP2;
		dyP2 = dyP2 + 1;
	}
	if (dyP2 >= SCREEN_H)
	{
		bulletP2Fired = 0;
		bulletP2Y = SCREEN_H;
	}
	if ((bulletP2Fired == 1) && (bulletP2X >= (colP1-1)) && (bulletP2X <= (colP1+1)) && (bulletP2Y == rowP1))
	{
		colP1 = random(1, 36);
		bulletP2Fired = 0;
		dyP2 = SCREEN_H;
		scoreP2 = scoreP2 + 4;
		if (scoreP2 >= 37)
		{
			scoreP2 = 0;
		}
	}

	screen_refresh();
}

void draw_0(char x, char y)
{
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+1][x+0] = 0;
	PXL_DATA[y+1][x+2] = 0;
	PXL_DATA[y+2][x+0] = 0;
	PXL_DATA[y+2][x+2] = 0;
	PXL_DATA[y+3][x+0] = 0;
	PXL_DATA[y+3][x+2] = 0;
	PXL_DATA[y+4][x+0] = 0;
	PXL_DATA[y+4][x+2] = 0;
	PXL_DATA[y+5][x+0] = 0;
	PXL_DATA[y+5][x+2] = 0;
	PXL_DATA[y+6][x+1] = 0;
}

void draw_1(char x, char y)
{
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+1][x+1] = 0;
	PXL_DATA[y+2][x+1] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+4][x+1] = 0;
	PXL_DATA[y+5][x+1] = 0;
	PXL_DATA[y+6][x+1] = 0;
}

void draw_2(char x, char y)
{
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+1][x+0] = 0;
	PXL_DATA[y+1][x+2] = 0;
	PXL_DATA[y+2][x+2] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+4][x+1] = 0;
	PXL_DATA[y+5][x+0] = 0;
	PXL_DATA[y+6][x+0] = 0;
	PXL_DATA[y+6][x+1] = 0;
	PXL_DATA[y+6][x+2] = 0;
}

void draw_3(char x, char y)
{
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+1][x+0] = 0;
	PXL_DATA[y+1][x+2] = 0;
	PXL_DATA[y+2][x+2] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+4][x+2] = 0;
	PXL_DATA[y+5][x+0] = 0;
	PXL_DATA[y+5][x+2] = 0;
	PXL_DATA[y+6][x+1] = 0;
}

void draw_4(char x, char y)
{
	PXL_DATA[y+0][x+2] = 0;
	PXL_DATA[y+1][x+1] = 0;
	PXL_DATA[y+1][x+2] = 0;
	PXL_DATA[y+2][x+0] = 0;
	PXL_DATA[y+2][x+2] = 0;
	PXL_DATA[y+3][x+0] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+3][x+2] = 0;
	PXL_DATA[y+4][x+2] = 0;
	PXL_DATA[y+5][x+2] = 0;
	PXL_DATA[y+6][x+2] = 0;
}

void draw_5(char x, char y)
{
	PXL_DATA[y+0][x+0] = 0;
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+0][x+2] = 0;
	PXL_DATA[y+1][x+0] = 0;
	PXL_DATA[y+2][x+0] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+3][x+2] = 0;
	PXL_DATA[y+4][x+2] = 0;
	PXL_DATA[y+5][x+0] = 0;
	PXL_DATA[y+5][x+2] = 0;
	PXL_DATA[y+6][x+1] = 0;
}

void draw_6(char x, char y)
{
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+1][x+0] = 0;
	PXL_DATA[y+1][x+2] = 0;
	PXL_DATA[y+2][x+0] = 0;
	PXL_DATA[y+3][x+0] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+4][x+0] = 0;
	PXL_DATA[y+4][x+2] = 0;
	PXL_DATA[y+5][x+0] = 0;
	PXL_DATA[y+5][x+2] = 0;
	PXL_DATA[y+6][x+1] = 0;
}

void draw_7(char x, char y)
{
	PXL_DATA[y+0][x+0] = 0;
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+0][x+2] = 0;
	PXL_DATA[y+1][x+2] = 0;
	PXL_DATA[y+2][x+1] = 0;
	PXL_DATA[y+3][x+0] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+3][x+2] = 0;
	PXL_DATA[y+4][x+1] = 0;
	PXL_DATA[y+5][x+1] = 0;
	PXL_DATA[y+6][x+1] = 0;
}

void draw_8(char x, char y)
{
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+1][x+0] = 0;
	PXL_DATA[y+1][x+2] = 0;
	PXL_DATA[y+2][x+0] = 0;
	PXL_DATA[y+2][x+2] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+4][x+0] = 0;
	PXL_DATA[y+4][x+2] = 0;
	PXL_DATA[y+5][x+0] = 0;
	PXL_DATA[y+5][x+2] = 0;
	PXL_DATA[y+6][x+1] = 0;
}

void draw_9(char x, char y)
{
	PXL_DATA[y+0][x+1] = 0;
	PXL_DATA[y+1][x+0] = 0;
	PXL_DATA[y+1][x+2] = 0;
	PXL_DATA[y+2][x+0] = 0;
	PXL_DATA[y+2][x+2] = 0;
	PXL_DATA[y+3][x+1] = 0;
	PXL_DATA[y+3][x+2] = 0;
	PXL_DATA[y+4][x+2] = 0;
	PXL_DATA[y+5][x+0] = 0;
	PXL_DATA[y+5][x+2] = 0;
	PXL_DATA[y+6][x+1] = 0;
}

void draw_sep(char x, char y)
{
	PXL_DATA[y+2][x+1] = 0;
	PXL_DATA[y+4][x+1] = 0;
}

void screen_refresh()
{
  char r, c;

  for (r = 0; r < SCREEN_H; r++) {
    for (c = 0; c < SCREEN_W; c++) {
      if ((r == rowP1) &&
        (c >= colP1) &&
        (c < colP1 + 3)) {
        PXL_DATA[r][c] = 0;
      }
      else if ((r == rowP1 - 1) &&
        (c >= colP1 + 1) &&
        (c < colP1 + 2)) {
        PXL_DATA[r][c] = 0;
      }
      else if ((r == rowP2 - 1) &&
        (c >= colP2) &&
        (c < colP2 + 3)) {
        PXL_DATA[r][c] = 0;
      }
      else if ((r == rowP2) &&
        (c >= colP2 + 1) &&
        (c < colP2 + 2)) {
        PXL_DATA[r][c] = 0;
      }
      else if ((bulletP1Fired == 1)&&(r == bulletP1Y) &&
        (c >= bulletP1X + 1) &&
        (c < bulletP1X + 2)) {
        PXL_DATA[r][c] = 0;
      }
      else if ((bulletP2Fired == 1) && (r == bulletP2Y) &&
        (c >= bulletP2X + 1) &&
        (c < bulletP2X + 2)) {
        PXL_DATA[r][c] = 0;
      }
      /*
      else if ((r >= enemyY) &&
        (r < enemyY + 1) &&
        (c >= enemyX) &&
        (c < enemyX + 1)) {
        PXL_DATA[r][c] = 0;
      }
      */
      else if ((r == 0) &&
        (c >= 0) &&
        (c < scoreP1)) {
        PXL_DATA[r][c] = 0;
      }
      else if ((r == 29) &&
        (c >= 0) &&
        (c < scoreP2)) {
        PXL_DATA[r][c] = 0;
      }
      else {
        PXL_DATA[r][c] = 1;
      }      
    }
  }

  switch (scoreP1/4)
  {
  case 0:
	draw_0(10, 10);
	break;
  case 1:
	draw_1(10, 10);
	break;
  case 2:
	draw_2(10, 10);
	break;
  case 3:
	draw_3(10, 10);
	break;
  case 4:
	draw_4(10, 10);
	break;
  case 5:
	draw_5(10, 10);
	break;
  case 6:
	draw_6(10, 10);
	break;
  case 7:
	draw_7(10, 10);
	break;
  case 8:
	draw_8(10, 10);
	break;
  case 9:
	draw_9(10, 10);
	break;
  }
  draw_sep(18, 10);
  switch (scoreP2/4)
  {
  case 0:
	draw_0(26, 10);
	break;
  case 1:
	draw_1(26, 10);
	break;
  case 2:
	draw_2(26, 10);
	break;
  case 3:
	draw_3(26, 10);
	break;
  case 4:
	draw_4(26, 10);
	break;
  case 5:
	draw_5(26, 10);
	break;
  case 6:
	draw_6(26, 10);
	break;
  case 7:
	draw_7(26, 10);
	break;
  case 8:
	draw_8(26, 10);
	break;
  case 9:
	draw_9(26, 10);
	break;
  }
}

Credits

MetaView
8 projects • 15 followers
Contact
Thanks to Dhruv Wadhwa.

Comments

Please log in or sign up to comment.