#include "breakout.h" #include "include/fb.h" #include "include/multicore.h" // OBJECT INITIALISERS void initBricks(void) { int brickwidth = 32; int brickheight = 8; int brickspacer = 20; const int brickcols[] = { 0x11, 0x22, 0xEE, 0x44, 0x66 }; int ybrick = MARGIN + brickheight; for (int i=0; imove || scoreboard->redraw); // Wait for any current move/redraw to finish scoreboard->x = lives; scoreboard->y = points; scoreboard->redraw = 1; } void initEndgame(void) { objects[numobjs].type = OBJ_ENDGAME; objects[numobjs].x = 0; objects[numobjs].y = 0; objects[numobjs].width = 0; // unused objects[numobjs].height = 0; // unused objects[numobjs].color = 0; objects[numobjs].alive = 0; objects[numobjs].redraw = 0; objects[numobjs].move = 0; endgame = &objects[numobjs]; numobjs++; } void updateEndgame(int gameover, int welldone) { while (endgame->move || endgame->redraw); // Wait for any current move/redraw to finish endgame->x = gameover; endgame->y = welldone; endgame->color = welldone ? 0x02 : 0x04; endgame->alive = gameover | welldone; endgame->redraw = 1; } void removeObject(volatile struct Object *object) { while (object->move || object->redraw); // Wait for any current move/redraw to finish object->alive = 0; object->redraw = 1; } volatile struct Object *detectObjectCollision(volatile struct Object *with, int xoff, int yoff) { for (int i=0; ix + xoff > objects[i].x + objects[i].width || objects[i].x > with->x + xoff + with->width) { // with is too far left or right to collide } else if (with->y + yoff > objects[i].y + objects[i].height || objects[i].y > with->y + yoff + with->height) { // with is too far up or down to collide } else { // Collision! return &objects[i]; } } } return 0; } void moveObject(volatile struct Object *object, int x, int y) { while (object->move || object->redraw); // Wait for any current move/redraw to finish object->newx = x; object->newy = y; object->move = 1; } // THE GAME const int ballradius = 15; const int paddlewidth = 80; volatile unsigned char dir; volatile unsigned int numobjs; volatile struct Object *objects = (struct Object *)HEAP_ADDRESS; volatile struct Object *ball; volatile struct Object *paddle; volatile struct Object *scoreboard; volatile struct Object *endgame; void breakout_init() { numobjs = 0; dir = 50; initBricks(); initBall(); initPaddle(); initScoreboard(0, NUM_LIVES); initEndgame(); } void breakout() { volatile struct Object *foundObject; int bricks = ROWS * COLS; int lives = NUM_LIVES; int points = 0; int velocity_x = 1; int velocity_y = 3; while (lives > 0 && bricks > 0) { // Are we going to hit anything? foundObject = detectObjectCollision(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++; updateScoreboard(points, lives); } } moveObject(ball, ball->x + velocity_x, ball->y + velocity_y); wait_msec(0x186A); // 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); updateScoreboard(points, lives); if (lives) { initBall(); initPaddle(); } } else if (ball->y <= MARGIN) { velocity_y = -velocity_y; } } // Show endgame state if (bricks == 0) { removeObject(ball); removeObject(paddle); updateEndgame(0, 1); } else { updateEndgame(1, 0); } wait_msec(0x500000); // Wait 5 seconds // Clear endgame state updateEndgame(0, 0); } void main() { fb_init(); // Init the screen for debug start_core3(comms_core); // Start the comms engine (core 3) while (!comms_up); // Wait for comms up breakout_init(); // Initialise the game engine (core 0) start_core1(gfx_core); // Start the graphics engine (core 1) start_core2(snd_core); // Start the sound engine (core 2) while (1) { breakout(); // Run the game breakout_init(); // Re-initialise the game engine } }