mirror of
https://github.com/isometimes/rpi4-osdev
synced 2024-11-08 19:30:39 +00:00
Tidy up of the breakout code
This commit is contained in:
parent
ffe23d671c
commit
b79e1dd054
5 changed files with 323 additions and 331 deletions
|
@ -1,252 +0,0 @@
|
|||
#include "fb.h"
|
||||
#include "io.h"
|
||||
|
||||
// The screen
|
||||
#define WIDTH 1920
|
||||
#define HEIGHT 1080
|
||||
#define MARGIN 75
|
||||
#define VIRTWIDTH (WIDTH-(2*MARGIN))
|
||||
#define FONT_BPG 8
|
||||
|
||||
// For the bricks
|
||||
#define ROWS 5
|
||||
#define COLS 10
|
||||
unsigned int bricks = ROWS * COLS;
|
||||
|
||||
// Gameplay
|
||||
#define NUM_LIVES 3
|
||||
|
||||
// OBJECT TRACKING
|
||||
|
||||
struct Object
|
||||
{
|
||||
unsigned int type;
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned char alive;
|
||||
};
|
||||
|
||||
enum {
|
||||
OBJ_NONE = 0,
|
||||
OBJ_BRICK = 1,
|
||||
OBJ_PADDLE = 2,
|
||||
OBJ_BALL = 3
|
||||
};
|
||||
|
||||
unsigned int numobjs = 0;
|
||||
struct Object objects[(ROWS * COLS) + (2 * NUM_LIVES)];
|
||||
struct Object *ball;
|
||||
struct Object *paddle;
|
||||
|
||||
void removeObject(struct Object *object)
|
||||
{
|
||||
drawRect(object->x, object->y, object->x + object->width, object->y + object->height, 0, 1);
|
||||
object->alive = 0;
|
||||
}
|
||||
|
||||
void moveObject(struct Object *object, int xoff, int yoff)
|
||||
{
|
||||
moveRect(object->x, object->y, object->width, object->height, xoff, yoff, 0x00);
|
||||
object->x = object->x + xoff;
|
||||
object->y = object->y + yoff;
|
||||
}
|
||||
|
||||
struct Object *objectAt(unsigned int x, unsigned int y)
|
||||
{
|
||||
for (int i=0; i<numobjs;i++) {
|
||||
if (x >= objects[i].x && x <= objects[i].x + objects[i].width) {
|
||||
if (y >= objects[i].y && y <= objects[i].y + objects[i].height) {
|
||||
if (&objects[i] != ball && objects[i].alive == 1) {
|
||||
return &objects[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Object *detectCollision(int xoff, int yoff)
|
||||
{
|
||||
struct Object *collision;
|
||||
|
||||
unsigned int x = ball->x + xoff;
|
||||
unsigned int y = ball->y + yoff;
|
||||
|
||||
collision = objectAt(x,y);
|
||||
if (collision) return collision;
|
||||
|
||||
collision = objectAt(x + ball->width, y);
|
||||
if (collision) return collision;
|
||||
|
||||
collision = objectAt(x, y + ball->height);
|
||||
if (collision) return collision;
|
||||
|
||||
collision = objectAt(x + ball->width, y + ball->height);
|
||||
if (collision) return collision;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// KEY HANDLER
|
||||
|
||||
unsigned char getUart()
|
||||
{
|
||||
unsigned char ch = 0;
|
||||
|
||||
if (uart_isReadByteReady()) ch = uart_readByte();
|
||||
return ch;
|
||||
}
|
||||
|
||||
// OBJECT INITIALISERS
|
||||
|
||||
void initBricks()
|
||||
{
|
||||
int brickwidth = 32;
|
||||
int brickheight = 8;
|
||||
int brickspacer = 20;
|
||||
int brickcols[5] = { 0x01, 0x02, 0x0E, 0x04, 0x06 };
|
||||
|
||||
int ybrick = MARGIN + brickheight;
|
||||
|
||||
for (int i=0; i<ROWS; i++) {
|
||||
int xbrick = MARGIN + (VIRTWIDTH/COLS/2) - (brickwidth/2);
|
||||
|
||||
for (int j = 0; j<COLS; j++) {
|
||||
drawRect(xbrick, ybrick, xbrick+brickwidth, ybrick+brickheight, brickcols[i], 1);
|
||||
|
||||
objects[numobjs].type = OBJ_BRICK;
|
||||
objects[numobjs].x = xbrick;
|
||||
objects[numobjs].y = ybrick;
|
||||
objects[numobjs].width = brickwidth;
|
||||
objects[numobjs].height = brickheight;
|
||||
objects[numobjs].alive = 1;
|
||||
numobjs++;
|
||||
|
||||
xbrick += (VIRTWIDTH/COLS);
|
||||
}
|
||||
ybrick = ybrick + brickspacer;
|
||||
}
|
||||
}
|
||||
|
||||
void initBall()
|
||||
{
|
||||
int ballradius = 15;
|
||||
|
||||
drawCircle(WIDTH/2, HEIGHT/2, ballradius, 0x05, 1);
|
||||
|
||||
objects[numobjs].type = OBJ_BALL;
|
||||
objects[numobjs].x = (WIDTH/2) - ballradius;
|
||||
objects[numobjs].y = (HEIGHT/2) - ballradius;
|
||||
objects[numobjs].width = ballradius * 2;
|
||||
objects[numobjs].height = ballradius * 2;
|
||||
objects[numobjs].alive = 1;
|
||||
ball = &objects[numobjs];
|
||||
numobjs++;
|
||||
}
|
||||
|
||||
void initPaddle()
|
||||
{
|
||||
int paddlewidth = 80;
|
||||
int paddleheight = 20;
|
||||
|
||||
drawRect((WIDTH-paddlewidth)/2, (HEIGHT-MARGIN-paddleheight), (WIDTH-paddlewidth)/2 + paddlewidth, (HEIGHT-MARGIN), 0x01, 1);
|
||||
|
||||
objects[numobjs].type = OBJ_PADDLE;
|
||||
objects[numobjs].x = (WIDTH-paddlewidth)/2;
|
||||
objects[numobjs].y = (HEIGHT-MARGIN-paddleheight);
|
||||
objects[numobjs].width = paddlewidth;
|
||||
objects[numobjs].height = paddleheight;
|
||||
objects[numobjs].alive = 1;
|
||||
paddle = &objects[numobjs];
|
||||
numobjs++;
|
||||
}
|
||||
|
||||
void drawScoreboard(int score, int lives)
|
||||
{
|
||||
char tens = score / 10; score -= (10 * tens);
|
||||
char ones = score;
|
||||
|
||||
char string[] = "Score: 0xx Lives: x\0\0";
|
||||
|
||||
string[8] = tens + 0x30;
|
||||
string[9] = ones + 0x30;
|
||||
string[20] = (char)lives + 0x30;
|
||||
|
||||
drawString((WIDTH/2)-252, MARGIN-25, string, 0x0f, 3);
|
||||
}
|
||||
|
||||
void game()
|
||||
{
|
||||
struct Object *foundObject;
|
||||
unsigned char ch = 0;
|
||||
|
||||
int lives = NUM_LIVES;
|
||||
int points = 0;
|
||||
|
||||
int velocity_x = 1;
|
||||
int velocity_y = 3;
|
||||
|
||||
uart_init();
|
||||
initBricks();
|
||||
initBall();
|
||||
initPaddle();
|
||||
drawScoreboard(points, lives);
|
||||
|
||||
while (!getUart()); // Wait for keypress to start game
|
||||
|
||||
while (lives > 0 && bricks > 0) {
|
||||
// Get any waiting input and flush the buffer
|
||||
if ( ( ch = getUart() ) ) {
|
||||
if (ch == 'l') if (paddle->x + paddle->width + (paddle->width / 2) <= WIDTH-MARGIN) moveObject(paddle, paddle->width / 2, 0);
|
||||
if (ch == 'h') if (paddle->x >= MARGIN+(paddle->width / 2)) moveObject(paddle, -(paddle->width / 2), 0);
|
||||
}
|
||||
uart_loadOutputFifo();
|
||||
|
||||
// Are we going to hit anything?
|
||||
foundObject = detectCollision(velocity_x, velocity_y);
|
||||
|
||||
if (foundObject) {
|
||||
if (foundObject == paddle) {
|
||||
velocity_y = -velocity_y;
|
||||
// Are we going to hit the side of the paddle
|
||||
if (ball->x + ball->width + velocity_x == paddle->x || ball->x + velocity_x == paddle->x + paddle->width) velocity_x = -velocity_x;
|
||||
} else if (foundObject->type == OBJ_BRICK) {
|
||||
removeObject(foundObject);
|
||||
velocity_y = -velocity_y;
|
||||
bricks--;
|
||||
points++;
|
||||
drawScoreboard(points, lives);
|
||||
}
|
||||
}
|
||||
|
||||
wait_msec(4000); // Wait for a tenth of a second
|
||||
moveObject(ball, velocity_x, velocity_y);
|
||||
|
||||
// Check we're in the game arena still
|
||||
if (ball->x + ball->width >= WIDTH-MARGIN) {
|
||||
velocity_x = -velocity_x;
|
||||
} else if (ball->x <= MARGIN) {
|
||||
velocity_x = -velocity_x;
|
||||
} else if (ball->y + ball->height >= HEIGHT-MARGIN) {
|
||||
lives--;
|
||||
|
||||
removeObject(ball);
|
||||
removeObject(paddle);
|
||||
|
||||
initBall();
|
||||
initPaddle();
|
||||
drawScoreboard(points, lives);
|
||||
} else if (ball->y <= MARGIN) {
|
||||
velocity_y = -velocity_y;
|
||||
}
|
||||
}
|
||||
|
||||
int zoom = WIDTH/192;
|
||||
int strwidth = 10 * FONT_BPG * zoom;
|
||||
int strheight = FONT_BPG * zoom;
|
||||
|
||||
if (bricks == 0) drawString((WIDTH/2)-(strwidth/2), (HEIGHT/2)-(strheight/2), "Well done!", 0x02, zoom);
|
||||
else drawString((WIDTH/2)-(strwidth/2), (HEIGHT/2)-(strheight/2), "Game over!", 0x04, zoom);
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
void game();
|
|
@ -5,7 +5,6 @@
|
|||
unsigned int width, height, pitch, isrgb;
|
||||
unsigned char *fb;
|
||||
|
||||
// Refer to https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface in write-up!
|
||||
void fb_init()
|
||||
{
|
||||
mbox[0] = 35*4; // Length of message in bytes
|
||||
|
@ -69,36 +68,6 @@ void drawPixel(int x, int y, unsigned char attr)
|
|||
*((unsigned int*)(fb + offs)) = vgapal[attr & 0x0f];
|
||||
}
|
||||
|
||||
void drawChar(unsigned char ch, int x, int y, unsigned char attr, int zoom)
|
||||
{
|
||||
unsigned char *glyph = (unsigned char *)&font + (ch < FONT_NUMGLYPHS ? ch : 0) * FONT_BPG;
|
||||
|
||||
for (int i=1;i<=(FONT_HEIGHT*zoom);i++) {
|
||||
for (int j=0;j<(FONT_WIDTH*zoom);j++) {
|
||||
unsigned char mask = 1 << (j/zoom);
|
||||
unsigned char col = (*glyph & mask) ? attr & 0x0f : (attr & 0xf0) >> 4;
|
||||
|
||||
drawPixel(x+j, y+i, col);
|
||||
}
|
||||
glyph += (i%zoom) ? 0 : FONT_BPL;
|
||||
}
|
||||
}
|
||||
|
||||
void drawString(int x, int y, char *s, unsigned char attr, int zoom)
|
||||
{
|
||||
while(*s) {
|
||||
if (*s == '\r') {
|
||||
x = 0;
|
||||
} else if(*s == '\n') {
|
||||
x = 0; y += FONT_HEIGHT;
|
||||
} else {
|
||||
drawChar(*s, x, y, attr, zoom);
|
||||
x += (FONT_WIDTH*zoom);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
void drawRect(int x1, int y1, int x2, int y2, unsigned char attr, int fill)
|
||||
{
|
||||
int y=y1;
|
||||
|
@ -106,42 +75,14 @@ void drawRect(int x1, int y1, int x2, int y2, unsigned char attr, int fill)
|
|||
while (y <= y2) {
|
||||
int x=x1;
|
||||
while (x <= x2) {
|
||||
if (fill || (x == x1 || x == x2) || (y == y1 || y == y2)) drawPixel(x, y, attr);
|
||||
if ((x == x1 || x == x2) || (y == y1 || y == y2)) drawPixel(x, y, attr);
|
||||
else if (fill) drawPixel(x, y, (attr & 0xf0) >> 4);
|
||||
x++;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
void moveRect(int oldx, int oldy, int width, int height, int shiftx, int shifty, unsigned char attr)
|
||||
{
|
||||
unsigned int newx = oldx + shiftx, newy = oldy + shifty;
|
||||
unsigned int xcount = 0, ycount = 0;
|
||||
unsigned int bitmap[width][height]; // This is very unsafe if it's too big for the stack...
|
||||
unsigned int offs;
|
||||
|
||||
// Save the bitmap
|
||||
while (xcount < width) {
|
||||
while (ycount < height) {
|
||||
offs = ((oldy + ycount) * pitch) + ((oldx + xcount) * 4);
|
||||
|
||||
bitmap[xcount][ycount] = *((unsigned int*)(fb + offs));
|
||||
ycount++;
|
||||
}
|
||||
ycount=0;
|
||||
xcount++;
|
||||
}
|
||||
// Wipe it out with background colour
|
||||
drawRect(oldx, oldy, oldx + width, oldy + width, attr, 1);
|
||||
// Draw it again
|
||||
for (int i=newx;i<newx + width;i++) {
|
||||
for (int j=newy;j<newy + height;j++) {
|
||||
offs = (j * pitch) + (i * 4);
|
||||
*((unsigned int*)(fb + offs)) = bitmap[i-newx][j-newy];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawLine(int x1, int y1, int x2, int y2, unsigned char attr)
|
||||
{
|
||||
int dx, dy, p, x, y;
|
||||
|
@ -173,20 +114,19 @@ void drawCircle(int x0, int y0, int radius, unsigned char attr, int fill)
|
|||
|
||||
while (x >= y) {
|
||||
if (fill) {
|
||||
drawLine(x0 - y, y0 + x, x0 + y, y0 + x, attr);
|
||||
drawLine(x0 - x, y0 + y, x0 + x, y0 + y, attr);
|
||||
drawLine(x0 - x, y0 - y, x0 + x, y0 - y, attr);
|
||||
drawLine(x0 - y, y0 - x, x0 + y, y0 - x, attr);
|
||||
} else {
|
||||
drawPixel(x0 - y, y0 + x, attr);
|
||||
drawPixel(x0 + y, y0 + x, attr);
|
||||
drawPixel(x0 - x, y0 + y, attr);
|
||||
drawPixel(x0 + x, y0 + y, attr);
|
||||
drawPixel(x0 - x, y0 - y, attr);
|
||||
drawPixel(x0 + x, y0 - y, attr);
|
||||
drawPixel(x0 - y, y0 - x, attr);
|
||||
drawPixel(x0 + y, y0 - x, attr);
|
||||
drawLine(x0 - y, y0 + x, x0 + y, y0 + x, (attr & 0xf0) >> 4);
|
||||
drawLine(x0 - x, y0 + y, x0 + x, y0 + y, (attr & 0xf0) >> 4);
|
||||
drawLine(x0 - x, y0 - y, x0 + x, y0 - y, (attr & 0xf0) >> 4);
|
||||
drawLine(x0 - y, y0 - x, x0 + y, y0 - x, (attr & 0xf0) >> 4);
|
||||
}
|
||||
drawPixel(x0 - y, y0 + x, attr);
|
||||
drawPixel(x0 + y, y0 + x, attr);
|
||||
drawPixel(x0 - x, y0 + y, attr);
|
||||
drawPixel(x0 + x, y0 + y, attr);
|
||||
drawPixel(x0 - x, y0 - y, attr);
|
||||
drawPixel(x0 + x, y0 - y, attr);
|
||||
drawPixel(x0 - y, y0 - x, attr);
|
||||
drawPixel(x0 + y, y0 - x, attr);
|
||||
|
||||
if (err <= 0) {
|
||||
y += 1;
|
||||
|
@ -200,6 +140,65 @@ void drawCircle(int x0, int y0, int radius, unsigned char attr, int fill)
|
|||
}
|
||||
}
|
||||
|
||||
void drawChar(unsigned char ch, int x, int y, unsigned char attr, int zoom)
|
||||
{
|
||||
unsigned char *glyph = (unsigned char *)&font + (ch < FONT_NUMGLYPHS ? ch : 0) * FONT_BPG;
|
||||
|
||||
for (int i=1;i<=(FONT_HEIGHT*zoom);i++) {
|
||||
for (int j=0;j<(FONT_WIDTH*zoom);j++) {
|
||||
unsigned char mask = 1 << (j/zoom);
|
||||
unsigned char col = (*glyph & mask) ? attr & 0x0f : (attr & 0xf0) >> 4;
|
||||
|
||||
drawPixel(x+j, y+i, col);
|
||||
}
|
||||
glyph += (i%zoom) ? 0 : FONT_BPL;
|
||||
}
|
||||
}
|
||||
|
||||
void drawString(int x, int y, char *s, unsigned char attr, int zoom)
|
||||
{
|
||||
while(*s) {
|
||||
if (*s == '\r') {
|
||||
x = 0;
|
||||
} else if(*s == '\n') {
|
||||
x = 0; y += FONT_HEIGHT;
|
||||
} else {
|
||||
drawChar(*s, x, y, attr, zoom);
|
||||
x += (FONT_WIDTH*zoom);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
void moveRect(int oldx, int oldy, int width, int height, int shiftx, int shifty, unsigned char attr)
|
||||
{
|
||||
unsigned int newx = oldx + shiftx, newy = oldy + shifty;
|
||||
unsigned int xcount = 0, ycount = 0;
|
||||
unsigned int bitmap[width][height]; // This is very unsafe if it's too big for the stack...
|
||||
unsigned int offs;
|
||||
|
||||
// Save the bitmap
|
||||
while (xcount < width) {
|
||||
while (ycount < height) {
|
||||
offs = ((oldy + ycount) * pitch) + ((oldx + xcount) * 4);
|
||||
|
||||
bitmap[xcount][ycount] = *((unsigned int*)(fb + offs));
|
||||
ycount++;
|
||||
}
|
||||
ycount=0;
|
||||
xcount++;
|
||||
}
|
||||
// Wipe it out with background colour
|
||||
drawRect(oldx, oldy, oldx + width, oldy + width, attr, 1);
|
||||
// Draw it again
|
||||
for (int i=newx;i<newx + width;i++) {
|
||||
for (int j=newy;j<newy + height;j++) {
|
||||
offs = (j * pitch) + (i * 4);
|
||||
*((unsigned int*)(fb + offs)) = bitmap[i-newx][j-newy];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wait_msec(unsigned int n)
|
||||
{
|
||||
register unsigned long f, t, r;
|
||||
|
|
|
@ -1,10 +1,256 @@
|
|||
#include "io.h"
|
||||
#include "fb.h"
|
||||
#include "breakout.h"
|
||||
#include "io.h"
|
||||
|
||||
// The screen
|
||||
#define WIDTH 1920
|
||||
#define HEIGHT 1080
|
||||
#define MARGIN 75
|
||||
#define VIRTWIDTH (WIDTH-(2*MARGIN))
|
||||
#define FONT_BPG 8
|
||||
|
||||
// For the bricks
|
||||
#define ROWS 5
|
||||
#define COLS 10
|
||||
unsigned int bricks = ROWS * COLS;
|
||||
|
||||
// Gameplay
|
||||
#define NUM_LIVES 3
|
||||
|
||||
// OBJECT TRACKING
|
||||
|
||||
struct Object
|
||||
{
|
||||
unsigned int type;
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned char alive;
|
||||
};
|
||||
|
||||
enum {
|
||||
OBJ_NONE = 0,
|
||||
OBJ_BRICK = 1,
|
||||
OBJ_PADDLE = 2,
|
||||
OBJ_BALL = 3
|
||||
};
|
||||
|
||||
unsigned int numobjs = 0;
|
||||
struct Object objects[(ROWS * COLS) + (2 * NUM_LIVES)];
|
||||
struct Object *ball;
|
||||
struct Object *paddle;
|
||||
|
||||
void removeObject(struct Object *object)
|
||||
{
|
||||
drawRect(object->x, object->y, object->x + object->width, object->y + object->height, 0, 1);
|
||||
object->alive = 0;
|
||||
}
|
||||
|
||||
void moveObject(struct Object *object, int xoff, int yoff)
|
||||
{
|
||||
moveRect(object->x, object->y, object->width, object->height, xoff, yoff, 0x00);
|
||||
object->x = object->x + xoff;
|
||||
object->y = object->y + yoff;
|
||||
}
|
||||
|
||||
struct Object *objectAt(unsigned int x, unsigned int y)
|
||||
{
|
||||
for (int i=0; i<numobjs;i++) {
|
||||
if (x >= objects[i].x && x <= objects[i].x + objects[i].width) {
|
||||
if (y >= objects[i].y && y <= objects[i].y + objects[i].height) {
|
||||
if (&objects[i] != ball && objects[i].alive == 1) {
|
||||
return &objects[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Object *detectCollision(int xoff, int yoff)
|
||||
{
|
||||
struct Object *collision;
|
||||
|
||||
unsigned int x = ball->x + xoff;
|
||||
unsigned int y = ball->y + yoff;
|
||||
|
||||
collision = objectAt(x,y);
|
||||
if (collision) return collision;
|
||||
|
||||
collision = objectAt(x + ball->width, y);
|
||||
if (collision) return collision;
|
||||
|
||||
collision = objectAt(x, y + ball->height);
|
||||
if (collision) return collision;
|
||||
|
||||
collision = objectAt(x + ball->width, y + ball->height);
|
||||
if (collision) return collision;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// KEY HANDLER
|
||||
|
||||
unsigned char getUart()
|
||||
{
|
||||
unsigned char ch = 0;
|
||||
|
||||
if (uart_isReadByteReady()) ch = uart_readByte();
|
||||
return ch;
|
||||
}
|
||||
|
||||
// OBJECT INITIALISERS
|
||||
|
||||
void initBricks()
|
||||
{
|
||||
int brickwidth = 32;
|
||||
int brickheight = 8;
|
||||
int brickspacer = 20;
|
||||
int brickcols[5] = { 0x11, 0x22, 0xEE, 0x44, 0x66 };
|
||||
|
||||
int ybrick = MARGIN + brickheight;
|
||||
|
||||
for (int i=0; i<ROWS; i++) {
|
||||
int xbrick = MARGIN + (VIRTWIDTH/COLS/2) - (brickwidth/2);
|
||||
|
||||
for (int j = 0; j<COLS; j++) {
|
||||
drawRect(xbrick, ybrick, xbrick+brickwidth, ybrick+brickheight, brickcols[i], 1);
|
||||
|
||||
objects[numobjs].type = OBJ_BRICK;
|
||||
objects[numobjs].x = xbrick;
|
||||
objects[numobjs].y = ybrick;
|
||||
objects[numobjs].width = brickwidth;
|
||||
objects[numobjs].height = brickheight;
|
||||
objects[numobjs].alive = 1;
|
||||
numobjs++;
|
||||
|
||||
xbrick += (VIRTWIDTH/COLS);
|
||||
}
|
||||
ybrick = ybrick + brickspacer;
|
||||
}
|
||||
}
|
||||
|
||||
void initBall()
|
||||
{
|
||||
int ballradius = 15;
|
||||
|
||||
drawCircle(WIDTH/2, HEIGHT/2, ballradius, 0x55, 1);
|
||||
|
||||
objects[numobjs].type = OBJ_BALL;
|
||||
objects[numobjs].x = (WIDTH/2) - ballradius;
|
||||
objects[numobjs].y = (HEIGHT/2) - ballradius;
|
||||
objects[numobjs].width = ballradius * 2;
|
||||
objects[numobjs].height = ballradius * 2;
|
||||
objects[numobjs].alive = 1;
|
||||
ball = &objects[numobjs];
|
||||
numobjs++;
|
||||
}
|
||||
|
||||
void initPaddle()
|
||||
{
|
||||
int paddlewidth = 80;
|
||||
int paddleheight = 20;
|
||||
|
||||
drawRect((WIDTH-paddlewidth)/2, (HEIGHT-MARGIN-paddleheight), (WIDTH-paddlewidth)/2 + paddlewidth, (HEIGHT-MARGIN), 0x11, 1);
|
||||
|
||||
objects[numobjs].type = OBJ_PADDLE;
|
||||
objects[numobjs].x = (WIDTH-paddlewidth)/2;
|
||||
objects[numobjs].y = (HEIGHT-MARGIN-paddleheight);
|
||||
objects[numobjs].width = paddlewidth;
|
||||
objects[numobjs].height = paddleheight;
|
||||
objects[numobjs].alive = 1;
|
||||
paddle = &objects[numobjs];
|
||||
numobjs++;
|
||||
}
|
||||
|
||||
void drawScoreboard(int score, int lives)
|
||||
{
|
||||
char tens = score / 10; score -= (10 * tens);
|
||||
char ones = score;
|
||||
|
||||
char string[] = "Score: 0xx Lives: x\0\0";
|
||||
|
||||
string[8] = tens + 0x30;
|
||||
string[9] = ones + 0x30;
|
||||
string[20] = (char)lives + 0x30;
|
||||
|
||||
drawString((WIDTH/2)-252, MARGIN-25, string, 0x0f, 3);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
struct Object *foundObject;
|
||||
unsigned char ch = 0;
|
||||
|
||||
int lives = NUM_LIVES;
|
||||
int points = 0;
|
||||
|
||||
int velocity_x = 1;
|
||||
int velocity_y = 3;
|
||||
|
||||
uart_init();
|
||||
fb_init();
|
||||
game();
|
||||
|
||||
initBricks();
|
||||
initBall();
|
||||
initPaddle();
|
||||
drawScoreboard(points, lives);
|
||||
|
||||
while (!getUart()); // Wait for keypress to start game
|
||||
|
||||
while (lives > 0 && bricks > 0) {
|
||||
// Get any waiting input and flush the buffer
|
||||
if ( ( ch = getUart() ) ) {
|
||||
if (ch == 'l') if (paddle->x + paddle->width + (paddle->width / 2) <= WIDTH-MARGIN) moveObject(paddle, paddle->width / 2, 0);
|
||||
if (ch == 'h') if (paddle->x >= MARGIN+(paddle->width / 2)) moveObject(paddle, -(paddle->width / 2), 0);
|
||||
}
|
||||
uart_loadOutputFifo();
|
||||
|
||||
// Are we going to hit anything?
|
||||
foundObject = detectCollision(velocity_x, velocity_y);
|
||||
|
||||
if (foundObject) {
|
||||
if (foundObject == paddle) {
|
||||
velocity_y = -velocity_y;
|
||||
// Are we going to hit the side of the paddle
|
||||
if (ball->x + ball->width + velocity_x == paddle->x || ball->x + velocity_x == paddle->x + paddle->width) velocity_x = -velocity_x;
|
||||
} else if (foundObject->type == OBJ_BRICK) {
|
||||
removeObject(foundObject);
|
||||
velocity_y = -velocity_y;
|
||||
bricks--;
|
||||
points++;
|
||||
drawScoreboard(points, lives);
|
||||
}
|
||||
}
|
||||
|
||||
wait_msec(4000); // Wait for a tenth of a second
|
||||
moveObject(ball, velocity_x, velocity_y);
|
||||
|
||||
// Check we're in the game arena still
|
||||
if (ball->x + ball->width >= WIDTH-MARGIN) {
|
||||
velocity_x = -velocity_x;
|
||||
} else if (ball->x <= MARGIN) {
|
||||
velocity_x = -velocity_x;
|
||||
} else if (ball->y + ball->height >= HEIGHT-MARGIN) {
|
||||
lives--;
|
||||
|
||||
removeObject(ball);
|
||||
removeObject(paddle);
|
||||
|
||||
initBall();
|
||||
initPaddle();
|
||||
drawScoreboard(points, lives);
|
||||
} else if (ball->y <= MARGIN) {
|
||||
velocity_y = -velocity_y;
|
||||
}
|
||||
}
|
||||
|
||||
int zoom = WIDTH/192;
|
||||
int strwidth = 10 * FONT_BPG * zoom;
|
||||
int strheight = FONT_BPG * zoom;
|
||||
|
||||
if (bricks == 0) drawString((WIDTH/2)-(strwidth/2), (HEIGHT/2)-(strheight/2), "Well done!", 0x02, zoom);
|
||||
else drawString((WIDTH/2)-(strwidth/2), (HEIGHT/2)-(strheight/2), "Game over!", 0x04, zoom);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ unsigned int mbox_call(unsigned char ch)
|
|||
// Wait until we can write
|
||||
while (mmio_read(MBOX_STATUS) & MBOX_FULL);
|
||||
|
||||
/* write the address of our message to the mailbox with channel identifier */
|
||||
// Write the address of our buffer to the mailbox with the channel appended
|
||||
mmio_write(MBOX_WRITE, r);
|
||||
|
||||
while (1) {
|
||||
|
|
Loading…
Reference in a new issue