Some improvements to Bluetooth Breakout

This commit is contained in:
Adam Greenwood-Byrne 2020-08-12 18:53:12 +01:00
parent dbc2c6139b
commit 21681400ae
4 changed files with 81 additions and 117 deletions

View file

@ -6,11 +6,9 @@ void bt_getbdaddr(unsigned char *bdaddr);
void bt_init();
unsigned int bt_isReadByteReady();
unsigned char bt_readByte();
unsigned char bt_waitReadByte();
void setLEeventmask(unsigned char mask);
void startActiveScanning();
void stopScanning();
void startActiveAdvertising();
void connect(unsigned char *addr);
void bt_flushrx();
void sendACLsubscribe(unsigned int handle);

View file

@ -170,35 +170,6 @@ void drawString(int x, int y, char *s, unsigned char attr, int zoom)
}
}
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 moveRectAbs(int oldx, int oldy, int width, int height, int newx, int newy, unsigned char attr)
{
unsigned int xcount = 0, ycount = 0;

View file

@ -5,6 +5,5 @@ void drawString(int x, int y, char *s, unsigned char attr, int zoom);
void drawRect(int x1, int y1, int x2, int y2, unsigned char attr, int fill);
void drawCircle(int x0, int y0, int radius, unsigned char attr, int fill);
void drawLine(int x1, int y1, int x2, int y2, unsigned char attr);
void moveRect(int oldx, int oldy, int width, int height, int shiftx, int shifty, unsigned char attr);
void moveRectAbs(int oldx, int oldy, int width, int height, int newx, int newy, unsigned char attr);
void wait_msec(unsigned int n);

View file

@ -25,7 +25,7 @@ unsigned int got_echo_name = 0;
unsigned char echo_addr[6];
unsigned int connected = 0;
unsigned int connection_handle = 0;
unsigned char dir = 'l';
unsigned char dir = 50;
void hci_poll2(unsigned char byte)
{
@ -160,7 +160,6 @@ void bt_conn()
// For the bricks
#define ROWS 5
#define COLS 10
unsigned int bricks = ROWS * COLS;
// Gameplay
#define NUM_LIVES 3
@ -196,13 +195,6 @@ void removeObject(struct Object *object)
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;
}
void moveObjectAbs(struct Object *object, int x, int y)
{
moveRectAbs(object->x, object->y, object->width, object->height, x, y, 0x00);
@ -277,11 +269,12 @@ void initBall()
void initPaddle()
{
int paddleheight = 20;
int startx = MARGIN + (dir * ((VIRTWIDTH - paddlewidth + MARGIN)/100));
drawRect((WIDTH-paddlewidth)/2, (HEIGHT-MARGIN-paddleheight), (WIDTH-paddlewidth)/2 + paddlewidth, (HEIGHT-MARGIN), 0x11, 1);
drawRect(startx, (HEIGHT-MARGIN-paddleheight), startx + paddlewidth, (HEIGHT-MARGIN), 0x11, 1);
objects[numobjs].type = OBJ_PADDLE;
objects[numobjs].x = (WIDTH-paddlewidth)/2;
objects[numobjs].x = startx;
objects[numobjs].y = (HEIGHT-MARGIN-paddleheight);
objects[numobjs].width = paddlewidth;
objects[numobjs].height = paddleheight;
@ -310,51 +303,107 @@ void acl_poll()
unsigned char byte = bt_readByte();
if (byte == HCI_EVENT_PKT) {
unsigned char opcode = bt_waitReadByte();
unsigned char length = bt_waitReadByte();
for (int i=0;i<length;i++) bt_waitReadByte();
bt_readByte(); // opcode
unsigned char length = bt_readByte();
for (int i=0;i<length;i++) bt_readByte();
} else if (byte == HCI_ACL_PKT) {
unsigned char h1 = bt_waitReadByte();
unsigned char h2 = bt_waitReadByte();
bt_readByte(); // handle1
bt_readByte(); // handle2
unsigned int handle = h1 | (h2 & 0x0f);
unsigned char flags = (h2 & 0xf0) >> 4;
h1 = bt_waitReadByte();
h2 = bt_waitReadByte();
unsigned char h1 = bt_readByte();
unsigned char h2 = bt_readByte();
unsigned int length = h1 | (h2 << 8);
unsigned char data[length];
for (int i=0;i<length;i++) data[i] = bt_waitReadByte();
for (int i=0;i<length;i++) data[i] = bt_readByte();
length = data[0] | (data[1] << 8);
unsigned int channel = data[2] | (data[3] << 8);
unsigned char opcode = data[4];
if (opcode == 0x1b) {
unsigned int from_handle = data[5] | (data[6] << 8);
if (length == 4) {
dir = data[7];
moveObjectAbs(paddle, MARGIN + (dir*((VIRTWIDTH - paddlewidth)/100)), paddle->y);
dir = data[7];
moveObjectAbs(paddle, MARGIN + (dir * ((VIRTWIDTH - paddlewidth + MARGIN)/100)), paddle->y);
}
uart_writeText("\n");
}
}
}
}
void main()
void breakout()
{
struct Object *foundObject;
int bricks = ROWS * COLS;
int lives = NUM_LIVES;
int points = 0;
int velocity_x = 1;
int velocity_y = 3;
initBricks();
initBall();
initPaddle();
drawScoreboard(points, lives);
while (lives > 0 && bricks > 0) {
acl_poll();
// Are we going to hit anything?
foundObject = detectCollision(ball, 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(0x186A);
moveObjectAbs(ball, ball->x + velocity_x, ball->y + 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);
drawScoreboard(points, lives);
if (lives) {
initBall();
initPaddle();
}
} 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);
wait_msec(0x500000); // Wait 5 seconds
drawRect((WIDTH/2)-(strwidth/2), (HEIGHT/2)-(strheight/2), (WIDTH/2)+(strwidth/2), (HEIGHT/2)+(strheight/2), 0, 1);
}
void main()
{
uart_init();
bt_init();
@ -364,12 +413,6 @@ void main()
bt_setbaud();
bt_setbdaddr();
fb_init();
initBricks();
initBall();
initPaddle();
drawScoreboard(points, lives);
// Print the BD_ADDR
unsigned char local_addr[6];
bt_getbdaddr(local_addr);
@ -398,55 +441,8 @@ void main()
// Begin the game
uart_writeText("Let the game commence...\n");
wait_msec(0x100000); // Wait a second
while (lives > 0 && bricks > 0) {
acl_poll();
// Are we going to hit anything?
foundObject = detectCollision(ball, 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(0x2000);
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) acl_poll();
fb_init();
while (1) breakout();
}