Controlling Breakout using the MacBook Pro trackpad over Bluetooth

This commit is contained in:
Adam Greenwood-Byrne 2020-08-12 14:58:20 +01:00
parent 3cea210167
commit dbc2c6139b
3 changed files with 80 additions and 61 deletions

View file

@ -199,6 +199,34 @@ void moveRect(int oldx, int oldy, int width, int height, int shiftx, int shifty,
}
}
void moveRectAbs(int oldx, int oldy, int width, int height, int newx, int newy, unsigned char attr)
{
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;

View file

@ -6,4 +6,5 @@ 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 = 1;
unsigned char dir = 'l';
void hci_poll2(unsigned char byte)
{
@ -150,47 +150,6 @@ void bt_conn()
}
}
void acl_poll()
{
while (bt_isReadByteReady()) {
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();
} else if (byte == HCI_ACL_PKT) {
unsigned char h1 = bt_waitReadByte();
unsigned char h2 = bt_waitReadByte();
unsigned int handle = h1 | (h2 & 0x0f);
unsigned char flags = (h2 & 0xf0) >> 4;
h1 = bt_waitReadByte();
h2 = bt_waitReadByte();
unsigned int length = h1 | (h2 << 8);
unsigned char data[length];
for (int i=0;i<length;i++) data[i] = bt_waitReadByte();
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];
uart_byte(dir);
}
uart_writeText("\n");
}
}
}
}
// The screen
#define WIDTH 1920
#define HEIGHT 1080
@ -229,6 +188,7 @@ unsigned int numobjs = 0;
struct Object objects[(ROWS * COLS) + (2 * NUM_LIVES)];
struct Object *ball;
struct Object *paddle;
int paddlewidth = 80;
void removeObject(struct Object *object)
{
@ -243,6 +203,13 @@ void moveObject(struct Object *object, int xoff, int yoff)
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);
object->x = x;
object->y = y;
}
struct Object *detectCollision(struct Object *with, int xoff, int yoff)
{
for (int i=0; i<numobjs;i++) {
@ -260,16 +227,6 @@ struct Object *detectCollision(struct Object *with, int xoff, int yoff)
return 0;
}
// KEY HANDLER
unsigned char getUart()
{
unsigned char ch = 0;
if (uart_isReadByteReady()) ch = uart_readByte();
return ch;
}
// OBJECT INITIALISERS
void initBricks()
@ -319,7 +276,6 @@ void initBall()
void initPaddle()
{
int paddlewidth = 80;
int paddleheight = 20;
drawRect((WIDTH-paddlewidth)/2, (HEIGHT-MARGIN-paddleheight), (WIDTH-paddlewidth)/2 + paddlewidth, (HEIGHT-MARGIN), 0x11, 1);
@ -348,6 +304,47 @@ void drawScoreboard(int score, int lives)
drawString((WIDTH/2)-252, MARGIN-25, string, 0x0f, 3);
}
void acl_poll()
{
while (bt_isReadByteReady()) {
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();
} else if (byte == HCI_ACL_PKT) {
unsigned char h1 = bt_waitReadByte();
unsigned char h2 = bt_waitReadByte();
unsigned int handle = h1 | (h2 & 0x0f);
unsigned char flags = (h2 & 0xf0) >> 4;
h1 = bt_waitReadByte();
h2 = bt_waitReadByte();
unsigned int length = h1 | (h2 << 8);
unsigned char data[length];
for (int i=0;i<length;i++) data[i] = bt_waitReadByte();
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);
}
uart_writeText("\n");
}
}
}
}
void main()
{
struct Object *foundObject;
@ -405,13 +402,6 @@ void main()
while (lives > 0 && bricks > 0) {
acl_poll();
// Get any waiting input and flush the buffer
if (dir != 1) {
if (dir == 2) if (paddle->x + paddle->width + (paddle->width / 2) <= WIDTH-MARGIN) moveObject(paddle, paddle->width / 2, 0);
if (dir == 0) if (paddle->x >= MARGIN+(paddle->width / 2)) moveObject(paddle, -(paddle->width / 2), 0);
}
uart_loadOutputFifo();
// Are we going to hit anything?
foundObject = detectCollision(ball, velocity_x, velocity_y);
@ -429,7 +419,7 @@ void main()
}
}
wait_msec(4000); // Wait a little...
wait_msec(0x2000);
moveObject(ball, velocity_x, velocity_y);
// Check we're in the game arena still