Sei sulla pagina 1di 42

Brick Breaker Game

ECE 3710 Final Project

Andrew Deakin A01353937


Mitch Morse A01221890
12/12/2014
Table of Contents

1. Introduction ..................................................................................................................................2
2. Scope ............................................................................................................................................2
3. Design Overview .........................................................................................................................2
3.1. Requirements ................................................................................................................2
3.2. Dependencies ................................................................................................................2
3.3. Theory of operation.......................................................................................................3
3.4. Flowchart ......................................................................................................................4
3.5. Design Alternatives .......................................................................................................4
4. Design Details ..............................................................................................................................4
4.1. Physical Layout .............................................................................................................5
4.2. Peripherals.....................................................................................................................5
4.2.1. Ilitek ILI9341LCD .........................................................................................5
4.2.2. MicroChip MCP4725 Digital to Analog Converter.......................................5
4.2.3. Analog Speaker Board ...................................................................................5
4.3 Schematic .......................................................................................................................6
4.4. Game Cycle ...................................................................................................................6
4.4.1. Pause ..............................................................................................................6
4.4.2. Process ...........................................................................................................7
4.4.3. Move ..............................................................................................................7
4.4.4. Redraw ...........................................................................................................7
4.5. Collision Detection .......................................................................................................8
5. Testing........................................................................................................................................10
6. Conclusion .................................................................................................................................11
Appendices
A-Pictures ..........................................................................................................................12
B-Code ...............................................................................................................................15

1
1. Introduction
This document describes the design of a brick breaker game. The device is built onto a standard
breadboard and is powered by three AA batteries (for 4.5 V total power). The device is
controlled by a Texas Instruments Tiva-C TM4C123GH6PM Microcontroller. The main
peripherals include an Ilitek ILI9341LCD touchscreen (approximately 2.2 x 1.65 inches) and a
MicroChip MCP4725 Digital to Analog Converter (DAC). The DAC is also connected to an
analog speaker board for game noises. A small PCB with 5 buttons and one bi-color LED is
used to control the game, which is a standard “Brick Breaker” type game, based on the original
Atari Breakout. The LCD displays several bricks on the upper portion of the screen, which must
be broken to win. A ball bounces around the screen, breaking bricks when it hits them. The user
controls a small rectangular paddle situated at the bottom of the screen. He or she can position
this paddle to stop the ball from hitting the lower edge of the screen (which causes a loss of the
game). The ball bounces off the paddle at six different angles based on six hit zones on the
paddle. Using these different zones, the user has some control over the placement of the ball and
can attempt to destroy all the bricks, moving on to the next level. The game is arcade style,
meaning it cannot be “beat.” The user simply attempts to complete as many levels as possible
before losing, and tries to beat the high score. There are a total of five different levels, which
continue to cycle until the user loses. Each time the user finishes a level, the speed of the game
increases, making it more and more difficult to play until the he or she inevitably loses.

2. Scope
Both the software and hardware design of the Brick Breaker game will be covered in detail in
this document, as well as the methods used to test it. Section 3 gives a design overview,
including requirements, dependencies, theory of operation, and a flow chart. Section 4 gives
enough design detail to recreate the device, including a schematic. Section 5 briefly describes
the testing that was done to verify portions of the project, and section 6 gives a conclusion.

3. Design Overview
The following section discusses the requirements of the program, what the system is dependent
on, and the theory of operation.

3.1. Requirements
The requirements of this project are as follows:

3.1.1. - The game must have sound.


3.1.2. - The game must store a high score value to non-volatile memory.
3.1.3. - The game must have a refresh speed high enough to give the appearance
of fluid motion.
3.1.4. - The game must operate smoothly with little to no interruptions or errors.

3.2. Dependencies
Both the LCD screen and the microcontroller need to be powered with at least a 4.5-5
volt source. It is also critical that the program has time to do all of the collision detection
between the ball and any walls, bricks, or the paddle before moving the ball to its next
location.

2
3.3. Theory of operation
As depicted in the flowchart below, the program starts by doing all of the necessary
configuration and drawing the first level. After that, the program goes into a pause stage,
where it first turns the LED to yellow, shows the current and high scores, and waits for
the player to hit the un-pause button. While waiting for the player, the program also
checks for a reset code that will reconfigure and redraw the entire screen in case of
random glitch errors. Once the player is ready, the LED goes green and the game begins
with the Detect Collisions section.

Firsts the program checks to see if the ball has run into any edges of the screen. If the
ball has hit a bottom wall, the speaker plays the losing sound beeps and the gameplay
variables are reset. If the player has beaten the high score then the new high score is
saved to memory and the program goes to the pause stage so that the player can see their
score compared to the old high score. If they did not beat the high score then the
program still takes them to the pause screen so that they can see what their score was
compared to the current high score. If the ball hit the right, left, or top wall then the X
and Y speed are adjusted accordingly and the speaker plays the wall beep sound.

If the ball is not near the paddle or near the bricks, then the program goes on the Move
stage. If the ball is near the paddle, the program checks to see if the ball has hit the
paddle. If the ball did hit the paddle then it adjusts the X and Y speed as well as the
bounce angle accordingly and the speaker plays the paddle beep sound. If the ball has
not hit the paddle then the program goes on to the Move section.

If the ball was not near the paddle but was near the bricks then the program checks to see
if the ball has hit any bricks. If the ball did hit any bricks then it adjusts the X and Y
speed accordingly and the speaker plays the brick beep sound. If the ball has not hit any
bricks then the program goes on to the Move section.

For the Move section, the ball position is always updated based on its X and Y speed, but
the paddle position is only updated if any of the four movement buttons were
pressed. The program then waits for a timer to expire and redraws the ball and the
paddle, if the paddle has moved.

Lastly, the program checks to see if the level has been beaten. If so, it increments the
level number, increases the game-play speed, and redraws the bricks. Finally, it checks
to see if the pause button is being pressed. If so, it enters the pause function showing the
player's current score and the high score until the player is ready to play again. If the
pause button was not pressed then the program just starts over at the Detect Collisions
section.

3
3.4. Flowchart

3.5. Design Alternatives


Rather than using a timer and polling method to control the screen refresh rate, an
interrupt could be used. Ultimately this was decided against because the processing stage
absolutely needs to be completed before the ball position can be rewritten. Using the
timer and polling method guarantees that this will happen. However, it was decided that
interrupts must be used to play the beep sounds so that the program can continue without
waiting for the sound to finish.

4. Design Details
This section gives enough low level detail to allow the reader to recreate the device. It will cover
the physical layout, including descriptions of each peripheral and a schematic. It will also cover
the basic flow of the game cycle as well as a description of the collisions detection techniques
used.

4
4.1 Physical Layout
The Brick Breaker game device was built on a standard breadboard. The main unit of the
device is a Texas Instruments Tiva-C TM4C123GH6PM Microcontroller, which is
mounted to the breadboard with a breakout board. All other peripherals are wired to the
microcontroller through the board using cut-to-fit lead wires or sections of ribbon
cable. The entire device is powered by one central 4.5 V battery pack, which contains
three AA batteries and includes an on/off switch. The Tiva-C microcontroller is
connected to the 4.5V power line on its VBUS pin, which is usually the raw 5V USB
power line. This line is converted using an onboard power regulator to 3.3V. A picture
of the entire device is shown in Fig 1 of App A.

4.2 Peripherals
There are three peripheral devices connected to the board:
4.2.1. Ilitek ILI9341LCD. This is a small LCD (approximately 2.2 x 1.65
inches) with a 320x240 pixel resolution. It has resistive touchscreen capabilities,
but they were not used. The LCD backlight is powered by two pins connected to
the 4.5V battery pack, and the LCD controller by two pins connected to the 3.3V
output of the microcontroller. The microcontroller communicates with the LCD
using the internal SPI module in 8-bit freescale mode. Refer to the schematic
below for the pin-outs.
4.2.2. MicroChip MCP4725 Digital to Analog Converter. This 12-bit DAC is
used to convert digital values into analog voltages to produce sound. The
microcontroller communicates with the DAC using its Internal I2C module in
burst mode. A ten entry sine table is used in the code to transmit DAC values
representing a sine wave to the DAC. When enabled, this produces an analog sine
wave, where the frequency is controlled by the speed over which the sine table is
iterated.
4.2.3. Analog Speaker Board. This generic analog speaker board also includes
potentiometers, which were not used. Its audio input line is connected to the
analog output of the DAC. When the DAC outputs a sine wave, the speaker emits
a solid tone. The game has several different frequency tones, which are each
output for only a short time, making a beeping noise. These beeps are achieved in
software by enabling a timer interrupt which outputs entries from the 10 entry
sine table at a frequency determined by the timer expiration period. Another
timer interrupt is used to disable the beep after a given amount of time has
expired. This allows the output of the beep to be any length and any frequency
(within the speaker’s range) with a single function call.

5
4.3 Schematic

4.4 Game Cycle


This section will discuss the basic software design of the game, which follows a fairly
straightforward cyclical procedure of four basic stages.
4.4.1 Pause. This is the initial state of the game. The game also returns to this
stage anytime the user presses the pause button. In it, a portion of the screen is
overwritten with a textual printout of the user’s current score and the high score as
seen in Fig 2b. Each character of the printout is stored in program memory as a
two dimensional char array, with a value of 1 for a white pixel and a value of 0
for a black pixel. These arrays are iterated and each pixel is transmitted to the
LCD using the SPI module. The user’s score is stored in local memory, and is
incremented each time the ball breaks a brick, with higher level bricks being

6
worth more points. The high score is stored in the Tiva-C microcontroller’s
onboard EPROM module. Since this is non-volatile memory, the high score can
persist through power cycles. At the time of a loss, if the user’s current score is
greater than the high score, the user’s score is written to EPROM as the new high
score. The pause function also takes care of the two color LED on the
controller. Whenever the game is paused, the LED lights up orange. When the
game is in active play mode, the LED lights up green.
4.4.2. Process. This is the stage in which the current state of the game (in this
case just the positions of each object) are processed. The largest portion of this
stage is consumed by collision detection, which will be discussed in greater detail
in section 4.5. This stage also monitors the pause button (returning to stage 1), as
well as handling level advancing and game loss.
4.4.3. Move. In this stage, each moving object has its position updated according
to its speed. The ball’s position on the X and Y axis will increment by its XSpeed
and YSpeed. Its direction of travel is determined by the ratio of these two
speeds. For example, if the ball has an XSpeed of 2 and a YSpeed of 1, the ball
will be moving at a shallow angle up and to the right. In addition, the paddle’s
position on the X axis will increment by its XSpeed. While the ball’s position
always changes, the paddle’s position only changes when the user is pressing the
left or right movement buttons. Depending on which button is pressed, the paddle
will move by its XSpeed in either a positive or negative direction. The paddle can
also be moved in jumps. If the user is pressing the jump left or jump right
buttons, the paddle’s position will change to the far left or far right of the
screen. All of these buttons, as well as the pause button and a two color LED, are
located on a small PCB connected to the microcontroller with a bundle of
wires. Fig 3a shows a picture of active gameplay using this controller.
4.4.4. Redraw. In this stage, objects which have changed position or state are
redrawn. Usually, this only means that the ball is moved. To move the ball, its
old position on the LCD must be written black, and its new position must be
written white. This provides the illusion of motion on the screen. The paddle is
composed of a white bar with two narrow strips of black on either end. These
black strips are not visible, but succeed in covering up the trail of white that the
paddle would otherwise leave without a full overwrite of the paddle area. This is
not effective when the jump buttons are used, so the old position of the paddle
must be overwritten in that case. Bricks which have been broken are also written
black. Although it would be easier to rewrite the entire screen in the redraw
phase, this partial redraw method saves a lot of LCD time, making the moving
objects seem more fluid and the bricks more static.

After each cycle of these stages, the microcontroller waits for a timer to expire before
repeating the process. This allows the movements to happen at a consistent rate despite
changes is processing time for stage 2. The speed of the game can also be increased by
lowering the expiration time of this timer, down to a certain threshold. Luckily, that
threshold proved to be well above the maximum speed that a human user could
conceivably play the game.

7
4.5 Collision Detection
Collision detection was perhaps the most difficult section of this project. During the
processing stage, each moving object must determine if its area has overlapped that of
another object. Since the ball is the only object which can hit any other object, these
collision detections are always done in terms of the ball. The ball can hit any of the four
walls (the bottom wall causing a death), any edge of any brick, or the top of the
paddle. Each object is defined in code as a struct, with members such as .left, .right, .top,
and .bottom. The ball’s sides are compared with that of all other objects to check for an
overlap. To save time, only those collisions which are currently possible given the state
of the ball are processed. For example, if the ball is moving up and to the right, only the
left and bottom sides of the bricks are checked. Below is a code snippet showing the
code used to determine if the ball has hit the right side of any brick.

void checkRightSides(void)
{
int i, j;
Brick brick;
for(i=0; i<BRICKS_PER_COLUMN ; i++)
{
for(j=0; j<BRICKS_PER_ROW; j++)
{
brick = bricks[i][j];
//if in Y range and past left and not broken
if(!brick.broken && (ball.bottom-1 >= brick.top) && (ball.top+1<=
brick.bottom) && (ball.left <= brick.left) && (ball.left+2 >= brick.right))
{
ball.xSpeed = -ball.xSpeed;
breakBrick(i,j);
return;
}
}
}
}

The bricks are stored in a two dimensional array, and a pair of for loops iterate through
every one. A conditional ‘if’ statement determines if the ball’s left edge has gone past
the brick’s right edge. It also checks to make sure that the ball is in the same Y zone as
the brick. The figure below shows the X zone and Y zone of the brick, as well as the left
and right edges of the ball and brick, respectively. It also shows how the ball must
bounce off the brick at the same angle it enters. For example, if the ball hits the brick at a
45 degree angle, it must bounce off the brick at a 45 degree angle. This is done by
simply changing the sign of the X speed variable of the ball (ball.xSpeed = -
ball.xSpeed;). All collisions with vertical barriers change the XSpeed in the same way,
while all horizontal barriers change the sign of Y speed.

8
The only exception to the bouncing rule is the paddle. In order to give the user control
over the ball, the paddle has six different hit zones. Each zone bounces the ball off at a
different, set angle, regardless of the pre-bounce angle of the ball. The figure below
shows each of the six zones and the direction the ball bounces off of it, with a table
showing the new X and Y speeds for each zone.

Zone New XSpeed New YSpeed

Zone 1 -2 1

Zone 2 -2 2

Zone 3 1 2

Zone 4 1 2

Zone 5 2 2

Zone 6 2 1

9
5. Testing
The program was tested primarily through an auto-play feature that could be enabled in the
code. During this mode the game was simply watched to check for the specific errors
listed. The auto-play worked by simply keeping the paddle underneath the ball so that the game
would never end. Often, when the auto-play was enabled, the game was brought into a high
speed mode so that bugs and errors could be found sooner. Other testing methods, described
below, consisted primarily of physical measurements and playing the game.

Observations to Applicable
Test Procedure Observations
Verify Requirements

Yes, the movement of both


The auto-play feature was
Is the movement the ball and the paddle were
used to watch the program 3.1.3
consistently consistently fluid for all
run for an extended period 3.1.4
fluid? speeds that the program
of time.
will ever run at.

At first, the sound would


occasionally cause stalls in
The auto-play feature was Does the sound
game-play. To fix this, the
used to watch the program interrupts 3.1.1
sine table was reduced to
run, and points where the interfere with 3.1.3
just 10 values. This did not
ball made sound were game-play 3.1.4
degrade the sound quality
specifically observed. motion?
much, but did fix the
stalling problem.

A first some occasional


The auto-play feature was Are trails left
trials were left when the 3.1.1
used to watch the program behind from the
sound was played, but once 3.1.3
run and any trails were ball or paddle
the sine table was reduced 3.1.4
observed. movements?
to 10, it worked great.

At first the ball would


The auto-play feature was occasionally overlap by one
Does the ball
used to watch the program pixel, based on the X or Y
overlap any
run, and points where the speed, so an adjustment 3.1.4
bricks before
ball hit bricks were was made in the collision
breaking them?
specifically observed. detection which caused that
not to happen anymore.

The auto-play feature was Can the program


Yes, the program
used to continually run fast enough to
functioned smoothly at 3.1.3
increase the speed of make the game
every speed that the player 3.1.4
game-play to see where it difficult enough
could conceivably play at.
maxed out. without crashing?

10
The ball would
occasionally stick to one
The auto-play feature was
What other errors wall and bounce off of it
used to watch the program
if any show up repeatedly. This was fixed
run for an extended period 3.1.4
during game- by separating the left and
of time, while any other
play? right wall check functions
errors were observed.
into two separate checks,
instead of one.

This item was tested by Yes, every time the high


playing the game for a score is beaten it will let the
high score, as high scores player see their new high
are not kept during auto- Does beating the score compared to the old
play. Then the high score keep high score, and the next
3.1.2
microcontroller was and use the new game that is played shows
power cycled to make high score? their new high score. Also,
sure that new high score that high score is still there
was properly saved and once the game has been
used. power cycled, as expected.

Yes, the measured voltage


This item was tested by at the output of the battery
Is the battery
measuring the battery pack was 4.57 volts, which
output between 3.1.4
output voltage with a is within our tolerance, and
4.5 - 5 volts?
voltmeter. the game runs smoothly
with this voltage.

6. Conclusion
In this document, we have outlined the hardware and software design of a Brick Breaker game,
implemented using a Texas Instruments Tiva-C microcontroller and several other peripheral
devices. We have shown a schematic and a flowchart representing the physical and functional
design, and described how several key functional blocks (such as collision detection) were
implemented. This project met all its original intended requirements and goals and was overall a
great success. Movements look very fluid and gameplay is almost never interrupted. Future
versions of the game could easily be expanded for more levels, multiple balls, and the storing of
a name with the high score. The only question that remains is if someone can beat Mitch’s high
score.

11
Appendix A: Pictures

Figure 1

Figure 2a

12
Figure 2b

Figure 3a

13
Figure 3b

14
Appendix B: Code

main.c:
/*
* Andrew Deakin, A01353937
* Mitch Morse, A01221890
* ECE 3710 Final project
* Due: 12/12/14
*/
#include "LCD.h"
#include "globals.h"
#include "objects.h"
#include "GPIO.h"
#include "SSI.h"
#include "I2C.h"
#include "GPTM.h"
#include "collisionDetection.h"
#include "text.h"
//function definitions
void config(void);
void MSDelay(unsigned int);
void GPIOPortB_Handler(void);
void move(Paddle);
void refresh(Paddle, Ball);
void scoreScreen(void);
void autoPlay(void);
void reInit(void);
void printText(void);
unsigned int *PA = (unsigned int *) 0x40004000;
unsigned int *PB = (unsigned int *) 0x40005000;
unsigned int *PE = (unsigned int *) 0x40024000;
unsigned int *SYSCTL = (unsigned int *) 0x400FE000;
unsigned int *SSI0 = (unsigned int *) 0x40008000;
unsigned int *I2C1 = (unsigned int *) 0x40021000;
unsigned int *CORE_PERIPH = (unsigned int *) 0xE000E000;
unsigned int *GPTM0 = (unsigned int *) 0x40030000;
unsigned int *GPTM1 = (unsigned int *) 0x40031000;
unsigned int *EPROM = (unsigned int *) 0x400AF000;
//global variable instantiations
////////////////////////////////
const int SIN_SIZE = 10;
int SIN[SIN_SIZE] = {311, 457, 547, 547, 457, 311, 165, 75, 75, 165};
int sinIndex=0;
char DAC_ADDR = 0x62;
int sysclk = 40; //MHz
int LCD_WIDTH = 320;
int LCD_HEIGHT = 240;
int BALL_RADIUS = 3;
const int BRICKS_PER_ROW = 11;
const int BRICKS_PER_COLUMN = 6;
int bricksLeft = BRICKS_PER_ROW * BRICKS_PER_COLUMN;
char dead = 0;
int score = 0;
int highScore = 0;
char autoPlayEnable = 0; //bool
const int minSpeed = 24000; //in Micro seconds (normal is 24000)
const int maxSpeed = 6000; //(higher speed number is slower)
int curSpeed = minSpeed;
Brick bricks[BRICKS_PER_COLUMN][BRICKS_PER_ROW];
Paddle paddle;
Ball ball;

15
const int numLevels = 5;
char levels[numLevels][BRICKS_PER_COLUMN][BRICKS_PER_ROW] = {
//level 1
{{0,0,0,0,0,0,0,0,0,0,0},
{1,1,1,1,1,0,1,1,1,1,1},
{0,0,1,1,1,0,1,1,1,0,0},
{0,0,1,1,1,0,1,1,1,0,0},
{0,0,1,1,1,0,1,1,1,0,0},
{1,1,1,1,1,1,1,1,1,1,1}},
//level 2
{{0,0,0,0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0},
{1,1,0,1,1,0,1,1,0,1,1},
{1,1,0,1,1,0,1,1,0,1,1},
{1,1,0,1,1,0,1,1,0,1,1}},
//level 3
{{0,1,0,1,0,1,0,1,0,1,0},
{1,0,1,0,1,0,1,0,1,0,1},
{1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,1,0,1,1,0,0,1},
{1,0,0,1,1,0,1,1,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1}},
//level 4
{{0,0,1,1,1,1,1,1,1,0,0},
{0,1,1,1,1,0,1,1,1,1,0},
{1,1,1,1,0,0,0,1,1,1,1},
{1,1,0,1,1,0,1,1,0,1,1},
{1,0,0,0,1,1,1,0,0,0,1},
{1,1,0,1,1,0,1,1,0,1,1}},
//level 5
{{1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,0,0,0,1,1,1,1},
{1,1,1,1,0,0,0,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1}}};

//global object properties


//////////////////////////////////////
//for Bricks
int SPACE = 3; //space between bricks
int THICKNESS = 1; //thickness of border
unsigned short BORDER_COLOR = 0xFFFF; //white
//for Balls
int RADIOUS = 5;
//for Paddles
int LENGTH = 50;
int main(void)
{
//variables
int brickWidth, brickHeight;
int i,j;
int xPos, yPos, xInc, yInc, brickScore;
unsigned short color = white;
Ball oldBall;
Paddle oldPaddle;
int curLevel = 0;
char first = 1; //bool

config(); //configure GPIO, SSI, I2C, Timers, interrupts, and LCD


EPROM[0x008/4] = 0x0; //set offset
highScore = EPROM[0x010/4]; //load old high score from EPROM

16
EPROM[0x008/4] = 0x4; //set offset for color
color = EPROM[0x010/4]; //load old color

while(1)
{
clearLCD(black);
//make bricks
brickWidth = (int)((LCD_WIDTH-SPACE)/(BRICKS_PER_ROW) - SPACE) +1;
brickHeight = (int)(((LCD_HEIGHT*0.4)-SPACE)/(BRICKS_PER_COLUMN) -
SPACE);
xPos = SPACE + brickWidth/2;
yPos = SPACE + brickHeight/2 + 2*brickHeight;
xInc = brickWidth + SPACE;
yInc = brickHeight + SPACE;
brickScore = BRICKS_PER_COLUMN;
for(i=0; i<BRICKS_PER_COLUMN; i++)
{
for(j=0; j<BRICKS_PER_ROW; j++)
{
color-=1800;
//if(color <= 0x0384 || color >= 0xFC7B) //prevent black or
white
if(color <= 0x450 || color >= 0xFB00) //prevent black or
white
color-=1800;
bricks[i][j].height = brickHeight;
bricks[i][j].width = brickWidth;
bricks[i][j].broken = !levels[curLevel][i][j];
bricksLeft -= !levels[curLevel][i][j];
bricks[i][j].color = color;
bricks[i][j].score = brickScore;
bricks[i][j].thickness = THICKNESS;
bricks[i][j].x = xPos;
bricks[i][j].y = yPos;

bricks[i][j].left = bricks[i][j].x+bricks[i][j].width/2;
bricks[i][j].right = bricks[i][j].x-bricks[i][j].width/2;
bricks[i][j].bottom = bricks[i][j].y+bricks[i][j].height/2;
bricks[i][j].top = bricks[i][j].y-bricks[i][j].height/2;
makeBrick(bricks[i][j]);

xPos += xInc;
}
xPos = SPACE + brickWidth/2;
yPos += yInc;
brickScore--;
}
EPROM[0x008/4] = 0x4; //set offset
EPROM[0x010/4] = color; //write new stored color

//make paddle
paddle.x = LCD_WIDTH/2;
paddle.width = 60;
paddle.height = 6;
paddle.xSpeed = 2;
paddle.top = LCD_HEIGHT - paddle.height;
paddle.divisionSize = paddle.width/6;
makePaddle(paddle);

//make Ball
ball.x = paddle.x;
ball.y = LCD_HEIGHT-paddle.height-BALL_RADIUS-2;
ball.xSpeed = 1;

17
ball.ySpeed = 2;
ball.radius = BALL_RADIUS;
makeBall(ball, ball);
ball.left = ball.x+ball.radius;
ball.right = ball.x-ball.radius;
ball.bottom = ball.y+ball.radius;
ball.top = ball.y-ball.radius;

if(first)
{
scoreScreen();
first = 0;
}

while(1)
{
detectCollision();
oldPaddle = paddle;
oldBall = ball;
move(oldPaddle);
while((CORE_PERIPH[0x010/4] & 0x10000) != 0x10000); //wait for
systick
refresh(oldPaddle, oldBall);
if((PE[0x3FC/4] & 0x10) != 0x10) //start/pause button
{
scoreScreen();
}

if(dead) //death
{
scoreScreen();
dead = 0;
curLevel = 0;
if((score > highScore) && !autoPlayEnable)
{
EPROM[0x008/4] = 0x0; //set offset
EPROM[0x010/4] = score; //write new high score
highScore = score;
}
score = 0;
bricksLeft = BRICKS_PER_ROW * BRICKS_PER_COLUMN;
curSpeed = minSpeed; //reset to slow speed
CORE_PERIPH[0x014/4] = getInitial(curSpeed, sysclk); //set
systick reload
break;
}

else if(bricksLeft <= 0) //done with level


{
curLevel++;
if(curSpeed > maxSpeed+2000)
{
curSpeed -= 2000;//increase speed
CORE_PERIPH[0x014/4] = getInitial(curSpeed, sysclk);
//set systick reload
}
else
{
curSpeed = maxSpeed;
}
bricksLeft = BRICKS_PER_ROW * BRICKS_PER_COLUMN;
if(curLevel >= numLevels)
{

18
curLevel = 0;
}
break;
}
}
}
}
/////////////////////////////
// Sub Routines
/////////////////////////////
void config(void)
{
int DacAddrWithTx;

SYSCTL[0x60/4] = 0x2400540; //use main osc, set xtal to 16 MHz, use PLL,

//and a divisor to get 40 MHz,

//all others are default

//activate clock for PA, PB, PE, SSIO, I2C, and timers
SYSCTL[0x104/4] = 0x34010; //SSI0, I2C1, Timer0A, Timer1A
SYSCTL[0x108/4] = 0x13; //ports A, B, and E

//configure GPIO A
configGPIO(PA, 0xFC, 0x2C, 0x80, 0x0, 0x7F, 0xFC);
PA[0x52C/4] = 0x33222200; //set PA for SSI0 and I2C

//configure GPIO B
configGPIO(PB, 0x0, 0x33, 0x0, 0x0, 0xFF, 0x3F);
//PB[0x3FC/4] = 0x2; //set rst bit to turn LCD on

//configure GPIO E
configGPIO(PE, 0x0, 0x0, 0x0, 0x1F, 0x0, 0x1F);

//configure EPROM
SYSCTL[0x658/4] = 0x1;

//configure I2C
i2cConfig(I2C1, sysclk);
DacAddrWithTx = DAC_ADDR << 1;
I2C1[0x000/4] = DacAddrWithTx; //set I2C slave address for transmit

configFreescale(SSI0); // setup_SSIO_0();

//configure Timer 0A
timerConfig(GPTM0, 2000, sysclk);
GPTM0[0x018/4] = 0x1; //enable interrupt
GPTM0[0x00C/4] = 0x0; //disable timer

//configure Timer 1A
timerConfig(GPTM1, 250, sysclk);
GPTM1[0x018/4] = 0x1; //enable interrupt
GPTM1[0x00C/4] = 0x0; //disable timer

//configure Systick
CORE_PERIPH[0x014/4] = getInitial(curSpeed, sysclk); //set reload
CORE_PERIPH[0x010/4] = 0x5; //enable
LCD_Init(); //configure LCD

//configure interrupts at NVIC


CORE_PERIPH[0x100/4] = 0x280000; //enable Timer0 and Timer1 interrupts at NVIC

19
}
void move(Paddle oldPaddle)
{
//move ball
ball.x -= ball.xSpeed;
ball.y -= ball.ySpeed;

if(ball.x-ball.radius < 0)
ball.x = ball.radius;
if(ball.y-ball.radius < 0)
ball.y = ball.radius;

//update ball bounds


ball.left = ball.x+ball.radius;
ball.right = ball.x-ball.radius;
ball.bottom = ball.y+ball.radius;
ball.top = ball.y-ball.radius;

if(autoPlayEnable)
{
autoPlay();
}

//move paddle: PE0 -> right button, PE1-> left button


if(((PE[0x3FC/4] & 0x1) != 0x1) && paddle.x-(paddle.width/2) > paddle.xSpeed)
//left
{
paddle.x -= paddle.xSpeed;
}

if(((PE[0x3FC/4] & 0x2) != 0x2)&& paddle.x+(paddle.width/2) < LCD_WIDTH-


paddle.xSpeed) //right
{
paddle.x += paddle.xSpeed;
}

if(((PE[0x3FC/4] & 0x4) != 0x4)) //jump left


{
paddle.x = LCD_WIDTH - paddle.width/2;
makeBox(240-oldPaddle.height/2, oldPaddle.x, oldPaddle.height,
oldPaddle.width, black); //clear old paddle
makeBox(240-paddle.height/2, paddle.x, paddle.height, paddle.width,
white); //write new paddle
}

else if(((PE[0x3FC/4] & 0x8) != 0x8)) //jump right


{
paddle.x = paddle.width/2;
makeBox(240-oldPaddle.height/2, oldPaddle.x, oldPaddle.height,
oldPaddle.width, black); //clear old paddle
makeBox(240-paddle.height/2, paddle.x, paddle.height, paddle.width,
white); //write new paddle
}
}
void refresh(Paddle oldPaddle, Ball oldBall)
{
makeBall(ball, oldBall);
if(paddle.x != oldPaddle.x)
{
makePaddle(paddle);
}
//bricks are refresh only when hit to save time
}

20
void scoreScreen(void)
{
//turn light orange
PB[0x3FC/4] &= 0xDF; //green off
PB[0x3FC/4] |= 0x10; //orange on

while((PE[0x3FC/4] & 0x10) != 0x10) //wait for release


{
MSDelay(2);
}
MSDelay(1);

printText();

while((PE[0x3FC/4] & 0x10) == 0x10) //wait for unpause


{
if((PE[0x3FC/4] & 0xF) == 0x0)
{
reInit();
}
}
while((PE[0x3FC/4] & 0x10) != 0x10) //wait for release
{
MSDelay(2);
}
MSDelay(20);

makeBox(172, LCD_WIDTH/2, 4*LETTER_WIDTH+8,LCD_WIDTH-4, black);//clear score


data

//turn light green


PB[0x3FC/4] &= 0xEF; //orange off
PB[0x3FC/4] |= 0x20; //green on

}
void printText(void)
{
int xPos,yPos,i;
int digits[4];
int number;
char startPrint=0; //bool
//display score data
makeBox(172, LCD_WIDTH/2, 4*LETTER_WIDTH+8,LCD_WIDTH-4, white);//clear score
area with border
makeBox(172, LCD_WIDTH/2, 4*LETTER_WIDTH+6,LCD_WIDTH-6, black);
xPos = 300;
yPos = 153;

//"Your "
writeChar(yPos, xPos, Y);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, O);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, U);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, R);
xPos -= 2*(LETTER_HEIGHT+1)+2; //space

//"Score: "
writeChar(yPos, xPos, S);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, C);
xPos -= LETTER_HEIGHT+1;

21
writeChar(yPos, xPos, O);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, R);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, E);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, colon);
xPos -= (LETTER_HEIGHT+1); //space

//score number
digits[0] = (score%10000)/1000;
digits[1] = (score%1000)/100;
digits[2] = (score%100)/10;
digits[3] = (score%10);

for(i=0; i<4; i++)


{
number = digits[i];
if (number != 0 || i == 3 || startPrint)
{
writeChar(yPos, xPos, numbers[number]);
xPos -= LETTER_HEIGHT+1;
startPrint = 1;
}
}

yPos += LETTER_WIDTH+15;
xPos = 300;

//"High "
writeChar(yPos, xPos, H);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, I);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, G);
xPos -= LETTER_HEIGHT+3;
writeChar(yPos, xPos, H);
xPos -= 2*(LETTER_HEIGHT+1); //space

//"Score: "
writeChar(yPos, xPos, S);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, C);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, O);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, R);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, E);
xPos -= LETTER_HEIGHT+1;
writeChar(yPos, xPos, colon);
xPos -= (LETTER_HEIGHT+1); //space

//high score number


digits[0] = (highScore%10000)/1000;
digits[1] = (highScore%1000)/100;
digits[2] = (highScore%100)/10;
digits[3] = (highScore%10);

startPrint = 0;
for(i=0; i<4; i++)
{
number = digits[i];

22
if (number != 0 || i == 3 || startPrint)
{
writeChar(yPos, xPos, numbers[number]);
xPos -= LETTER_HEIGHT+1;
startPrint = 1;
}
}
}
void reInit(void)
{
int i,j;
LCD_Init();
clearLCD(black);
for(i=0; i<BRICKS_PER_COLUMN; i++)
{
for(j=0; j<BRICKS_PER_ROW; j++)
{
makeBrick(bricks[i][j]);
}
}
makePaddle(paddle);
makeBall(ball,ball);
printText();
}
void autoPlay(void)
{
if((ball.x > paddle.width/2+1) && (ball.x < LCD_WIDTH-paddle.width/2-1))
{
if(ball.xSpeed > 0)
{
paddle.x = ball.x+2;
}
else if(ball.xSpeed < 0)
{
paddle.x = ball.x-2;
}
}
}
////////////////////////////////
// Interrupt service routines //
////////////////////////////////
void Timer0A_Handler(void)
{
int data;
GPTM0[0x024/4] = 0x1; //ack

data = SIN[sinIndex];
while((I2C1[0x004/4] & 0x1) == 0x1); //wait for busy bit to clear
I2C1[0x008/4] = (unsigned char)((data >> 8) & 0xFF); //send first byte
I2C1[0x004/4] = 0x3; //set master to burst mode

while((I2C1[0x004/4] & 0x1) == 0x1); //wait for busy bit to clear


I2C1[0x008/4] = (unsigned char)(data & 0xFF); //send second byte
I2C1[0x004/4] = 0x5; //set master to single mode

sinIndex++;
if(sinIndex>=SIN_SIZE)
{
sinIndex = 0;
}
}
void Timer1A_Handler(void)
{

23
GPTM1[0x024/4] = 0x1; //ack
GPTM0[0x00C/4] = 0x0; //disable Timer 0
GPTM1[0x00C/4] = 0x0; //disable Timer 1
}
collisionDetection.h:
#ifndef COLLISIONDETECTION_H
#define COLLISIONDETECTION_H
#include "objects.h"
void detectCollision(void);
void checkBottoms(void);
void checkTops(void);
void checkLeftSides(void);
void checkRightSides(void);
void breakBrick(int i, int j);
void beep(int freq, int durMs);
#endif
collisionDetection.c:
#include "collisionDetection.h"
#include "globals.h"
#include "LCD.h"
void detectCollision(void)
{
//check walls
if(ball.right < ball.xSpeed && ball.xSpeed > 0) //right side
{
ball.xSpeed = -ball.xSpeed;
beep(450, 35);
}

if(ball.left > LCD_WIDTH+ball.xSpeed && ball.xSpeed < 0) //left side


{
ball.xSpeed = -ball.xSpeed;
beep(450, 35);
}

if(ball.top < ball.ySpeed && ball.ySpeed > 0) //top


{
ball.ySpeed = -ball.ySpeed;
beep(450, 35);
}

if(ball.bottom > LCD_HEIGHT+ball.ySpeed && ball.ySpeed < 0) //bottom


{
beep(600, 150);
MSDelay(300);
beep(500, 150);
MSDelay(300);
beep(400, 150);
MSDelay(300);
beep(300, 600);
MSDelay(1000);
dead = 1;
return;
}

//check paddle
if(ball.bottom+2 >= paddle.top) //ball at bottom
{
//zone 1
if((ball.x <= paddle.x + 3*paddle.divisionSize+ball.radius) && (ball.x >
paddle.x + 2*paddle.divisionSize))
{

24
ball.xSpeed=-2;
ball.ySpeed=1;
beep(350, 35);
}
//zone 2
else if((ball.x <= paddle.x + 2*paddle.divisionSize) && (ball.x >
paddle.x + paddle.divisionSize))
{
ball.xSpeed=-2;
ball.ySpeed=2;
beep(350, 35);
}
//zone 3
else if((ball.x <= paddle.x + paddle.divisionSize) && (ball.x >
paddle.x))
{
ball.xSpeed=-1;
ball.ySpeed=2;
beep(350, 35);
}
//zone 4
else if((ball.x <= paddle.x) && (ball.x > paddle.x -
paddle.divisionSize))
{
ball.xSpeed=1;
ball.ySpeed=2;
beep(350, 35);
}
//zone 5
else if((ball.x <= paddle.x - paddle.divisionSize) && (ball.x > paddle.x
- 2*paddle.divisionSize))
{
ball.xSpeed=2;
ball.ySpeed=2;
beep(350, 35);
}
//zone 6
else if((ball.x <= paddle.x - 2*paddle.divisionSize) && (ball.x >
paddle.x - 3*paddle.divisionSize-ball.radius))
{
ball.xSpeed=2;
ball.ySpeed=1;
beep(350, 35);
}
makePaddle(paddle);
}

else if(ball.y < LCD_HEIGHT*0.6) //ball near bricks


{
//check bricks
if(ball.ySpeed > 0) //moving up
{
checkBottoms();
}

else if(ball.ySpeed < 0) //moving down


{
checkTops();
}

if(ball.xSpeed > 0) //moving right


{

25
checkLeftSides();
}

else if(ball.xSpeed < 0) //moving left


{
checkRightSides();
}
}
}
void checkBottoms(void)
{
int i, j;
Brick brick;
for(i=0; i<BRICKS_PER_COLUMN ; i++)
{
for(j=0; j<BRICKS_PER_ROW; j++)
{
brick = bricks[i][j];
//if in X range and past bottom and not broken
if(!brick.broken && (ball.right+1 <= brick.left) && (ball.left-1
>= brick.right) && (ball.top >= brick.top) && (ball.top-2 <= brick.bottom))
{
ball.ySpeed = -ball.ySpeed;
breakBrick(i,j);
return;
}
}
}
}
void checkTops(void)
{
int i, j;
Brick brick;
for(i=0; i<BRICKS_PER_COLUMN ; i++)
{
for(j=0; j<BRICKS_PER_ROW; j++)
{
brick = bricks[i][j];
//if in X range and past top and not broken
if(!brick.broken && (ball.right+1 <= brick.left) && (ball.left-1
>= brick.right) && (ball.bottom <= brick.bottom) && (ball.bottom+2 >= brick.top))
{
ball.ySpeed = -ball.ySpeed;
breakBrick(i,j);
return;
}
}
}
}
void checkLeftSides(void)
{
int i, j;
Brick brick;
for(i=0; i<BRICKS_PER_COLUMN ; i++)
{
for(j=0; j<BRICKS_PER_ROW; j++)
{
brick = bricks[i][j];
//if in Y range and past left and not broken
if(!brick.broken && (ball.bottom-1 >= brick.top) && (ball.top+1 <=
brick.bottom) && (ball.right >= brick.right) && (ball.right-2 <= brick.left))
{
ball.xSpeed = -ball.xSpeed;

26
breakBrick(i,j);
return;
}
}
}
}
void checkRightSides(void)
{
int i, j;
Brick brick;
for(i=0; i<BRICKS_PER_COLUMN ; i++)
{
for(j=0; j<BRICKS_PER_ROW; j++)
{
brick = bricks[i][j];
//if in Y range and past left and not broken
if(!brick.broken && (ball.bottom-1 >= brick.top) && (ball.top+1<=
brick.bottom) && (ball.left <= brick.left) && (ball.left+2 >= brick.right))
{
ball.xSpeed = -ball.xSpeed;
breakBrick(i,j);
return;
}
}
}
}
void breakBrick(int i, int j)
{
bricks[i][j].broken = 1;
beep(300, 35);

makeBox(bricks[i][j].y,bricks[i][j].x,bricks[i][j].height,bricks[i][j].width,bl
ack);
bricksLeft--;
score += bricks[i][j].score;
}
void beep(int freq, int durMS)
{
int initial0, initial1, TimerUS, durUS;
durUS = durMS * 1000;
TimerUS = (1./(freq*SIN_SIZE)) * 1000000.;

initial0 = sysclk * TimerUS;


initial1 = sysclk * durUS;

GPTM0[0x00C/4] = 0x0; //stop timer


GPTM0[0x028/4] = initial0; //set initial value
GPTM0[0x00C/4] = 0x1; //enable timer
GPTM1[0x00C/4] = 0x0; //stop timer
GPTM1[0x028/4] = initial1; //set initial value
GPTM1[0x00C/4] = 0x1; //enable timer

GPTM0[0x00C/4] = 0x1; //enable Timer 0


GPTM1[0x00C/4] = 0x1; //enable Timer 1
}
globals.h:
#ifndef GLOBALS_H
#define GLOBALS_H
#include "objects.h"
//Base Addresses
extern unsigned int *PA;
extern unsigned int *PB;
extern unsigned int *PE;

27
extern unsigned int *SYSCTL;
extern unsigned int *SSI0;
extern unsigned int *I2C1;
extern unsigned int *CORE_PERIPH;
extern unsigned int *GPTM0;
extern unsigned int *GPTM1;
//global variables
extern const int SIN_SIZE; //10
extern int SIN[10];
extern int sinIndex;
extern char DAC_ADDR;
extern int sysclk;
extern int LCD_WIDTH;
extern int LCD_HEIGHT;
extern int BALL_RADIUS;
extern int bricksLeft;
extern char dead; //bool
extern int score;
extern int highScore;
extern char autoPlayEnable; //bool
extern const int maxSpeed;
extern const int minSpeed;
extern int curSpeed;
extern int test;
//global constants
extern const int BRICKS_PER_ROW; //11
extern const int BRICKS_PER_COLUMN;
extern Brick bricks[6][11]; //6
extern Paddle paddle;
extern Ball ball;
#endif
GPIO.h:
#ifndef GPIO_H
#define GPIO_H
void configGPIO(unsigned int * BASE, int alt, int io, int drain, int pullUp, int
pullDown, int enable);
void configInterupt(unsigned int * BASE, int gpiois, int gpioibe, int gpioiev, int
gpioim);
#endif
GPIO.c:
#include "GPIO.h"
int test = 5;
void configGPIO(unsigned int * BASE, int alt, int io, int drain, int pullUp, int
pullDown, int enable)
{
//unlock, set commit, and unlock again
BASE[0x520/4] = 0x4C4F434B; //unlock ports
BASE[0x524/4] = 0xFF; //set commit
register (CR) to 0xFF (GPIOF is 0xFE by default, so PF0 is unusable)
BASE[0x520/4] = 0x4C4F434B; //unlock ports
again (setting CR sometimes relocks ports, but they must be unlocked to set CR)

//Set parameters for this GPIO


BASE[0x420/4] = alt; //offset for alternate function
reg
BASE[0x400/4] = io; //offset for I/O ports ( 0
for input, 1 for output )
BASE[0x50C/4] = drain; //set open drain pins
BASE[0x510/4] = pullUp; //set pull-up pins
BASE[0x514/4] = pullDown; //set pull-down pins
BASE[0x51C/4] = enable; //enable pins
}

28
void configInterupt(unsigned int * BASE, int gpiois, int gpioibe, int gpioiev, int
gpioim)
{
BASE[0x404/4] = gpiois; //GPIOIS
BASE[0x408/4] = gpioibe; //GPIOIBE
BASE[0x40C/4] = gpioiev; //GPIOIEV
BASE[0x410/4] = gpioim; //GPIOIM
}
GPTM.h:
#ifndef GPTM_H
#define GPTM_H
void timerConfig(unsigned int * BASE, int US, int sysclk);
int getInitial(int US, int sysclk);
#endif
GPTM.c:
#include "GPTM.h"
void timerConfig(unsigned int * BASE, int US, int sysclk)
{
int initial = getInitial(US, sysclk);
BASE[0x00C/4] = 0x0; //stop timer
BASE[0x000/4] = 0x0; //select 32 -bit mode
BASE[0x004/4] = 0x2; //select periodic
BASE[0x028/4] = initial; //set initial value
//BASE[0x00C/4] = 0x1; //enable timer
}
int getInitial(int US, int sysclk)
{
return sysclk * US;
}
I2C.h:
#ifndef I2C_H
#define I2C_H
void i2cConfig(unsigned int * BASE, int sysclk);
#endif
I2C.c:
#include "I2C.h"
void i2cConfig(unsigned int * BASE, int sysclk)
{
int TPR = ((sysclk*1000000. / (2.*(6.+4.)*400000.))-1.);
BASE[0x020/4] = 0x10; //set to master
BASE[0x00C/4] = TPR; //set to fast mode (400 KHz)
}
void Tx(unsigned int * BASE, int data){
while((BASE[0x004/4] & 0x1) == 0x1); //wait for busy bit to clear
BASE[0x008/4] = (unsigned char)((data >> 8) & 0xFF); //send first byte
BASE[0x004/4] = 0x3; //set master to burst mode

while((BASE[0x004/4] & 0x1) == 0x1); //wait for busy bit to clear


BASE[0x008/4] = (unsigned char)(data & 0xFF); //send second byte
BASE[0x004/4] = 0x5; //set master to single mode
}
LCD.h:
#ifndef LCD_H
#define LCD_H
#include "globals.h"
#include "objects.h"
// page 238 of the data sheet.
#define white 0xFFFF
#define black 0x0001
#define grey 0xF7DE
#define blue 0x001F

29
#define red 0xF800
#define magenta 0xF81F
#define green 0x07E0
#define cyan 0x7FFF
#define yellow 0xFFE0
void writeCmd(unsigned char CMD);
void writeDat(unsigned char DAT);
void writeDat2(unsigned short DAT);
void writeDat4(unsigned int DAT);
unsigned int setArea(unsigned short x1, unsigned short x2, unsigned short y1, unsigned
short y2);
void writeColor(unsigned short color, unsigned int size);
//void flash_screen(unsigned short color);
void LCD_Init(void);
//void writeRGB(unsigned char R, unsigned char G, unsigned char B);
void LCD_SetColumns(unsigned short x1, unsigned int x2);
void LCD_SetPages(unsigned short y1, unsigned int y2);
//////////////////////////
// helper functions
//////////////////////////
void clearLCD(unsigned short rgb); //set entire LCD to the color rgb (useful for
debugging above)
void MSDelay(unsigned int itime); //generate ms milliseconds of delay (timer or loop,
your choice)
////////////////////////////
// functions to draw boxes
////////////////////////////
void makeBox(unsigned short x,unsigned short y, unsigned short w, unsigned short h,
unsigned short rgb); //create a solid box @x,y of color given by rgb
void makeInnerBox(unsigned short x,unsigned short y, unsigned short w, unsigned short
h, unsigned short color); //create a solid box @x,y of color given by rgb
void makeBrick(Brick brick);
void makePaddle(Paddle paddle);
void makeBall(Ball ball, Ball oldBall);
#endif
LCD.c:
#include "LCD.h"
void LCD_Init()
{
int i;
writeCmd(0xCB);
writeDat(0x39);
writeDat(0x2C);
writeDat(0x00);
writeDat(0x34);
writeDat(0x02);
writeCmd(0xCF);
writeDat(0x00);
writeDat(0XC1);
writeDat(0X30);
writeCmd(0xE8);
writeDat(0x85);
writeDat(0x00);
writeDat(0x78);
writeCmd(0xEA);
writeDat(0x00);
writeDat(0x00);
writeCmd(0xED);
writeDat(0x64);
writeDat(0x03);
writeDat(0X12);
writeDat(0X81);
writeCmd(0xF7);

30
writeDat(0x20);
writeCmd(0xC0); //Power control
writeDat(0x23); //VRH[5:0]
writeCmd(0xC1); //Power control
writeDat(0x10); //SAP[2:0];BT[3:0]
writeCmd(0xC5); //VCM control
writeDat(0x3e);
writeDat(0x28);
writeCmd(0xC7); //VCM control2
writeDat(0x86); //--
writeCmd(0x36); // Memory Access Control
writeDat(0x48); //C8 //48
writeCmd(0x3A);
writeDat(0x55);
writeCmd(0xB1);
writeDat(0x00);
writeDat(0x18);
writeCmd(0xB6); // Display Function Control
writeDat(0x08);
writeDat(0x82);
writeDat(0x27);
writeCmd(0xF2); // 3Gamma Function Disable
writeDat(0x00);
writeCmd(0x26); //Gamma curve selected
writeDat(0x01);
writeCmd(0xE0); //Set Gamma
writeDat(0x0F);
writeDat(0x31);
writeDat(0x2B);
writeDat(0x0C);
writeDat(0x0E);
writeDat(0x08);
writeDat(0x4E);
writeDat(0xF1);
writeDat(0x37);
writeDat(0x07);
writeDat(0x10);
writeDat(0x03);
writeDat(0x0E);
writeDat(0x09);
writeDat(0x00);
writeCmd(0XE1); //Set Gamma
writeDat(0x00);
writeDat(0x0E);
writeDat(0x14);
writeDat(0x03);
writeDat(0x11);
writeDat(0x07);
writeDat(0x31);
writeDat(0xC1);
writeDat(0x48);
writeDat(0x08);
writeDat(0x0F);
writeDat(0x0C);
writeDat(0x31);
writeDat(0x36);
writeDat(0x0F);
writeCmd(0x11); //Exit Sleep
for( i = 0; i < 20000; i++) { i++;}
writeCmd(0x29); //Display on
//writeCmd(0x2c);
}
void writeCmd(unsigned char CMD)

31
{
SSI0[0x008/4] = CMD;
PB[0x3FC/4] &= 0xFE;//change PB0 to 0
while((SSI0[0x00C/4] & 1) == 0); //wait for TX
}
void writeDat(unsigned char DAT)
{
SSI0[0x008/4] = DAT;
PB[0x3FC/4] |= 0x1;//change PB0 to 1
while((SSI0[0x00C/4] & 1) == 0); //wait for TX
}
void writeDat2(unsigned short DAT)
{
SSI0[0x008/4] = (DAT >> 8) & 0xFF;
PB[0x3FC/4] |= 0x1;//change PB0 to 1
SSI0[0x008/4] = DAT & 0xFF;

while((SSI0[0x00C/4] & 1) == 0); //wait for TX


}
void writeDat4(unsigned int DAT)
{
SSI0[0x008/4] = (DAT >> 24) & 0xFF;
PB[0x3FC/4] |= 0x1;//change PB0 to 1
SSI0[0x008/4] = (DAT >> 16) & 0xFF;
SSI0[0x008/4] = (DAT >> 8) & 0xFF;
SSI0[0x008/4] = DAT & 0xFF;

while((SSI0[0x00C/4] & 1) == 0); //wait for TX


}
unsigned int setArea(unsigned short x1, unsigned short x2, unsigned short y1, unsigned
short y2)
{
LCD_SetColumns(x1,x2);
LCD_SetPages(y1,y2);
return (x2-x1+1) * (y2-y1+1);
}
void writeColor(unsigned short color, unsigned int size)
{
unsigned int i;
writeCmd(0x2C);
for(i=0; i < size; i++)
writeDat2(color);
}
void LCD_SetColumns(unsigned short x1, unsigned int x2)
{
writeCmd(0x2A);
writeDat2(x1);
writeDat2(x2);
}
void LCD_SetPages(unsigned short y1, unsigned int y2)
{
writeCmd(0x2B);
writeDat2(y1);
writeDat2(y2);
}
//////////////////////////
// helper functions
//////////////////////////
void clearLCD(unsigned short color) //set entire LCD to the color rgb (useful for
debugging above)
{
unsigned size;
size = setArea(0, 240, 0, 320);

32
writeColor(color, size);
}
void MSDelay(unsigned int itime)
{
int delay;
int i;
delay = (itime/1000.)/(5.*(1./(sysclk*1000000.)));
for(i = 0; i < delay; i++);
}
////////////////////////////
// functions to draw boxes
////////////////////////////
void makeBox(unsigned short x,unsigned short y, unsigned short w, unsigned short h,
unsigned short color) //create a solid box @x,y of color given by rgb
{
//x and y are the center point
//w and h and width and height of box
unsigned int size;
size = setArea(x-(w/2),x+(w/2),y-(h/2),y+(h/2));
writeColor(color, size);
}
void makeInnerBox(unsigned short x,unsigned short y, unsigned short w, unsigned short
h, unsigned short color) //create a solid box @x,y of color given by rgb
{
//x and y are the center point
//w and h and width and height of box
unsigned int size;
size = setArea(x-(w/2)-1,x+(w/2),y-(h/2)-1,y+(h/2));
writeColor(color, size);
}
void makeBrick(Brick brick) //draw a brick
{
//brick.x and brick.y are the center point
//brick.width and brick.height and width and height of box
//brick.thickness is the thckenss of the border
//brick.color is the fill color
//brick.border_color is the border color
if(!brick.broken)
{
makeBox(brick.y,brick.x,brick.height,brick.width,white);
makeInnerBox(brick.y,brick.x,brick.height-brick.thickness,brick.width-
brick.thickness,brick.color);
}
}
void makePaddle(Paddle paddle)
{
makeBox(240-paddle.height/2, paddle.x+paddle.width/2+paddle.xSpeed/2,
paddle.height, paddle.xSpeed, black); //write new paddle
if(paddle.x-paddle.width/2 > 1)
makeBox(240-paddle.height/2, paddle.x-paddle.width/2-paddle.xSpeed/2,
paddle.height, paddle.xSpeed, black); //write new paddle
makeBox(240-paddle.height/2, paddle.x, paddle.height, paddle.width, white);
//write new paddle
}
void makeBall(Ball ball, Ball oldBall)
{
makeBox(oldBall.y, oldBall.x, oldBall.radius*2, oldBall.radius*2, black);
//clear old ball
makeBox(oldBall.y, oldBall.x, oldBall.radius*2, oldBall.radius*2, black);
//clear again to prevent leaving pieces
makeBox(ball.y, ball.x, ball.radius*2, ball.radius*2, white); //write new ball
}
objects.h:

33
#ifndef OBJECTS_H
#define OBJECTS_H
typedef struct
{
short int x, y;
char width, height, thickness;
unsigned short color;
char broken; //boolean
char score;
short int left, right, bottom, top; //bounds
}Brick;
typedef struct
{
int x,y;
int xSpeed, ySpeed;
int radius;
int left, right, bottom, top; //bounds
}Ball;
typedef struct
{
int x;
int xSpeed;
int width, height;
int top, divisionSize;

}Paddle;
#endif
SSI.h:
#ifndef SSI_H
#define SSI_H
void configFreescale(unsigned int * BASE);
#endif
SSI.c:
#include "SSI.h"
void configFreescale(unsigned int * BASE){
BASE[0x4/4] = 0; //disable ssi during config and set role to master

//set prescale and clock rate (SysClk = 16 MHz)


//4 MHz = 16 MHz/4 => PRE*(1+CR) = 4 => PRE = 2, CR = 1
BASE[0x10/4] = 0x2; //PRE
BASE[0x1/4] = 0x1; //CR
//frame format/protocol: 16-bit data, FreeScale, SPH=SPO=0
BASE[0x0/4] = 0x107;
//set Bit Rate to same as Clock speed
//SPO = 0
//SPH = 0
//0x7 for 8 bit

BASE[0x4/4] |= 0x2; //enable ssi


}
text.h:
#ifndef TEST_H
#define TEST_H
extern const int LETTER_WIDTH; //21
extern const int LETTER_HEIGHT; //15
void writeChar(unsigned short x,unsigned short y, char array[15][21]);
extern char numbers[10][15][21];
extern char H[15][21];
extern char I[15][21];
extern char G[15][21];
// H
extern char Y[15][21];

34
extern char O[15][21];
extern char U[15][21];
extern char R[15][21];
extern char S[15][21];
extern char C[15][21];
// O
// R
extern char E[15][21];
extern char colon[15][21];
#endif
text.c:
#include "text.h"
#include "LCD.h"
const int LETTER_WIDTH = 21;
const int LETTER_HEIGHT = 15;
void writeChar(unsigned short x,unsigned short y, char
array[LETTER_HEIGHT][LETTER_WIDTH])
{
int i, j;
setArea(x-(LETTER_WIDTH/2),x+(LETTER_WIDTH/2),y-
(LETTER_HEIGHT/2),y+(LETTER_HEIGHT/2));
writeCmd(0x2C);
for(i=0; i < LETTER_HEIGHT; i++)
{
for(j=0; j < LETTER_WIDTH; j++)
{
if(array[i][j] == 1)
{
writeDat2(white);
}
else
{
writeDat2(black);
}
}
}
}
char numbers[10][LETTER_HEIGHT][LETTER_WIDTH] = {
//zero
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0}},

//one
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},

35
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},

//two
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1},
{0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
{0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
{0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},

//three
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0},
{0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0},
{0,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0},
{0,0,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,1,1,1,0},
{0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1},
{0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},

//four
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
{0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
{0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0}},

//five
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0},

36
{0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0},
{0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0},
{0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},

//six
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0},
{0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0},
{0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1},
{0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1},
{0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1},
{0,0,0,1,1,1,1,0,0,0,1,1,0,0,0,0,0,1,1,1,0},
{0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},

//seven
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},

//eight
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0},
{0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0},
{0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0},
{0,0,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,1,1,0},
{0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1},
{0,0,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,1,1,1},
{0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0},

37
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0}},

//nine
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,1,1,1,0},
{0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0},
{0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1},
{0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1},
{0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1},
{0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
};
char H[15][21] = {
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};

char I[15][21] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

char G[15][21] = {
{0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0},
{0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0},
{0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},

38
{0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
{0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0},
{0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0}};

char Y[15][21] = {
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

char O[15][21] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0}};

char U[15][21] = {
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}};

char R[15][21] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1},
{0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0},

39
{0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,0},
{0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

char S[15][21] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0},
{0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0},
{0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0},
{0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0},
{0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1},
{0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1},
{0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0},
{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

char C[15][21] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0},
{0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
{0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0},
{0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0}};

char E[15][21] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

40
char colon[15][21] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1},
{0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1},
{0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

41

Potrebbero piacerti anche