diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 71acb5f14..000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,91 +0,0 @@ -# Who owns all the fish by default -* @skotopes @DrZlo13 @hedger - -# Apps -/applications/about/ @skotopes @DrZlo13 @hedger -/applications/accessor/ @skotopes @DrZlo13 @hedger -/applications/archive/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/bad_usb/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/bt/ @skotopes @DrZlo13 @hedger @gornekich -/applications/cli/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/crypto/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/debug_tools/ @skotopes @DrZlo13 @hedger -/applications/desktop/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/dialogs/ @skotopes @DrZlo13 @hedger -/applications/dolphin/ @skotopes @DrZlo13 @hedger -/applications/gpio/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/gui/ @skotopes @DrZlo13 @hedger -/applications/ibutton/ @skotopes @DrZlo13 @hedger @gsurkov -/applications/infrared/ @skotopes @DrZlo13 @hedger @gsurkov -/applications/infrared_monitor/ @skotopes @DrZlo13 @hedger @gsurkov -/applications/input/ @skotopes @DrZlo13 @hedger -/applications/lfrfid/ @skotopes @DrZlo13 @hedger -/applications/lfrfid_debug/ @skotopes @DrZlo13 @hedger -/applications/loader/ @skotopes @DrZlo13 @hedger -/applications/music_player/ @skotopes @DrZlo13 @hedger -/applications/nfc/ @skotopes @DrZlo13 @hedger @gornekich -/applications/notification/ @skotopes @DrZlo13 @hedger -/applications/power/ @skotopes @DrZlo13 @hedger -/applications/rpc/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/snake_game/ @skotopes @DrZlo13 @hedger -/applications/storage/ @skotopes @DrZlo13 @hedger -/applications/storage_settings/ @skotopes @DrZlo13 @hedger -/applications/subghz/ @skotopes @DrZlo13 @hedger @Skorpionm -/applications/system/ @skotopes @DrZlo13 @hedger -/applications/u2f/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/unit_tests/ @skotopes @DrZlo13 @hedger -/applications/updater/ @skotopes @DrZlo13 @hedger - -# Assets -/assets/ @skotopes @DrZlo13 @hedger - -# Furi Core -/furi/ @skotopes @DrZlo13 @hedger - -# Debug tools and plugins -/debug/ @skotopes @DrZlo13 @hedger - -# Docker -/docker/ @skotopes @DrZlo13 @hedger @aprosvetova -/docker-compose.yml @skotopes @DrZlo13 @hedger @aprosvetova - -# Documentation -/documentation/ @skotopes @DrZlo13 @hedger @aprosvetova - -# Firmware targets -/firmware/ @skotopes @DrZlo13 @hedger - -# Lib -/lib/FreeRTOS-Kernel/ @skotopes @DrZlo13 @hedger -/lib/FreeRTOS-glue/ @skotopes @DrZlo13 @hedger -/lib/ST25RFAL002/ @skotopes @DrZlo13 @hedger @gornekich -/lib/STM32CubeWB/ @skotopes @DrZlo13 @hedger @gornekich -/lib/app-scened-template/ @skotopes @DrZlo13 @hedger -/lib/callback-connector/ @skotopes @DrZlo13 @hedger -/lib/digital_signal/ @skotopes @DrZlo13 @hedger @gornekich -/lib/drivers/ @skotopes @DrZlo13 @hedger -/lib/fatfs/ @skotopes @DrZlo13 @hedger -/lib/flipper_format/ @skotopes @DrZlo13 @hedger -/lib/fnv1a-hash/ @skotopes @DrZlo13 @hedger -/lib/heatshrink/ @skotopes @DrZlo13 @hedger -/lib/infrared/ @skotopes @DrZlo13 @hedger @gsurkov -/lib/libusb_stm32/ @skotopes @DrZlo13 @hedger @nminaylov -/lib/littlefs/ @skotopes @DrZlo13 @hedger -/lib/lfs_config.h @skotopes @DrZlo13 @hedger -/lib/micro-ecc/ @skotopes @DrZlo13 @hedger @nminaylov -/lib/microtar/ @skotopes @DrZlo13 @hedger -/lib/mlib/ @skotopes @DrZlo13 @hedger -/lib/nanopb/ @skotopes @DrZlo13 @hedger -/lib/nfc/ @skotopes @DrZlo13 @hedger @gornekich -/lib/one_wire/ @skotopes @DrZlo13 @hedger -/lib/qrcode/ @skotopes @DrZlo13 @hedger -/lib/subghz/ @skotopes @DrZlo13 @hedger @Skorpionm -/lib/toolbox/ @skotopes @DrZlo13 @hedger -/lib/u8g2/ @skotopes @DrZlo13 @hedger -/lib/update_util/ @skotopes @DrZlo13 @hedger - -# Make tools -/make/ @skotopes @DrZlo13 @hedger @aprosvetova - -# Helper scripts -/scripts/ @skotopes @DrZlo13 @hedger diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml index 844d62c48..a5a8b9828 100644 --- a/.github/ISSUE_TEMPLATE/01_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/01_bug_report.yml @@ -1,46 +1,45 @@ name: Bug report description: File a bug reports regarding the firmware. -labels: ['bug'] +labels: ["bug"] body: -- type: markdown - attributes: - value: | - Thank you for taking the time to fill out an issue, this template is meant for any issues related to the Flipper Zero firmware. - If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) -- type: textarea - id: description - attributes: - label: Describe the bug. - description: "A clear and concise description of what the bug is." - validations: - required: true -- type: textarea - id: repro - attributes: - label: Reproduction - description: "How can this bug be reproduced?" - placeholder: | - 1. Switch on... - 2. Press button '....' - 3. Wait for the moon phase - 4. It burns - validations: - required: true -- type: input - id: target - attributes: - label: Target - description: Specify the target - # Target seems to be largely ignored by outside sources. -- type: textarea - id: logs - attributes: - label: Logs - description: Attach your debug logs here - render: Text - # Avoid rendering as Markdown here. -- type: textarea - id: anything-else - attributes: - label: Anything else? - description: Let us know if you have anything else to share. + - type: markdown + attributes: + value: | + Thank you for taking the time to fill out an issue, this template is meant for any issues related to the Flipper Zero unleashed firmware. + - type: textarea + id: description + attributes: + label: Describe the bug. + description: "A clear and concise description of what the bug is." + validations: + required: true + - type: textarea + id: repro + attributes: + label: Reproduction + description: "How can this bug be reproduced?" + placeholder: | + 1. Switch on... + 2. Press button '....' + 3. Wait for the moon phase + 4. It burns + validations: + required: true + - type: input + id: target + attributes: + label: Target + description: Specify the target + # Target seems to be largely ignored by outside sources. + - type: textarea + id: logs + attributes: + label: Logs + description: Attach your debug logs here + render: Text + # Avoid rendering as Markdown here. + - type: textarea + id: anything-else + attributes: + label: Anything else? + description: Let us know if you have anything else to share. diff --git a/.github/ISSUE_TEMPLATE/02_enhancements.yml b/.github/ISSUE_TEMPLATE/02_enhancements.yml index 1768e193c..643d11cfb 100644 --- a/.github/ISSUE_TEMPLATE/02_enhancements.yml +++ b/.github/ISSUE_TEMPLATE/02_enhancements.yml @@ -1,21 +1,20 @@ name: Enhancements description: Suggest improvements for any existing functionality within the firmware. body: -- type: markdown - attributes: - value: | - Thank you for taking the time to fill out an issue. This template is meant for feature requests and improvements to already existing functionality. - If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) -- type: textarea - id: proposal - attributes: - label: "Describe the enhancement you're suggesting." - description: | - Feel free to describe in as much detail as you wish. - validations: - required: true -- type: textarea - id: anything-else - attributes: - label: Anything else? - description: Let us know if you have anything else to share. + - type: markdown + attributes: + value: | + Thank you for taking the time to fill out an issue. This template is meant for feature requests and improvements to already existing functionality. + - type: textarea + id: proposal + attributes: + label: "Describe the enhancement you're suggesting." + description: | + Feel free to describe in as much detail as you wish. + validations: + required: true + - type: textarea + id: anything-else + attributes: + label: Anything else? + description: Let us know if you have anything else to share. diff --git a/.github/ISSUE_TEMPLATE/03_feature_request.yml b/.github/ISSUE_TEMPLATE/03_feature_request.yml index 2af114547..91100bce3 100644 --- a/.github/ISSUE_TEMPLATE/03_feature_request.yml +++ b/.github/ISSUE_TEMPLATE/03_feature_request.yml @@ -1,24 +1,23 @@ name: Feature Request description: For feature requests regarding the firmware. -labels: ['feature request'] +labels: ["feature request"] body: -- type: markdown - attributes: - value: | - Thank you for taking the time to fill out an issue, this template is meant for any feature suggestions. - If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) -- type: textarea - id: proposal - attributes: - label: "Description of the feature you're suggesting." - description: | - Please describe your feature request in as many details as possible. - - Describe what it should do. - - Note whetever it is to extend existing functionality or introduce new functionality. - validations: - required: true -- type: textarea - id: anything-else - attributes: - label: Anything else? - description: Let us know if you have anything else to share. + - type: markdown + attributes: + value: | + Thank you for taking the time to fill out an issue, this template is meant for any feature suggestions. + - type: textarea + id: proposal + attributes: + label: "Description of the feature you're suggesting." + description: | + Please describe your feature request in as many details as possible. + - Describe what it should do. + - Note whetever it is to extend existing functionality or introduce new functionality. + validations: + required: true + - type: textarea + id: anything-else + attributes: + label: Anything else? + description: Let us know if you have anything else to share. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 55ff9d29e..2c7ccdfda 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,8 @@ blank_issues_enabled: true contact_links: - - name: Need help? - url: https://forum.flipperzero.one - about: For any question regarding on how to use the Flipper Zero and its firmware. + - name: Telegram + url: https://t.me/flipperzero_unofficial + about: Unofficial Telegram chat + - name: Discord + url: https://discord.gg/58D6E8BtTU + about: Unofficial Discord Community diff --git a/applications/arkanoid/application.fam b/applications/arkanoid/application.fam index fc7aeee4a..1d43561fd 100644 --- a/applications/arkanoid/application.fam +++ b/applications/arkanoid/application.fam @@ -5,6 +5,6 @@ App( entry_point="arkanoid_game_app", cdefines=["APP_ARKANOID_GAME"], requires=["gui"], - stack_size=1 * 1024, + stack_size=3 * 1024, order=30, ) diff --git a/applications/arkanoid/arkanoid_game.c b/applications/arkanoid/arkanoid_game.c index 152bf0fcb..27dd13c24 100644 --- a/applications/arkanoid/arkanoid_game.c +++ b/applications/arkanoid/arkanoid_game.c @@ -3,61 +3,53 @@ #include #include #include +#include +#include #define TAG "Arkanoid" -unsigned int COLUMNS = 13; //Columns of bricks -unsigned int ROWS = 4; //Rows of bricks -int dx = -1; //Initial movement of ball -int dy = -1; //Initial movement of ball -int xb; //Balls starting possition -int yb; //Balls starting possition -bool released; //If the ball has been released by the player -bool paused = false; //If the game has been paused -int xPaddle; //X position of paddle -bool isHit[4][13]; //Array of if bricks are hit or not -bool bounced = false; //Used to fix double bounce glitch -int lives = 3; //Amount of lives -int level = 1; //Current level -unsigned int score = 0; //Score for the game -unsigned int brickCount; //Amount of bricks hit -int pad1, pad2, pad3; //Button press buffer used to stop pause repeating -int oldpad, oldpad2, oldpad3; -char text[16]; //General string buffer -bool start = false; //If in menu or in game -bool initialDraw = false; //If the inital draw has happened -char initials[3]; //Initials used in high score - -//Ball Bounds used in collision detection -int leftBall; -int rightBall; -int topBall; -int bottomBall; - -//Brick Bounds used in collision detection -int leftBrick; -int rightBrick; -int topBrick; -int bottomBrick; - -int tick; - #define FLIPPER_LCD_WIDTH 128 #define FLIPPER_LCD_HEIGHT 64 typedef enum { EventTypeTick, EventTypeKey } EventType; -typedef enum { DirectionUp, DirectionRight, DirectionDown, DirectionLeft } Direction; - -typedef enum { GameStatePlaying, GameStateGameOver } GameState; +typedef struct { + //Brick Bounds used in collision detection + int leftBrick; + int rightBrick; + int topBrick; + int bottomBrick; + bool isHit[4][13]; //Array of if bricks are hit or not +} BrickState; typedef struct { - int x; - int y; -} Point; + int dx; //Initial movement of ball + int dy; //Initial movement of ball + int xb; //Balls starting possition + int yb; //Balls starting possition + bool released; //If the ball has been released by the player + //Ball Bounds used in collision detection + int leftBall; + int rightBall; + int topBall; + int bottomBall; +} BallState; typedef struct { - GameState game_state; + BallState ball_state; + BrickState brick_state; + NotificationApp* notify; + unsigned int COLUMNS; //Columns of bricks + unsigned int ROWS; //Rows of bricks + bool initialDraw; //If the inital draw has happened + int xPaddle; //X position of paddle + char text[16]; //General string buffer + bool bounced; //Used to fix double bounce glitch + int lives; //Amount of lives + int level; //Current level + unsigned int score; //Score for the game + unsigned int brickCount; //Amount of bricks hit + int tick; //Tick counter } ArkanoidState; typedef struct { @@ -65,128 +57,128 @@ typedef struct { InputEvent input; } GameEvent; +static const NotificationSequence sequence_short_sound = { + &message_note_c5, + &message_delay_50, + &message_sound_off, + NULL, +}; + // generate number in range [min,max) int rand_range(int min, int max) { int number = min + rand() % (max - min); return number; } -void intro(Canvas* canvas) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 46, 0, "Arkanoid"); - - //arduboy.tunes.tone(987, 160); - //delay(160); - //arduboy.tunes.tone(1318, 400); - //delay(2000); -} - -void move_ball(Canvas* canvas) { - tick++; - if(released) { +void move_ball(Canvas* canvas, ArkanoidState* st) { + st->tick++; + if(st->ball_state.released) { //Move ball - if(abs(dx) == 2) { - xb += dx / 2; + if(abs(st->ball_state.dx) == 2) { + st->ball_state.xb += st->ball_state.dx / 2; // 2x speed is really 1.5 speed - if(tick % 2 == 0) xb += dx / 2; + if(st->tick % 2 == 0) st->ball_state.xb += st->ball_state.dx / 2; } else { - xb += dx; + st->ball_state.xb += st->ball_state.dx; } - yb = yb + dy; + st->ball_state.yb = st->ball_state.yb + st->ball_state.dy; //Set bounds - leftBall = xb; - rightBall = xb + 2; - topBall = yb; - bottomBall = yb + 2; + st->ball_state.leftBall = st->ball_state.xb; + st->ball_state.rightBall = st->ball_state.xb + 2; + st->ball_state.topBall = st->ball_state.yb; + st->ball_state.bottomBall = st->ball_state.yb + 2; //Bounce off top edge - if(yb <= 0) { - yb = 2; - dy = -dy; - // arduboy.tunes.tone(523, 250); + if(st->ball_state.yb <= 0) { + st->ball_state.yb = 2; + st->ball_state.dy = -st->ball_state.dy; } //Lose a life if bottom edge hit - if(yb >= FLIPPER_LCD_HEIGHT) { - canvas_draw_frame(canvas, xPaddle, FLIPPER_LCD_HEIGHT - 1, 11, 1); - xPaddle = 54; - yb = 60; - released = false; - lives--; + if(st->ball_state.yb >= FLIPPER_LCD_HEIGHT) { + canvas_draw_frame(canvas, st->xPaddle, FLIPPER_LCD_HEIGHT - 1, 11, 1); + st->xPaddle = 54; + st->ball_state.yb = 60; + st->ball_state.released = false; + st->lives--; - // arduboy.tunes.tone(175, 250); if(rand_range(0, 2) == 0) { - dx = 1; + st->ball_state.dx = 1; } else { - dx = -1; + st->ball_state.dx = -1; } } //Bounce off left side - if(xb <= 0) { - xb = 2; - dx = -dx; - // arduboy.tunes.tone(523, 250); + if(st->ball_state.xb <= 0) { + st->ball_state.xb = 2; + st->ball_state.dx = -st->ball_state.dx; } //Bounce off right side - if(xb >= FLIPPER_LCD_WIDTH - 2) { - xb = FLIPPER_LCD_WIDTH - 4; - dx = -dx; + if(st->ball_state.xb >= FLIPPER_LCD_WIDTH - 2) { + st->ball_state.xb = FLIPPER_LCD_WIDTH - 4; + st->ball_state.dx = -st->ball_state.dx; // arduboy.tunes.tone(523, 250); } //Bounce off paddle - if(xb + 1 >= xPaddle && xb <= xPaddle + 12 && yb + 2 >= FLIPPER_LCD_HEIGHT - 1 && - yb <= FLIPPER_LCD_HEIGHT) { - dy = -dy; - dx = ((xb - (xPaddle + 6)) / 3); //Applies spin on the ball - // prevent straight bounce - if(dx == 0) { - dx = (rand_range(0, 2) == 1) ? 1 : -1; + if(st->ball_state.xb + 1 >= st->xPaddle && st->ball_state.xb <= st->xPaddle + 12 && + st->ball_state.yb + 2 >= FLIPPER_LCD_HEIGHT - 1 && + st->ball_state.yb <= FLIPPER_LCD_HEIGHT) { + st->ball_state.dy = -st->ball_state.dy; + st->ball_state.dx = + ((st->ball_state.xb - (st->xPaddle + 6)) / 3); //Applies spin on the ball + // prevent straight bounce, but not prevent roguuemaster from stealing + if(st->ball_state.dx == 0) { + st->ball_state.dx = (rand_range(0, 2) == 1) ? 1 : -1; } - // arduboy.tunes.tone(200, 250); } //Bounce off Bricks - for(unsigned int row = 0; row < ROWS; row++) { - for(unsigned int column = 0; column < COLUMNS; column++) { - if(!isHit[row][column]) { + for(unsigned int row = 0; row < st->ROWS; row++) { + for(unsigned int column = 0; column < st->COLUMNS; column++) { + if(!st->brick_state.isHit[row][column]) { //Sets Brick bounds - leftBrick = 10 * column; - rightBrick = 10 * column + 10; - topBrick = 6 * row + 1; - bottomBrick = 6 * row + 7; + st->brick_state.leftBrick = 10 * column; + st->brick_state.rightBrick = 10 * column + 10; + st->brick_state.topBrick = 6 * row + 1; + st->brick_state.bottomBrick = 6 * row + 7; //If A collison has occured - if(topBall <= bottomBrick && bottomBall >= topBrick && - leftBall <= rightBrick && rightBall >= leftBrick) { - score += (level * 10); + if(st->ball_state.topBall <= st->brick_state.bottomBrick && + st->ball_state.bottomBall >= st->brick_state.topBrick && + st->ball_state.leftBall <= st->brick_state.rightBrick && + st->ball_state.rightBall >= st->brick_state.leftBrick) { + st->score += st->level; + // Blink led when we hit some brick + notification_message(st->notify, &sequence_short_sound); + notification_message(st->notify, &sequence_blink_white_100); - brickCount++; - isHit[row][column] = true; + st->brickCount++; + st->brick_state.isHit[row][column] = true; canvas_draw_frame(canvas, 10 * column, 2 + 6 * row, 8, 4); //Vertical collision - if(bottomBall > bottomBrick || topBall < topBrick) { + if(st->ball_state.bottomBall > st->brick_state.bottomBrick || + st->ball_state.topBall < st->brick_state.topBrick) { //Only bounce once each ball move - if(!bounced) { - dy = -dy; - yb += dy; - bounced = true; - // arduboy.tunes.tone(261, 250); + if(!st->bounced) { + st->ball_state.dy = -st->ball_state.dy; + st->ball_state.yb += st->ball_state.dy; + st->bounced = true; } } //Hoizontal collision - if(leftBall < leftBrick || rightBall > rightBrick) { + if(st->ball_state.leftBall < st->brick_state.leftBrick || + st->ball_state.rightBall > st->brick_state.rightBrick) { //Only bounce once brick each ball move - if(!bounced) { - dx = -dx; - xb += dx; - bounced = true; - // arduboy.tunes.tone(261, 250); + if(!st->bounced) { + st->ball_state.dx = -st->ball_state.dx; + st->ball_state.xb += st->ball_state.dx; + st->bounced = true; } } } @@ -195,15 +187,15 @@ void move_ball(Canvas* canvas) { } //Reset Bounce - bounced = false; + st->bounced = false; } else { //Ball follows paddle - xb = xPaddle + 5; + st->ball_state.xb = st->xPaddle + 5; } } -void draw_lives(Canvas* canvas) { - if(lives == 3) { +void draw_lives(Canvas* canvas, ArkanoidState* arkanoid_state) { + if(arkanoid_state->lives == 3) { canvas_draw_dot(canvas, 4, FLIPPER_LCD_HEIGHT - 7); canvas_draw_dot(canvas, 3, FLIPPER_LCD_HEIGHT - 7); canvas_draw_dot(canvas, 4, FLIPPER_LCD_HEIGHT - 8); @@ -218,7 +210,7 @@ void draw_lives(Canvas* canvas) { canvas_draw_dot(canvas, 3, FLIPPER_LCD_HEIGHT - 15); canvas_draw_dot(canvas, 4, FLIPPER_LCD_HEIGHT - 16); canvas_draw_dot(canvas, 3, FLIPPER_LCD_HEIGHT - 16); - } else if(lives == 2) { + } else if(arkanoid_state->lives == 2) { canvas_draw_dot(canvas, 4, FLIPPER_LCD_HEIGHT - 7); canvas_draw_dot(canvas, 3, FLIPPER_LCD_HEIGHT - 7); canvas_draw_dot(canvas, 4, FLIPPER_LCD_HEIGHT - 8); @@ -236,98 +228,115 @@ void draw_lives(Canvas* canvas) { } } -void draw_score(Canvas* canvas) { - snprintf(text, sizeof(text), "%u", score); - canvas_draw_str_aligned(canvas, FLIPPER_LCD_WIDTH - 2, FLIPPER_LCD_HEIGHT - 6, AlignRight, AlignBottom, text); +void draw_score(Canvas* canvas, ArkanoidState* arkanoid_state) { + snprintf(arkanoid_state->text, sizeof(arkanoid_state->text), "%u", arkanoid_state->score); + canvas_draw_str_aligned( + canvas, + FLIPPER_LCD_WIDTH - 2, + FLIPPER_LCD_HEIGHT - 6, + AlignRight, + AlignBottom, + arkanoid_state->text); } -void draw_ball(Canvas* canvas) { - canvas_draw_dot(canvas, xb, yb); - canvas_draw_dot(canvas, xb + 1, yb); - canvas_draw_dot(canvas, xb, yb + 1); - canvas_draw_dot(canvas, xb + 1, yb + 1); +void draw_ball(Canvas* canvas, ArkanoidState* ast) { + canvas_draw_dot(canvas, ast->ball_state.xb, ast->ball_state.yb); + canvas_draw_dot(canvas, ast->ball_state.xb + 1, ast->ball_state.yb); + canvas_draw_dot(canvas, ast->ball_state.xb, ast->ball_state.yb + 1); + canvas_draw_dot(canvas, ast->ball_state.xb + 1, ast->ball_state.yb + 1); - move_ball(canvas); + move_ball(canvas, ast); } -void draw_paddle(Canvas* canvas) { - canvas_draw_frame(canvas, xPaddle, FLIPPER_LCD_HEIGHT - 1, 11, 1); +void draw_paddle(Canvas* canvas, ArkanoidState* arkanoid_state) { + canvas_draw_frame(canvas, arkanoid_state->xPaddle, FLIPPER_LCD_HEIGHT - 1, 11, 1); } -void reset_level(Canvas* canvas) { +void reset_level(Canvas* canvas, ArkanoidState* arkanoid_state) { //Undraw paddle - canvas_draw_frame(canvas, xPaddle, FLIPPER_LCD_HEIGHT - 1, 11, 1); + canvas_draw_frame(canvas, arkanoid_state->xPaddle, FLIPPER_LCD_HEIGHT - 1, 11, 1); //Undraw ball - canvas_draw_dot(canvas, xb, yb); - canvas_draw_dot(canvas, xb + 1, yb); - canvas_draw_dot(canvas, xb, yb + 1); - canvas_draw_dot(canvas, xb + 1, yb + 1); + canvas_draw_dot(canvas, arkanoid_state->ball_state.xb, arkanoid_state->ball_state.yb); + canvas_draw_dot(canvas, arkanoid_state->ball_state.xb + 1, arkanoid_state->ball_state.yb); + canvas_draw_dot(canvas, arkanoid_state->ball_state.xb, arkanoid_state->ball_state.yb + 1); + canvas_draw_dot(canvas, arkanoid_state->ball_state.xb + 1, arkanoid_state->ball_state.yb + 1); //Alter various variables to reset the game - xPaddle = 54; - yb = 60; - brickCount = 0; - released = false; + arkanoid_state->xPaddle = 54; + arkanoid_state->ball_state.yb = 60; + arkanoid_state->brickCount = 0; + arkanoid_state->ball_state.released = false; // Reset all brick hit states - for(unsigned int row = 0; row < ROWS; row++) { - for(unsigned int column = 0; column < COLUMNS; column++) { - isHit[row][column] = false; + for(unsigned int row = 0; row < arkanoid_state->ROWS; row++) { + for(unsigned int column = 0; column < arkanoid_state->COLUMNS; column++) { + arkanoid_state->brick_state.isHit[row][column] = false; } } } -static void arkanoid_state_init(ArkanoidState* const arkanoid_state) { +static void arkanoid_state_init(ArkanoidState* arkanoid_state) { + // Init notification + arkanoid_state->notify = furi_record_open(RECORD_NOTIFICATION); + // Set the initial game state - arkanoid_state->game_state = GameStatePlaying; + arkanoid_state->COLUMNS = 13; + arkanoid_state->ROWS = 4; + arkanoid_state->ball_state.dx = -1; + arkanoid_state->ball_state.dy = -1; + arkanoid_state->bounced = false; + arkanoid_state->lives = 3; + arkanoid_state->level = 1; + arkanoid_state->score = 0; + arkanoid_state->COLUMNS = 13; + arkanoid_state->COLUMNS = 13; // Reset initial state - initialDraw = false; + arkanoid_state->initialDraw = false; } static void arkanoid_draw_callback(Canvas* const canvas, void* ctx) { - const ArkanoidState* arkanoid_state = acquire_mutex((ValueMutex*)ctx, 25); + ArkanoidState* arkanoid_state = acquire_mutex((ValueMutex*)ctx, 25); if(arkanoid_state == NULL) { return; } //Initial level draw - if(!initialDraw) { - initialDraw = true; + if(!arkanoid_state->initialDraw) { + arkanoid_state->initialDraw = true; // Set default font for text - canvas_set_font(canvas, FontPrimary); + canvas_set_font(canvas, FontSecondary); //Draws the new level - reset_level(canvas); + reset_level(canvas, arkanoid_state); } //Draws new bricks and resets their values - for(unsigned int row = 0; row < ROWS; row++) { - for(unsigned int column = 0; column < COLUMNS; column++) { - if(!isHit[row][column]) { + for(unsigned int row = 0; row < arkanoid_state->ROWS; row++) { + for(unsigned int column = 0; column < arkanoid_state->COLUMNS; column++) { + if(!arkanoid_state->brick_state.isHit[row][column]) { canvas_draw_frame(canvas, 10 * column, 2 + 6 * row, 8, 4); } } } - if(lives > 0) { - draw_paddle(canvas); - draw_ball(canvas); - draw_score(canvas); - draw_lives(canvas); + if(arkanoid_state->lives > 0) { + draw_paddle(canvas, arkanoid_state); + draw_ball(canvas, arkanoid_state); + draw_score(canvas, arkanoid_state); + draw_lives(canvas, arkanoid_state); - if(brickCount == ROWS * COLUMNS) { - level++; - reset_level(canvas); + if(arkanoid_state->brickCount == arkanoid_state->ROWS * arkanoid_state->COLUMNS) { + arkanoid_state->level++; + reset_level(canvas, arkanoid_state); } } else { - reset_level(canvas); - initialDraw = false; - start = false; - lives = 3; - score = 0; + reset_level(canvas, arkanoid_state); + arkanoid_state->initialDraw = false; + arkanoid_state->lives = 3; + arkanoid_state->score = 0; } release_mutex((ValueMutex*)ctx, arkanoid_state); @@ -375,7 +384,7 @@ int32_t arkanoid_game_app(void* p) { furi_timer_start(timer, furi_kernel_get_tick_frequency() / 22); // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); GameEvent event; @@ -393,13 +402,13 @@ int32_t arkanoid_game_app(void* p) { processing = false; break; case InputKeyRight: - if(xPaddle < FLIPPER_LCD_WIDTH - 12) { - xPaddle += 8; + if(arkanoid_state->xPaddle < FLIPPER_LCD_WIDTH - 12) { + arkanoid_state->xPaddle += 8; } break; case InputKeyLeft: - if(xPaddle > 0) { - xPaddle -= 8; + if(arkanoid_state->xPaddle > 0) { + arkanoid_state->xPaddle -= 8; } break; case InputKeyUp: @@ -408,24 +417,24 @@ int32_t arkanoid_game_app(void* p) { break; case InputKeyOk: //Release ball if FIRE pressed - released = true; + arkanoid_state->ball_state.released = true; //Apply random direction to ball on release if(rand_range(0, 2) == 0) { - dx = 1; + arkanoid_state->ball_state.dx = 1; } else { - dx = -1; + arkanoid_state->ball_state.dx = -1; } //Makes sure the ball heads upwards - dy = -1; + arkanoid_state->ball_state.dy = -1; break; } } } } else { // Event timeout - FURI_LOG_D(TAG, "osMessageQueue: Event timeout"); + FURI_LOG_D(TAG, "furi_message_queue: Event timeout"); } view_port_update(view_port); @@ -434,7 +443,8 @@ int32_t arkanoid_game_app(void* p) { furi_timer_free(timer); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); view_port_free(view_port); delete_mutex(&state_mutex); diff --git a/applications/snake_game/snake_game.c b/applications/snake_game/snake_game.c index 9ad18c632..dfb2716d5 100644 --- a/applications/snake_game/snake_game.c +++ b/applications/snake_game/snake_game.c @@ -61,6 +61,15 @@ typedef struct { InputEvent input; } SnakeEvent; +static const NotificationSequence sequence_short_vibro_and_sound = { + &message_vibro_on, + &message_note_c5, + &message_delay_50, + &message_sound_off, + &message_vibro_off, + NULL, +}; + static void snake_game_render_callback(Canvas* const canvas, void* ctx) { const SnakeState* snake_state = acquire_mutex((ValueMutex*)ctx, 25); if(snake_state == NULL) { @@ -238,7 +247,7 @@ static void snake_game_move_snake(SnakeState* const snake_state, Point const nex snake_state->points[0] = next_step; } -static void snake_game_process_game_step(SnakeState* const snake_state) { +static void snake_game_process_game_step(SnakeState* const snake_state, NotificationApp* notify) { if(snake_state->state == GameStateGameOver) { return; } @@ -273,10 +282,8 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { bool eatFruit = (next_step.x == snake_state->fruit.x) && (next_step.y == snake_state->fruit.y); if(eatFruit) { - NotificationApp* notification = furi_record_open("notification"); - notification_message(notification, &sequence_single_vibro); - notification_message(notification, &sequence_blink_white_100); - furi_record_close("notification"); + notification_message(notify, &sequence_short_vibro_and_sound); + notification_message(notify, &sequence_blink_white_100); snake_state->len++; if(snake_state->len >= MAX_SNAKE_LEN) { @@ -320,6 +327,8 @@ int32_t snake_game_app(void* p) { Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + SnakeEvent event; for(bool processing = true; processing;) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); @@ -354,7 +363,7 @@ int32_t snake_game_app(void* p) { } } } else if(event.type == EventTypeTick) { - snake_game_process_game_step(snake_state); + snake_game_process_game_step(snake_state, notification); } } else { // event timeout @@ -368,6 +377,7 @@ int32_t snake_game_app(void* p) { view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); view_port_free(view_port); furi_message_queue_free(event_queue); delete_mutex(&state_mutex); diff --git a/applications/tetris_game/application.fam b/applications/tetris_game/application.fam index 406e13eac..496662b30 100644 --- a/applications/tetris_game/application.fam +++ b/applications/tetris_game/application.fam @@ -5,6 +5,6 @@ App( entry_point="tetris_game_app", cdefines=["APP_TETRIS_GAME"], requires=["gui"], - stack_size=1 * 1024, + stack_size=2 * 1024, order=20, )