diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aceea17 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode/ +*.elf +.editorconfig +.clang-format diff --git a/README.md b/README.md index 9b2677c..ac99d8e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # flipperzero-pong A Pong game for the Flipper Zero -![](https://github.com/nmrr/flipperzero-pong/blob/main/img/Flipper_Zero.jpg) - Assuming the toolchain is already installed, copy **flipper_pong** directory to **applications_user** Plug your **Flipper Zero** and build the Pong : @@ -19,5 +17,4 @@ Press **Up** or **Down** to move your paddle. Press back button to quit If you don't want to build the game, just simply copy **flipper_pong.fap** on your **Flipper Zero** ## Gallery ## - - +![](img/flipper1.png) | ![](img/flipper2.png) | ![](img/flipper3.png) \ No newline at end of file diff --git a/flipper_pong/application.fam b/application.fam similarity index 100% rename from flipper_pong/application.fam rename to application.fam diff --git a/dist/flipper_pong.fap b/dist/flipper_pong.fap new file mode 100644 index 0000000..465024e Binary files /dev/null and b/dist/flipper_pong.fap differ diff --git a/flipper_pong/flipper_pong.c b/flipper_pong.c similarity index 53% rename from flipper_pong/flipper_pong.c rename to flipper_pong.c index c25e46b..814627b 100644 --- a/flipper_pong/flipper_pong.c +++ b/flipper_pong.c @@ -15,7 +15,8 @@ #define PAD_SIZE_X 3 #define PAD_SIZE_Y 8 -#define PLAYER1_PAD_SPEED 2 +#define PLAYER1_PAD_SPEED 4 + #define PLAYER2_PAD_SPEED 2 #define BALL_SIZE 4 @@ -29,34 +30,39 @@ typedef struct { InputEvent input; } EventApp; -typedef struct Players -{ - uint8_t player1_X,player1_Y,player2_X,player2_Y; - uint16_t player1_score,player2_score; - uint8_t ball_X,ball_Y,ball_X_speed,ball_Y_speed,ball_X_direction,ball_Y_direction; +typedef struct Players { + uint8_t player1_X, player1_Y, player2_X, player2_Y; + uint16_t player1_score, player2_score; + uint8_t ball_X, ball_Y, ball_X_speed, ball_Y_speed, ball_X_direction, ball_Y_direction; } Players; -static void draw_callback(Canvas* canvas, void* ctx) -{ +static void draw_callback(Canvas* canvas, void* ctx) { UNUSED(ctx); Players* playersMutex = (Players*)acquire_mutex_block((ValueMutex*)ctx); canvas_draw_frame(canvas, 0, 0, 128, 64); - canvas_draw_box(canvas, playersMutex->player1_X, playersMutex->player1_Y, PAD_SIZE_X, PAD_SIZE_Y); - canvas_draw_box(canvas, playersMutex->player2_X, playersMutex->player2_Y, PAD_SIZE_X, PAD_SIZE_Y); + canvas_draw_box( + canvas, playersMutex->player1_X, playersMutex->player1_Y, PAD_SIZE_X, PAD_SIZE_Y); + canvas_draw_box( + canvas, playersMutex->player2_X, playersMutex->player2_Y, PAD_SIZE_X, PAD_SIZE_Y); canvas_draw_box(canvas, playersMutex->ball_X, playersMutex->ball_Y, BALL_SIZE, BALL_SIZE); canvas_set_font(canvas, FontPrimary); canvas_set_font_direction(canvas, CanvasDirectionBottomToTop); char buffer[16]; - snprintf(buffer, sizeof(buffer), "%u - %u", playersMutex->player1_score, playersMutex->player2_score); - canvas_draw_str_aligned(canvas, SCREEN_SIZE_X/2+15, SCREEN_SIZE_Y/2+2, AlignCenter, AlignTop, buffer); + snprintf( + buffer, + sizeof(buffer), + "%u - %u", + playersMutex->player1_score, + playersMutex->player2_score); + canvas_draw_str_aligned( + canvas, SCREEN_SIZE_X / 2 + 15, SCREEN_SIZE_Y / 2 + 2, AlignCenter, AlignTop, buffer); release_mutex((ValueMutex*)ctx, playersMutex); } -static void input_callback(InputEvent* input_event, void* ctx) -{ +static void input_callback(InputEvent* input_event, void* ctx) { furi_assert(ctx); FuriMessageQueue* event_queue = ctx; EventApp event = {.type = EventTypeInput, .input = *input_event}; @@ -70,48 +76,44 @@ static void clock_tick(void* ctx) { furi_message_queue_put(queue, &event, 0); } -bool insidePad(uint8_t x, uint8_t y, uint8_t playerX, uint8_t playerY) -{ - if (x >= playerX && x <= playerX+PAD_SIZE_X && y >= playerY && y <= playerY+PAD_SIZE_Y) return true; +bool insidePad(uint8_t x, uint8_t y, uint8_t playerX, uint8_t playerY) { + if(x >= playerX && x <= playerX + PAD_SIZE_X && y >= playerY && y <= playerY + PAD_SIZE_Y) + return true; return false; } -uint8_t changeSpeed() -{ +uint8_t changeSpeed() { uint8_t randomuint8[1]; - while(1) - { - furi_hal_random_fill_buf(randomuint8,1); - randomuint8[0] &= 0b00000011; - if (randomuint8[0] >= 1) break; + while(1) { + furi_hal_random_fill_buf(randomuint8, 1); + randomuint8[0] &= 0b00000011; + if(randomuint8[0] >= 1) break; } return randomuint8[0]; } -uint8_t changeDirection() -{ +uint8_t changeDirection() { uint8_t randomuint8[1]; - furi_hal_random_fill_buf(randomuint8,1); + furi_hal_random_fill_buf(randomuint8, 1); randomuint8[0] &= 0b1; - return randomuint8[0]; + return randomuint8[0]; } -int32_t flipper_pong_app() -{ +int32_t flipper_pong_app() { EventApp event; FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(EventApp)); Players players; - players.player1_X = SCREEN_SIZE_X-PAD_SIZE_X-1; - players.player1_Y = SCREEN_SIZE_Y/2 - PAD_SIZE_Y/2; + players.player1_X = SCREEN_SIZE_X - PAD_SIZE_X - 1; + players.player1_Y = SCREEN_SIZE_Y / 2 - PAD_SIZE_Y / 2; players.player1_score = 0; players.player2_X = 1; - players.player2_Y = SCREEN_SIZE_Y/2 - PAD_SIZE_Y/2; + players.player2_Y = SCREEN_SIZE_Y / 2 - PAD_SIZE_Y / 2; players.player2_score = 0; - players.ball_X = SCREEN_SIZE_X/2 - BALL_SIZE/2; - players.ball_Y = SCREEN_SIZE_Y/2 - BALL_SIZE/2; + players.ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; + players.ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; players.ball_X_speed = 1; players.ball_Y_speed = 1; players.ball_X_direction = changeDirection(); @@ -128,120 +130,120 @@ int32_t flipper_pong_app() gui_add_view_port(gui, view_port, GuiLayerFullscreen); NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - if (players.ball_X_direction == 0) notification_message(notification, &sequence_set_only_red_255); - else notification_message(notification, &sequence_set_only_blue_255); + if(players.ball_X_direction == 0) + notification_message(notification, &sequence_set_only_red_255); + else + notification_message(notification, &sequence_set_only_blue_255); FuriTimer* timer = furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, event_queue); - furi_timer_start(timer, 1000/FPS); + furi_timer_start(timer, 1000 / FPS); - while(1) - { + while(1) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); Players* playersMutex = (Players*)acquire_mutex_block(&state_mutex); - if (event_status == FuriStatusOk) - { - if(event.type == EventTypeInput) - { - if(event.input.key == InputKeyBack) - { + if(event_status == FuriStatusOk) { + if(event.type == EventTypeInput) { + if(event.input.key == InputKeyBack) { release_mutex(&state_mutex, playersMutex); notification_message(notification, &sequence_set_only_green_255); break; + } else if(event.input.key == InputKeyUp) { + if(playersMutex->player1_Y >= 1 + PLAYER1_PAD_SPEED) + playersMutex->player1_Y -= PLAYER1_PAD_SPEED; + else + playersMutex->player1_Y = 1; + } else if(event.input.key == InputKeyDown) { + if(playersMutex->player1_Y <= + SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER1_PAD_SPEED - 1) + playersMutex->player1_Y += PLAYER1_PAD_SPEED; + else + playersMutex->player1_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; } - else if(event.input.key == InputKeyUp) - { - if (playersMutex->player1_Y >= 1+PLAYER1_PAD_SPEED) playersMutex->player1_Y -= PLAYER1_PAD_SPEED; - else playersMutex->player1_Y = 1; - } - else if(event.input.key == InputKeyDown) - { - if (playersMutex->player1_Y <= SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER1_PAD_SPEED -1) playersMutex->player1_Y += PLAYER1_PAD_SPEED; - else playersMutex->player1_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; - } - } - else if (event.type == ClockEventTypeTick) - { - - if (playersMutex->ball_X + BALL_SIZE/2 <= SCREEN_SIZE_X*0.35 && playersMutex->ball_X_direction == 0) - { - if (playersMutex->ball_Y + BALL_SIZE/2 < playersMutex->player2_Y + PAD_SIZE_Y/2) - { - if (playersMutex->player2_Y >= 1+PLAYER2_PAD_SPEED) playersMutex->player2_Y -= PLAYER2_PAD_SPEED; - else playersMutex->player2_Y= 1; - } - else if (playersMutex->ball_Y + BALL_SIZE/2 > playersMutex->player2_Y + PAD_SIZE_Y/2) - { - if (playersMutex->player2_Y <= SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER2_PAD_SPEED -1) playersMutex->player2_Y += PLAYER2_PAD_SPEED; - else playersMutex->player2_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; + } else if(event.type == ClockEventTypeTick) { + if(playersMutex->ball_X + BALL_SIZE / 2 <= SCREEN_SIZE_X * 0.35 && + playersMutex->ball_X_direction == 0) { + if(playersMutex->ball_Y + BALL_SIZE / 2 < + playersMutex->player2_Y + PAD_SIZE_Y / 2) { + if(playersMutex->player2_Y >= 1 + PLAYER2_PAD_SPEED) + playersMutex->player2_Y -= PLAYER2_PAD_SPEED; + else + playersMutex->player2_Y = 1; + } else if( + playersMutex->ball_Y + BALL_SIZE / 2 > + playersMutex->player2_Y + PAD_SIZE_Y / 2) { + if(playersMutex->player2_Y <= + SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER2_PAD_SPEED - 1) + playersMutex->player2_Y += PLAYER2_PAD_SPEED; + else + playersMutex->player2_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; } } - uint8_t ball_corner_X[4] = {playersMutex->ball_X, playersMutex->ball_X + BALL_SIZE, playersMutex->ball_X + BALL_SIZE, playersMutex->ball_X}; - uint8_t ball_corner_Y[4] = {playersMutex->ball_Y, playersMutex->ball_Y, playersMutex->ball_Y + BALL_SIZE, playersMutex->ball_Y + BALL_SIZE}; + uint8_t ball_corner_X[4] = { + playersMutex->ball_X, + playersMutex->ball_X + BALL_SIZE, + playersMutex->ball_X + BALL_SIZE, + playersMutex->ball_X}; + uint8_t ball_corner_Y[4] = { + playersMutex->ball_Y, + playersMutex->ball_Y, + playersMutex->ball_Y + BALL_SIZE, + playersMutex->ball_Y + BALL_SIZE}; bool insidePlayer1 = false, insidePlayer2 = false; - for (int i=0;i<4;i++) - { - if (insidePad(ball_corner_X[i], ball_corner_Y[i], playersMutex->player1_X, playersMutex->player1_Y) == true) - { + for(int i = 0; i < 4; i++) { + if(insidePad( + ball_corner_X[i], + ball_corner_Y[i], + playersMutex->player1_X, + playersMutex->player1_Y) == true) { insidePlayer1 = true; break; } - if (insidePad(ball_corner_X[i], ball_corner_Y[i], playersMutex->player2_X, playersMutex->player2_Y) == true) - { + if(insidePad( + ball_corner_X[i], + ball_corner_Y[i], + playersMutex->player2_X, + playersMutex->player2_Y) == true) { insidePlayer2 = true; break; } } - if (insidePlayer1 == true) - { + if(insidePlayer1 == true) { playersMutex->ball_X_direction = 0; playersMutex->ball_X -= playersMutex->ball_X_speed; playersMutex->ball_X_speed = changeSpeed(); playersMutex->ball_Y_speed = changeSpeed(); notification_message(notification, &sequence_set_only_red_255); - } - else if (insidePlayer2 == true) - { + } else if(insidePlayer2 == true) { playersMutex->ball_X_direction = 1; playersMutex->ball_X += playersMutex->ball_X_speed; playersMutex->ball_X_speed = changeSpeed(); playersMutex->ball_Y_speed = changeSpeed(); notification_message(notification, &sequence_set_only_blue_255); - } - else - { - if (playersMutex->ball_X_direction == 1) - { - - if (playersMutex->ball_X <= SCREEN_SIZE_X - BALL_SIZE - 1 - playersMutex->ball_X_speed) - { + } else { + if(playersMutex->ball_X_direction == 1) { + if(playersMutex->ball_X <= + SCREEN_SIZE_X - BALL_SIZE - 1 - playersMutex->ball_X_speed) { playersMutex->ball_X += playersMutex->ball_X_speed; - } - else - { - playersMutex->ball_X = SCREEN_SIZE_X/2 - BALL_SIZE/2; - playersMutex->ball_Y = SCREEN_SIZE_Y/2 - BALL_SIZE/2; + } else { + playersMutex->ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; + playersMutex->ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; playersMutex->ball_X_speed = 1; playersMutex->ball_Y_speed = 1; playersMutex->ball_X_direction = 0; playersMutex->player2_score++; notification_message(notification, &sequence_set_only_red_255); } - } - else - { - if (playersMutex->ball_X >= 1 + playersMutex->ball_X_speed) - { + } else { + if(playersMutex->ball_X >= 1 + playersMutex->ball_X_speed) { playersMutex->ball_X -= playersMutex->ball_X_speed; - } - else - { - playersMutex->ball_X = SCREEN_SIZE_X/2 - BALL_SIZE/2; - playersMutex->ball_Y = SCREEN_SIZE_Y/2 - BALL_SIZE/2; + } else { + playersMutex->ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; + playersMutex->ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; playersMutex->ball_X_speed = 1; playersMutex->ball_Y_speed = 1; playersMutex->ball_X_direction = 1; @@ -251,28 +253,20 @@ int32_t flipper_pong_app() } } - if (playersMutex->ball_Y_direction == 1) - { - if (playersMutex->ball_Y <= SCREEN_SIZE_Y - BALL_SIZE - 1 - playersMutex->ball_Y_speed) - { + if(playersMutex->ball_Y_direction == 1) { + if(playersMutex->ball_Y <= + SCREEN_SIZE_Y - BALL_SIZE - 1 - playersMutex->ball_Y_speed) { playersMutex->ball_Y += playersMutex->ball_Y_speed; - } - else - { + } else { playersMutex->ball_Y = SCREEN_SIZE_Y - BALL_SIZE - 1; playersMutex->ball_X_speed = changeSpeed(); playersMutex->ball_Y_speed = changeSpeed(); playersMutex->ball_Y_direction = 0; } - } - else - { - if (playersMutex->ball_Y >= 1 + playersMutex->ball_Y_speed) - { + } else { + if(playersMutex->ball_Y >= 1 + playersMutex->ball_Y_speed) { playersMutex->ball_Y -= playersMutex->ball_Y_speed; - } - else - { + } else { playersMutex->ball_Y = 1; playersMutex->ball_X_speed = changeSpeed(); playersMutex->ball_Y_speed = changeSpeed(); @@ -286,6 +280,7 @@ int32_t flipper_pong_app() view_port_update(view_port); } + notification_message(notification, &sequence_reset_rgb); furi_message_queue_free(event_queue); delete_mutex(&state_mutex); gui_remove_view_port(gui, view_port); diff --git a/flipper_pong/pong.png b/pong.png similarity index 100% rename from flipper_pong/pong.png rename to pong.png