From 7c09807aebe22cfc28e401af5936c0ca9f6c9c7a Mon Sep 17 00:00:00 2001 From: RogueMaster Date: Thu, 17 Nov 2022 23:37:29 -0500 Subject: [PATCH] blackjack upd --- .../plugins/blackjack/application.fam | 6 +- .../blackjack/assets/card_graphics.png | Bin 0 -> 409 bytes applications/plugins/blackjack/blackjack.c | 635 ++++++++---------- applications/plugins/blackjack/common/card.c | 392 +++++++---- applications/plugins/blackjack/common/card.h | 118 +++- applications/plugins/blackjack/common/dml.c | 27 +- applications/plugins/blackjack/common/dml.h | 4 + applications/plugins/blackjack/common/menu.c | 90 ++- applications/plugins/blackjack/common/menu.h | 29 +- applications/plugins/blackjack/common/queue.c | 55 +- applications/plugins/blackjack/common/queue.h | 36 +- applications/plugins/blackjack/common/ui.c | 216 ++++++ applications/plugins/blackjack/common/ui.h | 58 ++ applications/plugins/blackjack/defines.h | 15 +- applications/plugins/blackjack/ui.c | 154 ++--- applications/plugins/blackjack/ui.h | 16 +- applications/plugins/blackjack/util.c | 52 +- 17 files changed, 1145 insertions(+), 758 deletions(-) create mode 100644 applications/plugins/blackjack/assets/card_graphics.png create mode 100644 applications/plugins/blackjack/common/ui.c create mode 100644 applications/plugins/blackjack/common/ui.h diff --git a/applications/plugins/blackjack/application.fam b/applications/plugins/blackjack/application.fam index a290a3f74..fda93eb61 100644 --- a/applications/plugins/blackjack/application.fam +++ b/applications/plugins/blackjack/application.fam @@ -1,10 +1,10 @@ App( - appid="BlackJack", - name="BlackJack", + appid="blackjack", + name="Blackjack", apptype=FlipperAppType.EXTERNAL, entry_point="blackjack_app", cdefines=["APP_BLACKJACK"], - requires=["gui","storage"], + requires=["gui","storage","canvas"], stack_size=2 * 1024, order=30, fap_icon="blackjack_10px.png", diff --git a/applications/plugins/blackjack/assets/card_graphics.png b/applications/plugins/blackjack/assets/card_graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..8b00e351fae43c2ee425b8445cc19f642eb95812 GIT binary patch literal 409 zcmV;K0cQS*P)Px$Q%OWYR7i=%R?89tAqWG<|NmusprtekbbIM?*iqyWAUf;k9CtUfbB>wCI=3Nd zkf&e|zMV0MyGy;9?L3P`+JU}vH`1-1@>YgochGRI-4)H10h(B| zu?)rikl@mNhYz!-W=#V~0KAmRK+~04F`1bkqP(mdn%5c6D6h*(rq>F9=Af6x^3-1f zL5A%URz$fnekt74ZgADU;s&o+tZ=(d4uHb%6NF*|d6@v*Hbn?_24XTYSs2`#s+{HB zt&Xj%;ir{>eoZXlre_D_j|PV6WL%OHRp!4I>_|q!^r> z=1*6(z84Z7Kc`qgR-c`O1<-b2v9y7hT^W!Oe-q>z!=01&K$^jK=yvNbnTDWEt0U-ExF~o%D-WCQ~}Km-Ad{Hoy_b3ZonT2xiD0D00000NkvXXu0mjf DEMm7A literal 0 HcmV?d00001 diff --git a/applications/plugins/blackjack/blackjack.c b/applications/plugins/blackjack/blackjack.c index 14d950b46..db1e7d677 100644 --- a/applications/plugins/blackjack/blackjack.c +++ b/applications/plugins/blackjack/blackjack.c @@ -3,6 +3,8 @@ #include #include #include +#include + #include #include "util.h" #include "defines.h" @@ -12,74 +14,76 @@ #include "util.h" #include "ui.h" -#include "BlackJack_icons.h" +#include "blackjack_icons.h" #define DEALER_MAX 17 -void start_round(GameState* game_state); +void start_round(GameState *game_state); -void init(GameState* game_state); +void init(GameState *game_state); + +static void draw_ui(Canvas *const canvas, const GameState *game_state) { -static void draw_ui(Canvas* const canvas, const GameState* game_state) { draw_money(canvas, game_state->player_score); draw_score(canvas, true, hand_count(game_state->player_cards, game_state->player_card_count)); - if(!game_state->queue_state.running && game_state->state == GameStatePlay) { - render_menu(game_state->menu, canvas, 2, 47); + if (!game_state->queue_state.running && game_state->state == GameStatePlay) { + render_menu(game_state->menu,canvas, 2, 47); } } -static void render_callback(Canvas* const canvas, void* ctx) { - const GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25); +static void render_callback(Canvas *const canvas, void *ctx) { + const GameState *game_state = acquire_mutex((ValueMutex *) ctx, 25); - if(game_state == NULL) { + if (game_state == NULL) { return; } canvas_set_color(canvas, ColorBlack); canvas_draw_frame(canvas, 0, 0, 128, 64); - if(game_state->state == GameStateStart) { + if (game_state->state == GameStateStart) { canvas_draw_icon(canvas, 0, 0, &I_blackjack); } - if(game_state->state == GameStateGameOver) { + if (game_state->state == GameStateGameOver) { canvas_draw_icon(canvas, 0, 0, &I_endscreen); } - if(game_state->state == GameStatePlay || game_state->state == GameStateDealer) { - if(game_state->state == GameStatePlay) + if (game_state->state == GameStatePlay || game_state->state == GameStateDealer) { + if (game_state->state == GameStatePlay) draw_player_scene(canvas, game_state); else draw_dealer_scene(canvas, game_state); render_queue(&(game_state->queue_state), game_state, canvas); draw_ui(canvas, game_state); - } else if(game_state->state == GameStateSettings) { + } else if (game_state->state == GameStateSettings) { settings_page(canvas, game_state); } - release_mutex((ValueMutex*)ctx, game_state); + release_mutex((ValueMutex *) ctx, game_state); } //region card draw -Card draw_card(GameState* game_state) { +Card draw_card(GameState *game_state) { Card c = game_state->deck.cards[game_state->deck.index]; game_state->deck.index++; return c; } -void drawPlayerCard(void* ctx) { - GameState* game_state = ctx; + +void drawPlayerCard(void *ctx) { + GameState *game_state = ctx; Card c = draw_card(game_state); game_state->player_cards[game_state->player_card_count] = c; game_state->player_card_count++; - if(game_state->player_score < game_state->settings.round_price || game_state->doubled) { + if(game_state->player_score < game_state->settings.round_price || game_state->doubled){ set_menu_state(game_state->menu, 0, false); } } -void drawDealerCard(void* ctx) { - GameState* game_state = ctx; +void drawDealerCard(void *ctx) { + GameState *game_state = ctx; Card c = draw_card(game_state); game_state->dealer_cards[game_state->dealer_card_count] = c; game_state->dealer_card_count++; @@ -87,363 +91,317 @@ void drawDealerCard(void* ctx) { //endregion //region queue callbacks -void to_lose_state(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; +void to_lose_state(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; + if (game_state->settings.message_duration == 0) + return; popup_frame(canvas); elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "You lost"); } -void to_bust_state(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; +void to_bust_state(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; + if (game_state->settings.message_duration == 0) + return; popup_frame(canvas); elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Busted!"); } -void to_draw_state(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; +void to_draw_state(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; + if (game_state->settings.message_duration == 0) + return; popup_frame(canvas); elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Draw"); } -void to_dealer_turn(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; +void to_dealer_turn(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; + if (game_state->settings.message_duration == 0) + return; popup_frame(canvas); elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Dealers turn"); } -void to_win_state(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; +void to_win_state(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; + if (game_state->settings.message_duration == 0) + return; popup_frame(canvas); elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "You win"); } -void to_start(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; +void to_start(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; + if (game_state->settings.message_duration == 0) + return; popup_frame(canvas); elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Round started"); } -void before_start(void* ctx) { - GameState* game_state = ctx; +void before_start(void *ctx) { + GameState *game_state = ctx; game_state->dealer_card_count = 0; game_state->player_card_count = 0; } -void start(void* ctx) { - GameState* game_state = ctx; + +void start(void *ctx) { + GameState *game_state = ctx; start_round(game_state); } -void draw(void* ctx) { - GameState* game_state = ctx; +void draw(void *ctx) { + GameState *game_state = ctx; game_state->player_score += game_state->bet; game_state->bet = 0; - enqueue( - &(game_state->queue_state), - game_state, - start, - before_start, - to_start, - game_state->settings.message_duration); + enqueue(&(game_state->queue_state), game_state, start, before_start, to_start, + game_state->settings.message_duration); } -void game_over(void* ctx) { - GameState* game_state = ctx; +void game_over(void *ctx) { + GameState *game_state = ctx; game_state->state = GameStateGameOver; } -void lose(void* ctx) { - GameState* game_state = ctx; +void lose(void *ctx) { + GameState *game_state = ctx; game_state->state = GameStatePlay; game_state->bet = 0; - if(game_state->player_score >= game_state->settings.round_price) { - enqueue( - &(game_state->queue_state), - game_state, - start, - before_start, - to_start, - game_state->settings.message_duration); + if (game_state->player_score >= game_state->settings.round_price) { + enqueue(&(game_state->queue_state), game_state, start, before_start, to_start, + game_state->settings.message_duration); } else { - enqueue(&(game_state->queue_state), game_state, game_over, NULL, NULL, 0); + enqueue(&(game_state->queue_state), game_state, game_over, NULL, NULL, + 0); } } -void win(void* ctx) { - GameState* game_state = ctx; +void win(void *ctx) { + GameState *game_state = ctx; game_state->state = GameStatePlay; game_state->player_score += game_state->bet * 2; game_state->bet = 0; - enqueue( - &(game_state->queue_state), - game_state, - start, - before_start, - to_start, - game_state->settings.message_duration); + enqueue(&(game_state->queue_state), game_state, start, before_start, to_start, + game_state->settings.message_duration); } -void dealerTurn(void* ctx) { - GameState* game_state = ctx; + +void dealerTurn(void *ctx) { + GameState *game_state = ctx; game_state->state = GameStateDealer; } -float animationTime(const GameState* game_state) { - return (float)(furi_get_tick() - game_state->queue_state.start) / - (float)(game_state->settings.animation_duration); +float animationTime(const GameState *game_state){ + return (float) (furi_get_tick() - game_state->queue_state.start) / + (float) (game_state->settings.animation_duration); } -void dealer_card_animation(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; +void dealer_card_animation(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; float t = animationTime(game_state); Card animatingCard = game_state->deck.cards[game_state->deck.index]; - if(game_state->dealer_card_count > 1) { + if (game_state->dealer_card_count > 1) { Vector end = card_pos_at_index(game_state->dealer_card_count); - draw_card_animation(animatingCard, (Vector){0, 64}, (Vector){0, 32}, end, t, true, canvas); + draw_card_animation(animatingCard, + (Vector) {0, 64}, + (Vector) {0, 32}, + end, + t, + true, + canvas); } else { - draw_card_animation( - animatingCard, - (Vector){32, -CARD_HEIGHT}, - (Vector){64, 32}, - (Vector){2, 2}, - t, - false, - canvas); - // draw_deck(game_state->dealer_cards, game_state->dealer_card_count, canvas); + draw_card_animation(animatingCard, + (Vector) {32, -CARD_HEIGHT}, + (Vector) {64, 32}, + (Vector) {2, 2}, + t, + false, + canvas); } } -void dealer_back_card_animation(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; +void dealer_back_card_animation(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; float t = animationTime(game_state); - Vector currentPos = - quadratic_2d((Vector){32, -CARD_HEIGHT}, (Vector){64, 32}, (Vector){13, 5}, t); + Vector currentPos = quadratic_2d((Vector) {32, -CARD_HEIGHT}, (Vector) {64, 32}, (Vector) {13, 5}, t); draw_card_back_at(currentPos.x, currentPos.y, canvas); } -void player_card_animation(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; +void player_card_animation(const void *ctx, Canvas *const canvas) { + const GameState *game_state = ctx; float t = animationTime(game_state); Card animatingCard = game_state->deck.cards[game_state->deck.index]; Vector end = card_pos_at_index(game_state->player_card_count); - draw_card_animation( - animatingCard, (Vector){32, -CARD_HEIGHT}, (Vector){0, 32}, end, t, true, canvas); - // draw_deck(game_state->dealer_cards, game_state->player_card_count, canvas); + draw_card_animation(animatingCard, + (Vector) {32, -CARD_HEIGHT}, + (Vector) {0, 32}, + end, + t, + true, + canvas); } //endregion -void player_tick(GameState* game_state) { +void player_tick(GameState *game_state) { uint8_t score = hand_count(game_state->player_cards, game_state->player_card_count); - if((game_state->doubled && score <= 21) || score == 21) { - enqueue( - &(game_state->queue_state), - game_state, - dealerTurn, - NULL, - to_dealer_turn, - game_state->settings.message_duration); - } else if(score > 21) { - enqueue( - &(game_state->queue_state), - game_state, - lose, - NULL, - to_bust_state, - game_state->settings.message_duration); + if ((game_state->doubled && score <= 21) || score == 21) { + enqueue(&(game_state->queue_state), game_state, dealerTurn, NULL, to_dealer_turn, + game_state->settings.message_duration); + } else if (score > 21) { + enqueue(&(game_state->queue_state), game_state, lose, NULL, to_bust_state, + game_state->settings.message_duration); } else { - if(game_state->selectDirection == DirectionUp || - game_state->selectDirection == DirectionDown) { + if(game_state->selectDirection == DirectionUp || game_state->selectDirection == DirectionDown){ move_menu(game_state->menu, game_state->selectDirection == DirectionUp ? -1 : 1); } - if(game_state->selectDirection == Select) { + if (game_state->selectDirection == Select){ activate_menu(game_state->menu, game_state); + } } } -void dealer_tick(GameState* game_state) { +void dealer_tick(GameState *game_state) { uint8_t dealer_score = hand_count(game_state->dealer_cards, game_state->dealer_card_count); uint8_t player_score = hand_count(game_state->player_cards, game_state->player_card_count); - if(dealer_score >= DEALER_MAX) { - if(dealer_score > 21 || dealer_score < player_score) { - enqueue( - &(game_state->queue_state), - game_state, - win, - NULL, - to_win_state, - game_state->settings.message_duration); - } else if(dealer_score > player_score) { - enqueue( - &(game_state->queue_state), - game_state, - lose, - NULL, - to_lose_state, - game_state->settings.message_duration); - } else if(dealer_score == player_score) { - enqueue( - &(game_state->queue_state), - game_state, - draw, - NULL, - to_draw_state, - game_state->settings.message_duration); + if (dealer_score >= DEALER_MAX) { + if (dealer_score > 21 || dealer_score < player_score) { + enqueue(&(game_state->queue_state), game_state, win, NULL, to_win_state, + game_state->settings.message_duration); + } else if (dealer_score > player_score) { + enqueue(&(game_state->queue_state), game_state, lose, NULL, to_lose_state, + game_state->settings.message_duration); + } else if (dealer_score == player_score) { + enqueue(&(game_state->queue_state), game_state, draw, NULL, to_draw_state, + game_state->settings.message_duration); } } else { - enqueue( - &(game_state->queue_state), - game_state, - drawDealerCard, - NULL, - dealer_card_animation, - game_state->settings.animation_duration); + enqueue(&(game_state->queue_state), game_state, drawDealerCard, NULL, dealer_card_animation, + game_state->settings.animation_duration); } } -void settings_tick(GameState* game_state) { - if(game_state->selectDirection == DirectionDown && game_state->selectedMenu < 4) { +void settings_tick(GameState *game_state) { + if (game_state->selectDirection == DirectionDown && game_state->selectedMenu < 4) { game_state->selectedMenu++; } - if(game_state->selectDirection == DirectionUp && game_state->selectedMenu > 0) { + if (game_state->selectDirection == DirectionUp && game_state->selectedMenu > 0) { game_state->selectedMenu--; } - if(game_state->selectDirection == DirectionLeft || - game_state->selectDirection == DirectionRight) { + if (game_state->selectDirection == DirectionLeft || game_state->selectDirection == DirectionRight) { int nextScore = 0; - switch(game_state->selectedMenu) { - case 0: - nextScore = game_state->settings.starting_money; - if(game_state->selectDirection == DirectionLeft) - nextScore -= 10; - else - nextScore += 10; - if(nextScore >= (int)game_state->settings.round_price && nextScore < 400) - game_state->settings.starting_money = nextScore; - break; - case 1: - nextScore = game_state->settings.round_price; - if(game_state->selectDirection == DirectionLeft) - nextScore -= 10; - else - nextScore += 10; - if(nextScore >= 5 && nextScore <= (int)game_state->settings.starting_money) - game_state->settings.round_price = nextScore; - break; - case 2: - nextScore = game_state->settings.animation_duration; - if(game_state->selectDirection == DirectionLeft) - nextScore -= 100; - else - nextScore += 100; - if(nextScore >= 0 && nextScore < 2000) - game_state->settings.animation_duration = nextScore; - break; - case 3: - nextScore = game_state->settings.message_duration; - if(game_state->selectDirection == DirectionLeft) - nextScore -= 100; - else - nextScore += 100; - if(nextScore >= 0 && nextScore < 2000) - game_state->settings.message_duration = nextScore; - break; - case 4: - game_state->settings.sound_effects = !game_state->settings.sound_effects; - default: - break; + switch (game_state->selectedMenu) { + case 0: + nextScore = game_state->settings.starting_money; + if (game_state->selectDirection == DirectionLeft) + nextScore -= 10; + else + nextScore += 10; + if (nextScore >= (int) game_state->settings.round_price && nextScore < 400) + game_state->settings.starting_money = nextScore; + break; + case 1: + nextScore = game_state->settings.round_price; + if (game_state->selectDirection == DirectionLeft) + nextScore -= 10; + else + nextScore += 10; + if (nextScore >= 5 && nextScore <= (int) game_state->settings.starting_money) + game_state->settings.round_price = nextScore; + break; + case 2: + nextScore = game_state->settings.animation_duration; + if (game_state->selectDirection == DirectionLeft) + nextScore -= 100; + else + nextScore += 100; + if (nextScore >= 0 && nextScore < 2000) + game_state->settings.animation_duration = nextScore; + break; + case 3: + nextScore = game_state->settings.message_duration; + if (game_state->selectDirection == DirectionLeft) + nextScore -= 100; + else + nextScore += 100; + if (nextScore >= 0 && nextScore < 2000) + game_state->settings.message_duration = nextScore; + break; + case 4: + game_state->settings.sound_effects = !game_state->settings.sound_effects; + default: + break; } } + } -void tick(GameState* game_state) { +void tick(GameState *game_state) { game_state->last_tick = furi_get_tick(); bool queue_ran = run_queue(&(game_state->queue_state), game_state); - switch(game_state->state) { - case GameStateGameOver: - case GameStateStart: - if(game_state->selectDirection == Select) - init(game_state); - else if(game_state->selectDirection == DirectionRight) { - game_state->selectedMenu = 0; - game_state->state = GameStateSettings; - } - break; - case GameStatePlay: - if(!game_state->started) { - game_state->selectedMenu = 0; - game_state->started = true; - enqueue( - &(game_state->queue_state), - game_state, - drawDealerCard, - NULL, - dealer_back_card_animation, - game_state->settings.animation_duration); - enqueue( - &(game_state->queue_state), - game_state, - drawPlayerCard, - NULL, - player_card_animation, - game_state->settings.animation_duration); - enqueue( - &(game_state->queue_state), - game_state, - drawDealerCard, - NULL, - dealer_card_animation, - game_state->settings.animation_duration); - enqueue( - &(game_state->queue_state), - game_state, - drawPlayerCard, - NULL, - player_card_animation, - game_state->settings.animation_duration); - } - if(!queue_ran) player_tick(game_state); - break; - case GameStateDealer: - if(!queue_ran) dealer_tick(game_state); - break; - case GameStateSettings: - settings_tick(game_state); - break; - default: - break; + switch (game_state->state) { + case GameStateGameOver: + case GameStateStart: + if (game_state->selectDirection == Select) + init(game_state); + else if (game_state->selectDirection == DirectionRight) { + game_state->selectedMenu = 0; + game_state->state = GameStateSettings; + } + break; + case GameStatePlay: + if (!game_state->started) { + game_state->selectedMenu = 0; + game_state->started = true; + enqueue(&(game_state->queue_state), game_state, drawDealerCard, NULL, dealer_back_card_animation, + game_state->settings.animation_duration); + enqueue(&(game_state->queue_state), game_state, drawPlayerCard, NULL, player_card_animation, + game_state->settings.animation_duration); + enqueue(&(game_state->queue_state), game_state, drawDealerCard, NULL, dealer_card_animation, + game_state->settings.animation_duration); + enqueue(&(game_state->queue_state), game_state, drawPlayerCard, NULL, player_card_animation, + game_state->settings.animation_duration); + } + if (!queue_ran) + player_tick(game_state); + break; + case GameStateDealer: + if (!queue_ran) + dealer_tick(game_state); + break; + case GameStateSettings: + settings_tick(game_state); + break; + default: + break; } game_state->selectDirection = None; + } -void start_round(GameState* game_state) { - game_state->menu->current_menu = 1; +void start_round(GameState *game_state) { + game_state->menu->current_menu=1; game_state->player_card_count = 0; game_state->dealer_card_count = 0; set_menu_state(game_state->menu, 0, true); - game_state->menu->enabled = true; + game_state->menu->enabled=true; game_state->started = false; game_state->doubled = false; game_state->queue_state.running = true; shuffle_deck(&(game_state->deck)); game_state->doubled = false; game_state->bet = game_state->settings.round_price; - if(game_state->player_score < game_state->settings.round_price) { + if (game_state->player_score < game_state->settings.round_price) { game_state->state = GameStateGameOver; } else { game_state->player_score -= game_state->settings.round_price; @@ -451,10 +409,10 @@ void start_round(GameState* game_state) { game_state->state = GameStatePlay; } -void init(GameState* game_state) { +void init(GameState *game_state) { set_menu_state(game_state->menu, 0, true); - game_state->menu->enabled = true; - game_state->menu->current_menu = 1; + game_state->menu->enabled=true; + game_state->menu->current_menu=1; game_state->settings = load_settings(); game_state->last_tick = 0; game_state->processing = true; @@ -464,146 +422,123 @@ void init(GameState* game_state) { start_round(game_state); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { +static void input_callback(InputEvent *input_event, FuriMessageQueue *event_queue) { furi_assert(event_queue); AppEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void update_timer_callback(FuriMessageQueue* event_queue) { +static void update_timer_callback(FuriMessageQueue *event_queue) { furi_assert(event_queue); AppEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); } -void doubleAction(void* state) { - GameState* game_state = state; - if(!game_state->doubled && game_state->player_score >= game_state->settings.round_price) { +void doubleAction(void *state){ + GameState *game_state = state; + if (!game_state->doubled && game_state->player_score >= game_state->settings.round_price) { game_state->player_score -= game_state->settings.round_price; game_state->bet += game_state->settings.round_price; game_state->doubled = true; - enqueue( - &(game_state->queue_state), - game_state, - drawPlayerCard, - NULL, - player_card_animation, - game_state->settings.animation_duration); - game_state->player_cards[game_state->player_card_count] = - game_state->deck.cards[game_state->deck.index]; + enqueue(&(game_state->queue_state), game_state, drawPlayerCard, NULL, player_card_animation, + game_state->settings.animation_duration); + game_state->player_cards[game_state->player_card_count] = game_state->deck.cards[game_state->deck.index]; uint8_t score = hand_count(game_state->player_cards, game_state->player_card_count + 1); - if(score > 21) { - enqueue( - &(game_state->queue_state), - game_state, - lose, - NULL, - to_bust_state, - game_state->settings.message_duration); + if (score > 21) { + enqueue(&(game_state->queue_state), game_state, lose, NULL, to_bust_state, + game_state->settings.message_duration); } else { - enqueue( - &(game_state->queue_state), - game_state, - dealerTurn, - NULL, - to_dealer_turn, - game_state->settings.message_duration); + enqueue(&(game_state->queue_state), game_state, dealerTurn, NULL, to_dealer_turn, + game_state->settings.message_duration); } set_menu_state(game_state->menu, 0, false); } } -void hitAction(void* state) { - GameState* game_state = state; - enqueue( - &(game_state->queue_state), - game_state, - drawPlayerCard, - NULL, - player_card_animation, - game_state->settings.animation_duration); +void hitAction(void *state){ + GameState *game_state = state; + enqueue(&(game_state->queue_state), game_state, drawPlayerCard, NULL, player_card_animation, + game_state->settings.animation_duration); } -void stayAction(void* state) { - GameState* game_state = state; - enqueue( - &(game_state->queue_state), - game_state, - dealerTurn, - NULL, - to_dealer_turn, - game_state->settings.message_duration); +void stayAction(void *state){ + GameState *game_state = state; + enqueue(&(game_state->queue_state), game_state, dealerTurn, NULL, to_dealer_turn, + game_state->settings.message_duration); } -int32_t blackjack_app(void* p) { +int32_t blackjack_app(void *p) { UNUSED(p); int32_t return_code = 0; - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); + FuriMessageQueue *event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); - GameState* game_state = malloc(sizeof(GameState)); - game_state->menu = malloc(sizeof(Menu)); - game_state->menu->menu_width = 40; + GameState *game_state = malloc(sizeof(GameState)); + game_state->menu= malloc(sizeof(Menu)); + game_state->menu->menu_width=40; init(game_state); add_menu(game_state->menu, "Double", doubleAction); add_menu(game_state->menu, "Hit", hitAction); add_menu(game_state->menu, "Stay", stayAction); + set_card_graphics(&I_card_graphics); game_state->state = GameStateStart; ValueMutex state_mutex; - if(!init_mutex(&state_mutex, game_state, sizeof(GameState))) { + if (!init_mutex(&state_mutex, game_state, sizeof(GameState))) { FURI_LOG_E(APP_NAME, "cannot create mutex\r\n"); return_code = 255; goto free_and_exit; } - ViewPort* view_port = view_port_alloc(); + ViewPort *view_port = view_port_alloc(); view_port_draw_callback_set(view_port, render_callback, &state_mutex); view_port_input_callback_set(view_port, input_callback, event_queue); - FuriTimer* timer = furi_timer_alloc(update_timer_callback, FuriTimerTypePeriodic, event_queue); + FuriTimer *timer = + furi_timer_alloc(update_timer_callback, FuriTimerTypePeriodic, event_queue); furi_timer_start(timer, furi_kernel_get_tick_frequency() / 25); - Gui* gui = furi_record_open("gui"); + Gui *gui = furi_record_open("gui"); gui_add_view_port(gui, view_port, GuiLayerFullscreen); AppEvent event; - for(bool processing = true; processing;) { + for (bool processing = true; processing;) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - GameState* localstate = (GameState*)acquire_mutex_block(&state_mutex); - if(event_status == FuriStatusOk) { - if(event.type == EventTypeKey) { - if(event.input.type == InputTypePress) { - switch(event.input.key) { - case InputKeyUp: - localstate->selectDirection = DirectionUp; - break; - case InputKeyDown: - localstate->selectDirection = DirectionDown; - break; - case InputKeyRight: - localstate->selectDirection = DirectionRight; - break; - case InputKeyLeft: - localstate->selectDirection = DirectionLeft; - break; - case InputKeyBack: - if(localstate->state == GameStateSettings) { - localstate->state = GameStateStart; - save_settings(localstate->settings); - } else - processing = false; - break; - case InputKeyOk: - localstate->selectDirection = Select; - break; - default: - break; + GameState *localstate = (GameState *) acquire_mutex_block(&state_mutex); + if (event_status == FuriStatusOk) { + if (event.type == EventTypeKey) { + + if (event.input.type == InputTypePress) { + switch (event.input.key) { + case InputKeyUp: + localstate->selectDirection = DirectionUp; + break; + case InputKeyDown: + localstate->selectDirection = DirectionDown; + break; + case InputKeyRight: + localstate->selectDirection = DirectionRight; + break; + case InputKeyLeft: + localstate->selectDirection = DirectionLeft; + break; + case InputKeyBack: + if (localstate->state == GameStateSettings) { + localstate->state = GameStateStart; + save_settings(localstate->settings); + } else + processing = false; + break; + case InputKeyOk: + localstate->selectDirection = Select; + break; + default: + break; } } - } else if(event.type == EventTypeTick) { + } else if (event.type == EventTypeTick) { tick(localstate); processing = localstate->processing; } @@ -615,6 +550,7 @@ int32_t blackjack_app(void* p) { release_mutex(&state_mutex, localstate); } + furi_timer_free(timer); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); @@ -622,7 +558,8 @@ int32_t blackjack_app(void* p) { view_port_free(view_port); delete_mutex(&state_mutex); -free_and_exit: + free_and_exit: + free(game_state->deck.cards); free_menu(game_state->menu); queue_clear(&(game_state->queue_state)); free(game_state); diff --git a/applications/plugins/blackjack/common/card.c b/applications/plugins/blackjack/common/card.c index 4ff2d58b4..cfa07a5d4 100644 --- a/applications/plugins/blackjack/common/card.c +++ b/applications/plugins/blackjack/common/card.c @@ -1,7 +1,7 @@ #include "card.h" #include "dml.h" +#include "ui.h" -#define CORNER_MARGIN 3 #define CARD_DRAW_X_START 108 #define CARD_DRAW_Y_START 38 #define CARD_DRAW_X_SPACE 10 @@ -9,154 +9,145 @@ #define CARD_DRAW_X_OFFSET 4 #define CARD_DRAW_FIRST_ROW_LENGTH 7 -bool pips[4][49] = { - {//spades - 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0}, - { - //hearts - 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, - }, - {//diamonds - 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, - {//clubs - 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0}}; +uint8_t pips[4][3] = { + {21, 10, 7}, //spades + {7, 10, 7}, //hearts + {0, 10, 7}, //diamonds + {14, 10, 7}, //clubs +}; +uint8_t letters[13][3] = { + {0, 0, 5}, + {5, 0, 5}, + {10, 0, 5}, + {15, 0, 5}, + {20, 0, 5}, + {25, 0, 5}, + {30, 0, 5}, + {0, 5, 5}, + {5, 5, 5}, + {10, 5, 5}, + {15, 5, 5}, + {20, 5, 5}, + {25, 5, 5}, +}; //region Player card positions uint8_t playerCardPositions[22][4] = { - //first row - {108, 38}, - {98, 38}, - {88, 38}, - {78, 38}, - {68, 38}, - {58, 38}, - {48, 38}, - {38, 38}, - //second row - {104, 26}, - {94, 26}, - {84, 26}, - {74, 26}, - {64, 26}, - {54, 26}, - {44, 26}, - //third row - {99, 14}, - {89, 14}, - {79, 14}, - {69, 14}, - {59, 14}, - {49, 14}, + //first row + {108, 38}, + {98, 38}, + {88, 38}, + {78, 38}, + {68, 38}, + {58, 38}, + {48, 38}, + {38, 38}, + //second row + {104, 26}, + {94, 26}, + {84, 26}, + {74, 26}, + {64, 26}, + {54, 26}, + {44, 26}, + //third row + {99, 14}, + {89, 14}, + {79, 14}, + {69, 14}, + {59, 14}, + {49, 14}, }; //endregion +Icon *card_graphics = NULL; -bool get_pip_pixel(uint8_t pip, uint8_t x, uint8_t y) { - return pips[pip][x + y * 7]; +void set_card_graphics(const Icon *graphics) { + card_graphics = (Icon *) graphics; } -void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Canvas* const canvas) { - canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT); +void +draw_card_at_colored(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, bool inverted, Canvas *const canvas) { + DrawMode primary = inverted ? Black : White; + DrawMode secondary = inverted ? White : Black; + draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, primary); + draw_rounded_box_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); - canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT); + uint8_t *drawInfo = pips[pip]; + uint8_t px = drawInfo[0], py = drawInfo[1], s = drawInfo[2]; - uint8_t left = pos_x + CORNER_MARGIN; - uint8_t right = (pos_x + CARD_WIDTH - CORNER_MARGIN - 7); - uint8_t top = pos_y + CORNER_MARGIN; - uint8_t bottom = (pos_y + CARD_HEIGHT - CORNER_MARGIN - 7); + uint8_t left = pos_x + 2; + uint8_t right = (pos_x + CARD_WIDTH - s - 2); + uint8_t top = pos_y + 2; + uint8_t bottom = (pos_y + CARD_HEIGHT - s - 2); - for(uint8_t x = 0; x < 7; x++) { - for(uint8_t y = 0; y < 7; y++) { - if(get_pip_pixel(pip, x, y)) { - canvas_draw_dot(canvas, right + x + 1, top + y); - canvas_draw_dot(canvas, left + x - 1, bottom + y); - } - } - } + draw_icon_clip(canvas, card_graphics, right, top, px, py, s, s, + secondary); + draw_icon_clip_flipped(canvas, card_graphics, left, bottom, px, py, s, s, + secondary); - canvas_set_font(canvas, FontSecondary); - char drawChar[3]; - if(character < 9) - snprintf(drawChar, sizeof(drawChar), "%i", character + 2); - else { - if(character == 9) - snprintf(drawChar, sizeof(drawChar), "J"); - else if(character == 10) - snprintf(drawChar, sizeof(drawChar), "Q"); - else if(character == 11) - snprintf(drawChar, sizeof(drawChar), "K"); - else if(character == 12) - snprintf(drawChar, sizeof(drawChar), "A"); - } + drawInfo = letters[character]; + px = drawInfo[0], py = drawInfo[1], s = drawInfo[2]; + left = pos_x + 2; + right = (pos_x + CARD_WIDTH - s - 2); + top = pos_y + 2; + bottom = (pos_y + CARD_HEIGHT - s - 2); - canvas_set_font_direction(canvas, CanvasDirectionLeftToRight); - canvas_draw_str_aligned(canvas, left + 2, top + 3, AlignCenter, AlignCenter, drawChar); - - canvas_set_font_direction(canvas, CanvasDirectionRightToLeft); - //flipper crashes on non center aligned text when upside down - uint8_t margin = 9; - if(character == 8) //10 needs bigger margin - margin = 12; - canvas_draw_str_aligned( - canvas, right + margin, bottom - 3, AlignCenter, AlignCenter, drawChar); - - canvas_set_font_direction(canvas, CanvasDirectionLeftToRight); + draw_icon_clip(canvas, card_graphics, left, top + 1, px, py, s, s, + secondary); + draw_icon_clip_flipped(canvas, card_graphics, right, bottom - 1, px, py, s, s, + secondary); } -void draw_deck(const Card* cards, uint8_t count, Canvas* const canvas) { - for(int i = count - 1; i >= 0; i--) { - draw_card_at( - playerCardPositions[i][0], - playerCardPositions[i][1], - cards[i].pip, - cards[i].character, - canvas); +void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Canvas *const canvas) { + draw_card_at_colored(pos_x, pos_y, pip, character, false, canvas); +} + +void draw_deck(const Card *cards, uint8_t count, Canvas *const canvas) { + for (int i = count - 1; i >= 0; i--) { + draw_card_at(playerCardPositions[i][0], playerCardPositions[i][1], cards[i].pip, cards[i].character, canvas); } } Vector card_pos_at_index(uint8_t index) { - return (Vector){playerCardPositions[index][0], playerCardPositions[index][1]}; + return (Vector) { + playerCardPositions[index][0], + playerCardPositions[index][1] + }; } -void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas* const canvas) { - canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT); +void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas *const canvas) { + draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, White); + draw_rounded_box_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); + + draw_icon_clip(canvas, card_graphics, pos_x + 1, pos_y + 1, 35, 0, 15, 21, Black); - canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT); - for(uint8_t x = 0; x < CARD_WIDTH - 2; x++) { - for(uint8_t y = 0; y < CARD_HEIGHT - 2; y++) { - if((x + y) % 2 == 1) { - canvas_draw_dot(canvas, pos_x + x + 1, pos_y + y + 1); - } - } - } } -void generate_deck(Deck* deck_ptr, uint8_t deck_count) { +void generate_deck(Deck *deck_ptr, uint8_t deck_count) { uint16_t counter = 0; - deck_ptr->deck_count = deck_count; - deck_ptr->cards = malloc(sizeof(Card) * 52 * deck_count); - for(uint8_t deck = 0; deck < deck_count; deck++) { - for(uint8_t pip = 0; pip < 4; pip++) { - for(uint8_t label = 0; label < 13; label++) { - deck_ptr->cards[counter] = (Card){pip, label}; + if (deck_ptr->cards == NULL) { + deck_ptr->deck_count = deck_count; + deck_ptr->card_count = deck_count * 52; + deck_ptr->cards = malloc(sizeof(Card) * deck_ptr->card_count); + } + for (uint8_t deck = 0; deck < deck_count; deck++) { + for (uint8_t pip = 0; pip < 4; pip++) { + for (uint8_t label = 0; label < 13; label++) { + deck_ptr->cards[counter] = (Card) + { + pip, label, false, false + }; counter++; } } } } -void shuffle_deck(Deck* deck_ptr) { +void shuffle_deck(Deck *deck_ptr) { srand(DWT->CYCCNT); deck_ptr->index = 0; int max = deck_ptr->deck_count * 52; - for(int i = 0; i < max; i++) { + for (int i = 0; i < max; i++) { int r = i + (rand() % (max - i)); Card tmp = deck_ptr->cards[i]; deck_ptr->cards[i] = deck_ptr->cards[r]; @@ -164,53 +155,176 @@ void shuffle_deck(Deck* deck_ptr) { } } -uint8_t hand_count(const Card* cards, uint8_t count) { +uint8_t hand_count(const Card *cards, uint8_t count) { uint8_t aceCount = 0; uint8_t score = 0; - for(uint8_t i = 0; i < count; i++) { - if(cards[i].character == 12) + for (uint8_t i = 0; i < count; i++) { + if (cards[i].character == 12) aceCount++; else { - if(cards[i].character > 8) + if (cards[i].character > 8) score += 10; else score += cards[i].character + 2; } } - for(uint8_t i = 0; i < aceCount; i++) { - if((score + 11) <= 21) - score += 11; - else - score++; + for (uint8_t i = 0; i < aceCount; i++) { + if ((score + 11) <= 21) score += 11; + else score++; } return score; } -void draw_card_animation( - Card animatingCard, - Vector from, - Vector control, - Vector to, - float t, - bool extra_margin, - Canvas* const canvas) { +void draw_card_animation(Card animatingCard, Vector from, Vector control, Vector to, float t, bool extra_margin, + Canvas *const canvas) { float time = t; - if(extra_margin) { + if (extra_margin) { time += 0.2; } Vector currentPos = quadratic_2d(from, control, to, time); - if(t > 1) { - draw_card_at( - currentPos.x, currentPos.y, animatingCard.pip, animatingCard.character, canvas); + if (t > 1) { + draw_card_at(currentPos.x, currentPos.y, animatingCard.pip, + animatingCard.character, canvas); } else { - if(t < 0.5) + if (t < 0.5) draw_card_back_at(currentPos.x, currentPos.y, canvas); else - draw_card_at( - currentPos.x, currentPos.y, animatingCard.pip, animatingCard.character, canvas); + draw_card_at(currentPos.x, currentPos.y, animatingCard.pip, + animatingCard.character, canvas); } } + +void init_hand(Hand *hand_ptr, uint8_t count) { + hand_ptr->cards = malloc(sizeof(Card) * count); + hand_ptr->index = 0; + hand_ptr->max = count; +} + +void free_hand(Hand *hand_ptr) { + FURI_LOG_D("CARD", "Freeing hand"); + free(hand_ptr->cards); +} + +void add_to_hand(Hand *hand_ptr, Card card) { + FURI_LOG_D("CARD", "Adding to hand"); + if (hand_ptr->index < hand_ptr->max) { + hand_ptr->cards[hand_ptr->index] = card; + hand_ptr->index++; + } +} + +void draw_card_space(int16_t pos_x, int16_t pos_y, bool highlighted, Canvas *const canvas) { + if (highlighted) { + draw_rounded_box_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); + draw_rounded_box_frame(canvas, pos_x + 2, pos_y + 2, CARD_WIDTH - 4, CARD_HEIGHT - 4, White); + } else { + draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); + draw_rounded_box_frame(canvas, pos_x + 2, pos_y + 2, CARD_WIDTH - 4, CARD_HEIGHT - 4, White); + } +} + +int first_non_flipped_card(Hand hand) { + for (int i = 0; i < hand.index; i++) { + if (!hand.cards[i].flipped) { + return i; + } + } + return hand.index; +} + +void draw_hand_column(Hand hand, int16_t pos_x, int16_t pos_y, int8_t highlight, Canvas *const canvas) { + if (hand.index == 0) { + draw_card_space(pos_x, pos_y, highlight > 0, canvas); + if(highlight==0) + draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, + Inverse); + return; + } + + int loopEnd = hand.index; + int hStart = max(loopEnd-4, 0); + int pos = 0; + int first= first_non_flipped_card(hand); + bool wastop=false; + if(first>=0 && first<=hStart && highlight!=first){ + if(first>0){ + draw_card_back_at(pos_x, pos_y + pos, canvas); + pos+=4; + hStart++; + wastop=true; + } + draw_card_at_colored(pos_x, pos_y + pos, hand.cards[first].pip, hand.cards[first].character, + false, + canvas); + pos+=8; + hStart++; + } + if(hStart>highlight && highlight>=0){ + if(!wastop && first>0){ + draw_card_back_at(pos_x, pos_y + pos, canvas); + pos+=4; + hStart++; + } + draw_card_at_colored(pos_x, pos_y + pos, hand.cards[highlight].pip, hand.cards[highlight].character, + true, + canvas); + pos+=8; + hStart++; + } + for (int i = hStart; i < loopEnd; i++, pos+=4) { + if (hand.cards[i].flipped) { + draw_card_back_at(pos_x, pos_y + pos, canvas); + if(i==highlight) + draw_rounded_box(canvas, pos_x+1, pos_y + pos+1, CARD_WIDTH - 2, CARD_HEIGHT - 2, + Inverse); + } else { + draw_card_at_colored(pos_x, pos_y + pos, hand.cards[i].pip, hand.cards[i].character, + (i == highlight), + canvas); + if(i == highlight || i==first) pos+=4; + } + } +} + +Card remove_from_deck(uint16_t index, Deck *deck) { + FURI_LOG_D("CARD", "Removing from deck"); + Card result = {0, 0, true, false}; + if (deck->card_count > 0) { + deck->card_count--; + for (int i = 0, curr_index = 0; i <= deck->card_count; i++) { + if (i != index) { + deck->cards[curr_index] = deck->cards[i]; + curr_index++; + } else { + result = deck->cards[i]; + } + } + if (deck->index >= 0) { + deck->index--; + } + } + return result; +} + +void extract_hand_region(Hand *hand, Hand *to, uint8_t start_index) { + FURI_LOG_D("CARD", "Extracting hand region"); + if (start_index >= hand->index) return; + + for (uint8_t i = start_index; i < hand->index; i++) { + add_to_hand(to, hand->cards[i]); + } + hand->index = start_index; +} + +void add_hand_region(Hand *to, Hand *from) { + FURI_LOG_D("CARD", "Adding hand region"); + if ((to->index + from->index) <= to->max) { + for (int i = 0; i < from->index; i++) { + add_to_hand(to, from->cards[i]); + } + } +} \ No newline at end of file diff --git a/applications/plugins/blackjack/common/card.h b/applications/plugins/blackjack/common/card.h index 990c76261..3d0b27117 100644 --- a/applications/plugins/blackjack/common/card.h +++ b/applications/plugins/blackjack/common/card.h @@ -5,24 +5,35 @@ #include #include "dml.h" -#define CARD_HEIGHT 24 -#define CARD_HALF_HEIGHT CARD_HEIGHT / 2 -#define CARD_WIDTH 18 -#define CARD_HALF_WIDTH CARD_WIDTH / 2 +#define CARD_HEIGHT 23 +#define CARD_HALF_HEIGHT 11 +#define CARD_WIDTH 17 +#define CARD_HALF_WIDTH 8 //region types typedef struct { - uint8_t pip; //Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs - uint8_t character; //Card letter [0-12], 0 means 2, 12 is Ace + uint8_t pip; //Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs + uint8_t character; //Card letter [0-12], 0 means 2, 12 is Ace + bool disabled; + bool flipped; } Card; typedef struct { - uint8_t deck_count; //Number of decks used - Card* cards; //Cards in the deck - int index; //Card index (to know where we at in the deck) + uint8_t deck_count; //Number of decks used + Card *cards; //Cards in the deck + int card_count; + int index; //Card index (to know where we at in the deck) } Deck; + +typedef struct { + Card *cards; //Cards in the deck + uint8_t index; //Current index + uint8_t max; //How many cards we want to store +} Hand; //endregion +void set_card_graphics(const Icon *graphics); + /** * Gets card coordinates at the index (range: 0-20). * @@ -40,7 +51,20 @@ Vector card_pos_at_index(uint8_t index); * @param character Letter [0-12] 0 is 2, 12 is A * @param canvas Pointer to Flipper's canvas object */ -void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Canvas* const canvas); +void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Canvas *const canvas); + +/** + * Draws card at a given coordinate (top-left corner) + * + * @param pos_x X position + * @param pos_y Y position + * @param pip Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs + * @param character Letter [0-12] 0 is 2, 12 is A + * @param inverted Invert colors + * @param canvas Pointer to Flipper's canvas object + */ +void +draw_card_at_colored(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, bool inverted, Canvas *const canvas); /** * Draws 'count' cards at the bottom right corner @@ -49,7 +73,7 @@ void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Ca * @param count Count of cards * @param canvas Pointer to Flipper's canvas object */ -void draw_deck(const Card* cards, uint8_t count, Canvas* const canvas); +void draw_deck(const Card *cards, uint8_t count, Canvas *const canvas); /** * Draws card back at a given coordinate (top-left corner) @@ -58,7 +82,7 @@ void draw_deck(const Card* cards, uint8_t count, Canvas* const canvas); * @param pos_y Y coordinate * @param canvas Pointer to Flipper's canvas object */ -void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas* const canvas); +void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas *const canvas); /** * Generates the deck @@ -66,14 +90,14 @@ void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas* const canvas); * @param deck_ptr Pointer to the deck * @param deck_count Number of decks */ -void generate_deck(Deck* deck_ptr, uint8_t deck_count); +void generate_deck(Deck *deck_ptr, uint8_t deck_count); /** * Shuffles the deck * * @param deck_ptr Pointer to the deck */ -void shuffle_deck(Deck* deck_ptr); +void shuffle_deck(Deck *deck_ptr); /** * Calculates the hand count for blackjack @@ -82,7 +106,7 @@ void shuffle_deck(Deck* deck_ptr); * @param count Count of cards * @return Hand value */ -uint8_t hand_count(const Card* cards, uint8_t count); +uint8_t hand_count(const Card *cards, uint8_t count); /** * Draws card animation @@ -95,11 +119,59 @@ uint8_t hand_count(const Card* cards, uint8_t count); * @param extra_margin Use extra margin at the end (arrives 0.2 unit before the end so it can stay there a bit) * @param canvas Pointer to Flipper's canvas object */ -void draw_card_animation( - Card animatingCard, - Vector from, - Vector control, - Vector to, - float t, - bool extra_margin, - Canvas* const canvas); \ No newline at end of file +void draw_card_animation(Card animatingCard, Vector from, Vector control, Vector to, float t, bool extra_margin, + Canvas *const canvas); + +/** + * Init hand pointer + * @param hand_ptr Pointer to hand + * @param count Number of cards we want to store + */ +void init_hand(Hand *hand_ptr, uint8_t count); + +/** + * Free hand resources + * @param hand_ptr Pointer to hand + */ +void free_hand(Hand *hand_ptr); + +/** + * Add card to hand + * @param hand_ptr Pointer to hand + * @param card Card to add + */ +void add_to_hand(Hand *hand_ptr, Card card); + +/** + * Draw card placement position at coordinate + * @param pos_x X coordinate + * @param pos_y Y coordinate + * @param highlighted Apply highlight effect + * @param canvas Canvas object + */ +void draw_card_space(int16_t pos_x, int16_t pos_y, bool highlighted, Canvas *const canvas); + +/** + * Draws a column of card, displaying the last [max_cards] cards on the list + * @param hand Hand object + * @param pos_x X coordinate to draw + * @param pos_y Y coordinate to draw + * @param highlight Index to highlight, negative means no highlight + * @param canvas Canvas object + */ +void +draw_hand_column(Hand hand, int16_t pos_x, int16_t pos_y, int8_t highlight, Canvas *const canvas); + +/** + * Removes a card from the deck (Be aware, if you remove the first item, the deck index will be at -1 so you have to handle that) + * @param index Index to remove + * @param deck Deck reference + * @return The removed card + */ +Card remove_from_deck(uint16_t index, Deck *deck); + +int first_non_flipped_card(Hand hand); + +void extract_hand_region(Hand *hand, Hand *to, uint8_t start_index); + +void add_hand_region(Hand *to, Hand *from); \ No newline at end of file diff --git a/applications/plugins/blackjack/common/dml.c b/applications/plugins/blackjack/common/dml.c index b9a0e395f..5329a3be0 100644 --- a/applications/plugins/blackjack/common/dml.c +++ b/applications/plugins/blackjack/common/dml.c @@ -2,40 +2,47 @@ #include float lerp(float v0, float v1, float t) { - if(t > 1) return v1; + if (t > 1) return v1; return (1 - t) * v0 + t * v1; } Vector lerp_2d(Vector start, Vector end, float t) { - return (Vector){ - lerp(start.x, end.x, t), - lerp(start.y, end.y, t), + return (Vector) { + lerp(start.x, end.x, t), + lerp(start.y, end.y, t), }; } Vector quadratic_2d(Vector start, Vector control, Vector end, float t) { - return lerp_2d(lerp_2d(start, control, t), lerp_2d(control, end, t), t); + return lerp_2d( + lerp_2d(start, control, t), + lerp_2d(control, end, t), + t + ); } Vector vector_add(Vector a, Vector b) { - return (Vector){a.x + b.x, a.y + b.y}; + return (Vector) {a.x + b.x, a.y + b.y}; } Vector vector_sub(Vector a, Vector b) { - return (Vector){a.x - b.x, a.y - b.y}; + return (Vector) {a.x - b.x, a.y - b.y}; } Vector vector_mul_components(Vector a, Vector b) { - return (Vector){a.x * b.x, a.y * b.y}; + return (Vector) {a.x * b.x, a.y * b.y}; } Vector vector_div_components(Vector a, Vector b) { - return (Vector){a.x / b.x, a.y / b.y}; + return (Vector) {a.x / b.x, a.y / b.y}; } Vector vector_normalized(Vector a) { float length = vector_magnitude(a); - return (Vector){a.x / length, a.y / length}; + return (Vector) { + a.x / length, + a.y / length + }; } float vector_magnitude(Vector a) { diff --git a/applications/plugins/blackjack/common/dml.h b/applications/plugins/blackjack/common/dml.h index 3f3391d23..25e19da7d 100644 --- a/applications/plugins/blackjack/common/dml.h +++ b/applications/plugins/blackjack/common/dml.h @@ -9,6 +9,10 @@ typedef struct { float y; } Vector; +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define abs(x) ((x)>0?(x):-(x)) + /** * Lerp function * diff --git a/applications/plugins/blackjack/common/menu.c b/applications/plugins/blackjack/common/menu.c index ffc3921b7..a58b9bba3 100644 --- a/applications/plugins/blackjack/common/menu.c +++ b/applications/plugins/blackjack/common/menu.c @@ -1,53 +1,43 @@ #include "menu.h" -void add_menu(Menu* menu, const char* name, void (*callback)(void*)) { - MenuItem* items = menu->items; +void add_menu(Menu *menu, const char *name, void (*callback)(void *)) { + MenuItem *items = menu->items; menu->items = malloc(sizeof(MenuItem) * (menu->menu_count + 1)); - for(uint8_t i = 0; i < menu->menu_count; i++) { + for (uint8_t i = 0; i < menu->menu_count; i++) { menu->items[i] = items[i]; } free(items); - menu->items[menu->menu_count] = (MenuItem){name, true, callback}; + menu->items[menu->menu_count] = (MenuItem) {name, true, callback}; menu->menu_count++; } -void free_menu(Menu* menu) { +void free_menu(Menu *menu) { free(menu->items); free(menu); } -void set_menu_state(Menu* menu, uint8_t index, bool state) { - if(menu->menu_count > index) { +void set_menu_state(Menu *menu, uint8_t index, bool state) { + if (menu->menu_count > index) { menu->items[index].enabled = state; } - if(!state && menu->current_menu == index) move_menu(menu, 1); + if(!state && menu->current_menu==index) + move_menu(menu, 1); } -void move_menu(Menu* menu, int8_t direction) { - if(!menu->enabled) return; +void move_menu(Menu *menu, int8_t direction) { + if (!menu->enabled) return; int max = menu->menu_count; - for(int8_t i = 0; i < max; i++) { - FURI_LOG_D( - "MENU", - "Iteration %i, current %i, direction %i, state %i", - i, - menu->current_menu, - direction, - menu->items[menu->current_menu].enabled ? 1 : 0); - if(direction < 0 && menu->current_menu == 0) { + for (int8_t i = 0; i < max; i++) { + FURI_LOG_D("MENU", "Iteration %i, current %i, direction %i, state %i", i, menu->current_menu,direction,menu->items[menu->current_menu].enabled?1:0); + if (direction < 0 && menu->current_menu == 0) { menu->current_menu = menu->menu_count - 1; } else { menu->current_menu = (menu->current_menu + direction) % menu->menu_count; } - FURI_LOG_D( - "MENU", - "After process current %i, direction %i, state %i", - menu->current_menu, - direction, - menu->items[menu->current_menu].enabled ? 1 : 0); - if(menu->items[menu->current_menu].enabled) { + FURI_LOG_D("MENU", "After process current %i, direction %i, state %i", menu->current_menu,direction,menu->items[menu->current_menu].enabled?1:0); + if (menu->items[menu->current_menu].enabled) { FURI_LOG_D("MENU", "Next menu %i", menu->current_menu); return; } @@ -56,48 +46,44 @@ void move_menu(Menu* menu, int8_t direction) { menu->enabled = false; } -void activate_menu(Menu* menu, void* state) { - if(!menu->enabled) return; +void activate_menu(Menu *menu, void *state) { + if (!menu->enabled) return; menu->items[menu->current_menu].callback(state); } -void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y) { - if(!menu->enabled) return; +void render_menu(Menu *menu, Canvas *canvas, uint8_t pos_x, uint8_t pos_y) { + if (!menu->enabled) return; canvas_set_color(canvas, ColorWhite); canvas_draw_rbox(canvas, pos_x, pos_y, menu->menu_width + 2, 10, 2); - uint8_t w = pos_x + menu->menu_width; - uint8_t h = pos_y + 10; - uint8_t p1x = pos_x + 2; - uint8_t p2x = pos_x + menu->menu_width - 2; - uint8_t p1y = pos_y + 2; - uint8_t p2y = pos_y + 8; + uint8_t w = pos_x+menu->menu_width; + uint8_t h = pos_y+10; + uint8_t p1x = pos_x+2; + uint8_t p2x = pos_x+menu->menu_width-2; + uint8_t p1y = pos_y+2; + uint8_t p2y = pos_y+8; canvas_set_color(canvas, ColorBlack); canvas_draw_line(canvas, p1x, pos_y, p2x, pos_y); canvas_draw_line(canvas, p1x, h, p2x, h); canvas_draw_line(canvas, pos_x, p1y, pos_x, p2y); canvas_draw_line(canvas, w, p1y, w, p2y); - canvas_draw_dot(canvas, pos_x + 1, pos_y + 1); - canvas_draw_dot(canvas, w - 1, pos_y + 1); - canvas_draw_dot(canvas, w - 1, h - 1); - canvas_draw_dot(canvas, pos_x + 1, h - 1); + canvas_draw_dot(canvas, pos_x+1, pos_y+1); + canvas_draw_dot(canvas, w-1, pos_y+1); + canvas_draw_dot(canvas, w-1, h-1); + canvas_draw_dot(canvas, pos_x+1, h-1); - // canvas_draw_rbox(canvas, pos_x, pos_y, menu->menu_width + 2, 10, 2); +// canvas_draw_rbox(canvas, pos_x, pos_y, menu->menu_width + 2, 10, 2); canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - pos_x + menu->menu_width / 2, - pos_y + 6, - AlignCenter, - AlignCenter, - menu->items[menu->current_menu].name); + canvas_draw_str_aligned(canvas, pos_x + menu->menu_width / 2, pos_y + 6, AlignCenter, AlignCenter, + menu->items[menu->current_menu].name); //9*5 int center = pos_x + menu->menu_width / 2; - for(uint8_t i = 0; i < 4; i++) { - for(int8_t j = -i; j <= i; j++) { - canvas_draw_dot(canvas, center + j, pos_y - 4 + i); - canvas_draw_dot(canvas, center + j, pos_y + 14 - i); + for(uint8_t i=0;i<4;i++){ + for(int8_t j = -i; j<=i;j++){ + canvas_draw_dot(canvas, center+j, pos_y-4+i); + canvas_draw_dot(canvas, center+j, pos_y+14-i); } } + } \ No newline at end of file diff --git a/applications/plugins/blackjack/common/menu.h b/applications/plugins/blackjack/common/menu.h index 9f2852522..519a7edad 100644 --- a/applications/plugins/blackjack/common/menu.h +++ b/applications/plugins/blackjack/common/menu.h @@ -4,19 +4,18 @@ #include typedef struct { - const char* name; //Name of the menu - bool enabled; //Is the menu item enabled (it will not render, you cannot select it) + const char *name; //Name of the menu + bool enabled; //Is the menu item enabled (it will not render, you cannot select it) - void (*callback)( - void* state); //Callback for when the activate_menu is called while this menu is selected + void (*callback)(void *state); //Callback for when the activate_menu is called while this menu is selected } MenuItem; typedef struct { - MenuItem* items; //list of menu items - uint8_t menu_count; //count of menu items (do not change) - uint8_t current_menu; //currently selected menu item - uint8_t menu_width; //width of the menu - bool enabled; //is the menu enabled (it will not render and accept events when disabled) + MenuItem *items; //list of menu items + uint8_t menu_count; //count of menu items (do not change) + uint8_t current_menu; //currently selected menu item + uint8_t menu_width; //width of the menu + bool enabled; //is the menu enabled (it will not render and accept events when disabled) } Menu; /** @@ -24,7 +23,7 @@ typedef struct { * * @param menu Pointer of the menu to clean up */ -void free_menu(Menu* menu); +void free_menu(Menu *menu); /** * Add a new menu item @@ -33,7 +32,7 @@ void free_menu(Menu* menu); * @param name Name of the menu item * @param callback Callback called on activation */ -void add_menu(Menu* menu, const char* name, void (*callback)(void*)); +void add_menu(Menu *menu, const char *name, void (*callback)(void *)); /** * Setting menu item to be enabled/disabled @@ -42,7 +41,7 @@ void add_menu(Menu* menu, const char* name, void (*callback)(void*)); * @param index Menu index to set * @param state Enabled (true), Disabled(false) */ -void set_menu_state(Menu* menu, uint8_t index, bool state); +void set_menu_state(Menu *menu, uint8_t index, bool state); /** * Moves selection up or down @@ -50,7 +49,7 @@ void set_menu_state(Menu* menu, uint8_t index, bool state); * @param menu Pointer of the menu * @param direction Direction to move -1 down, 1 up */ -void move_menu(Menu* menu, int8_t direction); +void move_menu(Menu *menu, int8_t direction); /** * Triggers the current menu callback @@ -58,7 +57,7 @@ void move_menu(Menu* menu, int8_t direction); * @param menu Pointer of the menu * @param state Usually your application state */ -void activate_menu(Menu* menu, void* state); +void activate_menu(Menu *menu, void *state); /** * Renders the menu at a coordinate (call it in your render function). @@ -74,4 +73,4 @@ void activate_menu(Menu* menu, void* state); * @param pos_x X position to draw * @param pos_y Y position to draw */ -void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y); \ No newline at end of file +void render_menu(Menu *menu, Canvas *canvas, uint8_t pos_x, uint8_t pos_y); \ No newline at end of file diff --git a/applications/plugins/blackjack/common/queue.c b/applications/plugins/blackjack/common/queue.c index a80373460..36171f3e3 100644 --- a/applications/plugins/blackjack/common/queue.c +++ b/applications/plugins/blackjack/common/queue.c @@ -1,14 +1,15 @@ #include "queue.h" -void render_queue(const QueueState* queue_state, const void* app_state, Canvas* const canvas) { - if(queue_state->current != NULL && queue_state->current->render != NULL) - ((QueueItem*)queue_state->current)->render(app_state, canvas); + +void render_queue(const QueueState *queue_state, const void *app_state, Canvas *const canvas) { + if (queue_state->current != NULL && queue_state->current->render != NULL) + ((QueueItem *) queue_state->current)->render(app_state, canvas); } -bool run_queue(QueueState* queue_state, void* app_state) { - if(queue_state->current != NULL) { +bool run_queue(QueueState *queue_state, void *app_state) { + if (queue_state->current != NULL) { queue_state->running = true; - if((furi_get_tick() - queue_state->start) >= queue_state->current->duration) + if ((furi_get_tick() - queue_state->start) >= queue_state->current->duration) dequeue(queue_state, app_state); return true; @@ -16,48 +17,44 @@ bool run_queue(QueueState* queue_state, void* app_state) { return false; } -void dequeue(QueueState* queue_state, void* app_state) { - ((QueueItem*)queue_state->current)->callback(app_state); - QueueItem* f = queue_state->current; +void dequeue(QueueState *queue_state, void *app_state) { + ((QueueItem *) queue_state->current)->callback(app_state); + QueueItem *f = queue_state->current; queue_state->current = f->next; free(f); - if(queue_state->current != NULL) { - if(queue_state->current->start != NULL) queue_state->current->start(app_state); + if (queue_state->current != NULL) { + if (queue_state->current->start != NULL) + queue_state->current->start(app_state); queue_state->start = furi_get_tick(); - } else { + }else{ queue_state->running = false; } } -void queue_clear(QueueState* queue_state) { +void queue_clear(QueueState *queue_state) { queue_state->running = false; - QueueItem* curr = queue_state->current; - while(curr != NULL) { - QueueItem* f = curr; + QueueItem *curr = queue_state->current; + while (curr != NULL) { + QueueItem *f = curr; curr = curr->next; free(f); } } -void enqueue( - QueueState* queue_state, - void* app_state, - void (*done)(void* state), - void (*start)(void* state), - void (*render)(const void* state, Canvas* const canvas), - uint32_t duration) { - QueueItem* next; - if(queue_state->current == NULL) { +void enqueue(QueueState *queue_state, void *app_state, + void(*done)(void *state), void(*start)(void *state), + void (*render)(const void *state, Canvas *const canvas), uint32_t duration) { + QueueItem *next; + if (queue_state->current == NULL) { queue_state->start = furi_get_tick(); queue_state->current = malloc(sizeof(QueueItem)); next = queue_state->current; - if(next->start != NULL) next->start(app_state); + if (next->start != NULL) + next->start(app_state); } else { next = queue_state->current; - while(next->next != NULL) { - next = (QueueItem*)(next->next); - } + while (next->next != NULL) { next = (QueueItem *) (next->next); } next->next = malloc(sizeof(QueueItem)); next = next->next; } diff --git a/applications/plugins/blackjack/common/queue.h b/applications/plugins/blackjack/common/queue.h index dcfe0c091..cf61cc6b5 100644 --- a/applications/plugins/blackjack/common/queue.h +++ b/applications/plugins/blackjack/common/queue.h @@ -4,19 +4,17 @@ #include typedef struct { - void (*callback)(void* state); //Callback for when the item is dequeued - void (*render)( - const void* state, - Canvas* const canvas); //Callback for the rendering loop while this item is running - void (*start)(void* state); //Callback when this item is started running - void* next; //Pointer to the next item - uint32_t duration; //duration of the item + void (*callback)(void *state); //Callback for when the item is dequeued + void (*render)(const void *state, Canvas *const canvas); //Callback for the rendering loop while this item is running + void (*start)(void *state); //Callback when this item is started running + void *next; //Pointer to the next item + uint32_t duration; //duration of the item } QueueItem; typedef struct { - unsigned int start; //current queue item start time - QueueItem* current; //current queue item - bool running; //is the queue running + unsigned int start; //current queue item start time + QueueItem *current; //current queue item + bool running; //is the queue running } QueueState; /** @@ -29,19 +27,15 @@ typedef struct { * @param render Callback to render loop if needed * @param duration Length of the item */ -void enqueue( - QueueState* queue_state, - void* app_state, - void (*done)(void* state), - void (*start)(void* state), - void (*render)(const void* state, Canvas* const canvas), - uint32_t duration); +void enqueue(QueueState *queue_state, void *app_state, + void(*done)(void *state), void(*start)(void *state), + void (*render)(const void *state, Canvas *const canvas), uint32_t duration); /** * Clears all queue items * * @param queue_state The queue state pointer */ -void queue_clear(QueueState* queue_state); +void queue_clear(QueueState *queue_state); /** * Dequeues the active queue item. Usually you don't need to call it directly. @@ -49,7 +43,7 @@ void queue_clear(QueueState* queue_state); * @param queue_state The queue state pointer * @param app_state Your application state */ -void dequeue(QueueState* queue_state, void* app_state); +void dequeue(QueueState *queue_state, void *app_state); /** * Runs the queue logic (place it in your tick function) @@ -58,7 +52,7 @@ void dequeue(QueueState* queue_state, void* app_state); * @param app_state Your application state * @return FALSE when there is nothing to run, TRUE otherwise */ -bool run_queue(QueueState* queue_state, void* app_state); +bool run_queue(QueueState *queue_state, void *app_state); /** * Calls the currently active queue items render callback (if there is any) @@ -67,4 +61,4 @@ bool run_queue(QueueState* queue_state, void* app_state); * @param app_state Your application state * @param canvas Pointer to Flipper's canvas object */ -void render_queue(const QueueState* queue_state, const void* app_state, Canvas* const canvas); \ No newline at end of file +void render_queue(const QueueState *queue_state, const void *app_state, Canvas *const canvas); \ No newline at end of file diff --git a/applications/plugins/blackjack/common/ui.c b/applications/plugins/blackjack/common/ui.c new file mode 100644 index 000000000..b04b93674 --- /dev/null +++ b/applications/plugins/blackjack/common/ui.c @@ -0,0 +1,216 @@ +#include "ui.h" +#include +#include +#include +#include +#include +#include + +TileMap *tileMap; +uint8_t tileMapCount = 0; + +void ui_cleanup() { + if (tileMap != NULL) { + for (uint8_t i = 0; i < tileMapCount; i++) { + if (tileMap[i].data != NULL) + free(tileMap[i].data); + } + free(tileMap); + } +} + +void add_new_tilemap(uint8_t *data, unsigned long iconId) { + TileMap *old = tileMap; + tileMapCount++; + tileMap = malloc(sizeof(TileMap) * tileMapCount); + if (tileMapCount > 1) { + for (uint8_t i = 0; i < tileMapCount; i++) + tileMap[i] = old[i]; + } + tileMap[tileMapCount - 1] = (TileMap) {data, iconId}; +} + + +uint8_t *get_tilemap(unsigned long icon_id) { + for (uint8_t i = 0; i < tileMapCount; i++) { + if (tileMap[i].iconId == icon_id) + return tileMap[i].data; + } + + return NULL; +} + +uint32_t pixel_index(uint8_t x, uint8_t y) { + return y * SCREEN_WIDTH + x; +} + +bool in_screen(int16_t x, int16_t y) { + return x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HEIGHT; +} + +unsigned flipBit(uint8_t x, uint8_t bit) { + return x ^ (1 << bit); +} + +unsigned setBit(uint8_t x, uint8_t bit) { + return x | (1 << bit); +} + +unsigned unsetBit(uint8_t x, uint8_t bit) { + return x & ~(1 << bit); +} + +bool test_pixel(uint8_t *data, uint8_t x, uint8_t y, uint8_t w) { + uint8_t current_bit = (y % 8); + uint8_t current_row = ((y - current_bit) / 8); + uint8_t current_value = data[current_row * w + x]; + return current_value & (1 << current_bit); +} + +uint8_t* get_buffer(Canvas *const canvas){ + return canvas->fb.tile_buf_ptr; + // return canvas_get_buffer(canvas); +} +uint8_t* make_buffer(){ + return malloc(sizeof(uint8_t) * 8 * 128); +} +void clone_buffer(uint8_t* canvas, uint8_t* data){ + for(int i=0;i<1024;i++){ + data[i]= canvas[i]; + } +} + + +bool read_pixel(Canvas *const canvas, int16_t x, int16_t y) { + if (in_screen(x, y)) { + return test_pixel(get_buffer(canvas), x, y, SCREEN_WIDTH); + } + return false; +} + +void set_pixel(Canvas *const canvas, int16_t x, int16_t y, DrawMode draw_mode) { + if (in_screen(x, y)) { + uint8_t current_bit = (y % 8); + uint8_t current_row = ((y - current_bit) / 8); + uint32_t i = pixel_index(x, current_row); + uint8_t* buffer = get_buffer(canvas); + + uint8_t current_value = buffer[i]; + if (draw_mode == Inverse) { + buffer[i] = flipBit(current_value, current_bit); + } else { + if (draw_mode == White) { + buffer[i] = unsetBit(current_value, current_bit); + } else { + buffer[i] = setBit(current_value, current_bit); + } + } + } +} + +void draw_line(Canvas *const canvas, int16_t x1, int16_t y1, int16_t x2, int16_t y2, DrawMode draw_mode) { + for (int16_t x = x2; x >= x1; x--) { + for (int16_t y = y2; y >= y1; y--) { + set_pixel(canvas, x, y, draw_mode); + } + } +} + +void draw_rounded_box_frame(Canvas *const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h, DrawMode draw_mode) { + int16_t xMinCorner = x + 1; + int16_t xMax = x + w - 1; + int16_t xMaxCorner = x + w - 2; + int16_t yMinCorner = y + 1; + int16_t yMax = y + h - 1; + int16_t yMaxCorner = y + h - 2; + draw_line(canvas, xMinCorner, y, xMaxCorner, y, draw_mode); + draw_line(canvas, xMinCorner, yMax, xMaxCorner, yMax, draw_mode); + draw_line(canvas, x, yMinCorner, x, yMaxCorner, draw_mode); + draw_line(canvas, xMax, yMinCorner, xMax, yMaxCorner, draw_mode); +} + +void draw_rounded_box(Canvas *const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h, DrawMode draw_mode) { + for (int16_t o = w - 2; o >= 1; o--) { + for (int16_t p = h - 2; p >= 1; p--) { + set_pixel(canvas, x + o, y + p, draw_mode); + } + } + draw_rounded_box_frame(canvas, x, y, w, h, draw_mode); +} + +void invert_shape(Canvas *const canvas, uint8_t *data, int16_t x, int16_t y, uint8_t w, uint8_t h) { + draw_pixels(canvas, data, x, y, w, h, Inverse); +} + +void draw_pixels(Canvas *const canvas, uint8_t *data, int16_t x, int16_t y, uint8_t w, uint8_t h, DrawMode drawMode) { + for (int8_t o = 0; o < w; o++) { + for (int8_t p = 0; p < h; p++) { + if (in_screen(o + x, p + y) && data[p * w + o] == 1) + set_pixel(canvas, o + x, p + y, drawMode); + } + } +} + +void draw_rectangle(Canvas *const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h, DrawMode drawMode) { + for (int8_t o = 0; o < w; o++) { + for (int8_t p = 0; p < h; p++) { + if (in_screen(o + x, p + y)) { + set_pixel(canvas, o + x, p + y, drawMode); + } + } + } +} + +void invert_rectangle(Canvas *const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h) { + draw_rectangle(canvas, x, y, w, h, Inverse); +} + +uint8_t *image_data(Canvas *const canvas, const Icon *icon) { + uint8_t *data = malloc(sizeof(uint8_t) * 8 * 128); + uint8_t *screen = canvas->fb.tile_buf_ptr; + canvas->fb.tile_buf_ptr = data; + canvas_draw_icon(canvas, 0, 0, icon); + canvas->fb.tile_buf_ptr = screen; + return data; +} + +uint8_t *getOrAddIconData(Canvas *const canvas, const Icon *icon) { + uint8_t *icon_data = get_tilemap((unsigned long) icon); + if (icon_data == NULL) { + icon_data = image_data(canvas, icon); + add_new_tilemap(icon_data, (unsigned long) icon); + } + return icon_data; +} + +void draw_icon_clip(Canvas *const canvas, const Icon *icon, int16_t x, int16_t y, uint8_t left, uint8_t top, uint8_t w, + uint8_t h, DrawMode drawMode) { + uint8_t *icon_data = getOrAddIconData(canvas, icon); + + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + bool on = test_pixel(icon_data, left + i, top + j, SCREEN_WIDTH); + if (drawMode == Filled) { + set_pixel(canvas, x + i, y + j, on ? Black : White); + } else if (on) + set_pixel(canvas, x + i, y + j, drawMode); + } + } +} + +void draw_icon_clip_flipped(Canvas *const canvas, const Icon *icon, int16_t x, int16_t y, uint8_t left, uint8_t top, + uint8_t w, + uint8_t h, DrawMode drawMode) { + uint8_t *icon_data = getOrAddIconData(canvas, icon); + + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + bool on = test_pixel(icon_data, left + i, top + j, SCREEN_WIDTH); + + if (drawMode == Filled) { + set_pixel(canvas, x + w - i - 1, y + h - j - 1, on ? Black : White); + } else if (on) + set_pixel(canvas, x + w - i - 1, y + h - j - 1, drawMode); + } + } +} \ No newline at end of file diff --git a/applications/plugins/blackjack/common/ui.h b/applications/plugins/blackjack/common/ui.h new file mode 100644 index 000000000..06e38c4e3 --- /dev/null +++ b/applications/plugins/blackjack/common/ui.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 + +typedef enum { + Black, + White, + Inverse, + Filled //Currently only for Icon clip drawing +} DrawMode; + +// size is the screen size + +typedef struct { + uint8_t *data; + unsigned long iconId; +} TileMap; + +bool test_pixel(uint8_t *data, uint8_t x, uint8_t y, uint8_t w); + +uint8_t *image_data(Canvas *const canvas, const Icon *icon); + +uint32_t pixel_index(uint8_t x, uint8_t y); + +void draw_icon_clip(Canvas *const canvas, const Icon *icon, int16_t x, int16_t y, uint8_t left, uint8_t top, uint8_t w, + uint8_t h, DrawMode drawMode); + +void draw_icon_clip_flipped(Canvas *const canvas, const Icon *icon, int16_t x, int16_t y, uint8_t left, uint8_t top, uint8_t w, + uint8_t h, DrawMode drawMode); + +void draw_rounded_box(Canvas *const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h, DrawMode drawMode); + +void draw_rounded_box_frame(Canvas *const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h, DrawMode drawMode); + +void draw_rectangle(Canvas *const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h, DrawMode drawMode); + +void invert_rectangle(Canvas *const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h); + +void invert_shape(Canvas *const canvas, uint8_t *data, int16_t x, int16_t y, uint8_t w, uint8_t h); + +void draw_pixels(Canvas *const canvas, uint8_t *data, int16_t x, int16_t y, uint8_t w, uint8_t h, DrawMode drawMode); + +bool read_pixel(Canvas *const canvas, int16_t x, int16_t y); + +void set_pixel(Canvas *const canvas, int16_t x, int16_t y, DrawMode draw_mode); + +void draw_line(Canvas *const canvas, int16_t x1, int16_t y1, int16_t x2, int16_t y2, DrawMode draw_mode); + +bool in_screen(int16_t x, int16_t y); + +void ui_cleanup(); +uint8_t* get_buffer(Canvas *const canvas); +uint8_t* make_buffer(); +void clone_buffer(uint8_t* canvas, uint8_t* data); \ No newline at end of file diff --git a/applications/plugins/blackjack/defines.h b/applications/plugins/blackjack/defines.h index ebe8d9f9c..8b1d3ff1a 100644 --- a/applications/plugins/blackjack/defines.h +++ b/applications/plugins/blackjack/defines.h @@ -22,7 +22,7 @@ typedef enum { EventTypeKey, } EventType; -typedef struct { +typedef struct{ uint32_t animation_duration; uint32_t message_duration; uint32_t starting_money; @@ -43,7 +43,15 @@ typedef enum { GameStateDealer, } PlayState; -typedef enum { DirectionUp, DirectionRight, DirectionDown, DirectionLeft, Select, None } Direction; +typedef enum { + DirectionUp, + DirectionDown, + DirectionRight, + DirectionLeft, + Select, + Back, + None +} Direction; typedef struct { Card player_cards[21]; @@ -63,6 +71,7 @@ typedef struct { Deck deck; PlayState state; QueueState queue_state; - Menu* menu; + Menu *menu; unsigned int last_tick; } GameState; + diff --git a/applications/plugins/blackjack/ui.c b/applications/plugins/blackjack/ui.c index 79338b00d..a58c95c6a 100644 --- a/applications/plugins/blackjack/ui.c +++ b/applications/plugins/blackjack/ui.c @@ -6,28 +6,32 @@ #define LINE_HEIGHT 16 #define ITEM_PADDING 4 -const char MoneyMul[4] = {'K', 'B', 'T', 'S'}; +const char MoneyMul[4] = { + 'K', 'B', 'T', 'S' +}; -void draw_player_scene(Canvas* const canvas, const GameState* game_state) { +void draw_player_scene(Canvas *const canvas, const GameState *game_state) { int max_card = game_state->player_card_count; - if(max_card > 0) draw_deck((game_state->player_cards), max_card, canvas); + if (max_card > 0) + draw_deck((game_state->player_cards), max_card, canvas); - if(game_state->dealer_card_count > 0) draw_card_back_at(13, 5, canvas); + if (game_state->dealer_card_count > 0) + draw_card_back_at(13, 5, canvas); max_card = game_state->dealer_card_count; - if(max_card > 1) { - draw_card_at( - 2, 2, game_state->dealer_cards[1].pip, game_state->dealer_cards[1].character, canvas); + if (max_card > 1) { + draw_card_at(2, 2, game_state->dealer_cards[1].pip, game_state->dealer_cards[1].character, + canvas); } } -void draw_dealer_scene(Canvas* const canvas, const GameState* game_state) { +void draw_dealer_scene(Canvas *const canvas, const GameState *game_state) { uint8_t max_card = game_state->dealer_card_count; draw_deck((game_state->dealer_cards), max_card, canvas); } -void popup_frame(Canvas* const canvas) { +void popup_frame(Canvas *const canvas) { canvas_set_color(canvas, ColorWhite); canvas_draw_box(canvas, 32, 15, 66, 13); canvas_set_color(canvas, ColorBlack); @@ -35,16 +39,15 @@ void popup_frame(Canvas* const canvas) { canvas_set_font(canvas, FontSecondary); } -void draw_play_menu(Canvas* const canvas, const GameState* game_state) { - const char* menus[3] = {"Double", "Hit", "Stay"}; - for(uint8_t m = 0; m < 3; m++) { - if(m == 0 && - (game_state->doubled || game_state->player_score < game_state->settings.round_price)) - continue; + +void draw_play_menu(Canvas *const canvas, const GameState *game_state) { + const char *menus[3] = {"Double", "Hit", "Stay"}; + for (uint8_t m = 0; m < 3; m++) { + if (m == 0 && (game_state->doubled || game_state->player_score < game_state->settings.round_price)) continue; int y = m * 13 + 25; canvas_set_color(canvas, ColorBlack); - if(game_state->selectedMenu == m) { + if (game_state->selectedMenu == m) { canvas_set_color(canvas, ColorBlack); canvas_draw_box(canvas, 1, y, 31, 12); } else { @@ -54,7 +57,7 @@ void draw_play_menu(Canvas* const canvas, const GameState* game_state) { canvas_draw_frame(canvas, 1, y, 31, 12); } - if(game_state->selectedMenu == m) + if (game_state->selectedMenu == m) canvas_set_color(canvas, ColorWhite); else canvas_set_color(canvas, ColorBlack); @@ -62,34 +65,35 @@ void draw_play_menu(Canvas* const canvas, const GameState* game_state) { } } -void draw_screen(Canvas* const canvas, const bool* points) { - for(uint8_t x = 0; x < 128; x++) { - for(uint8_t y = 0; y < 64; y++) { - if(points[y * 128 + x]) canvas_draw_dot(canvas, x, y); +void draw_screen(Canvas *const canvas, const bool *points) { + for (uint8_t x = 0; x < 128; x++) { + for (uint8_t y = 0; y < 64; y++) { + if (points[y * 128 + x]) + canvas_draw_dot(canvas, x, y); } } } -void draw_score(Canvas* const canvas, bool top, uint8_t amount) { +void draw_score(Canvas *const canvas, bool top, uint8_t amount) { char drawChar[20]; snprintf(drawChar, sizeof(drawChar), "Player score: %i", amount); - if(top) + if (top) canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, drawChar); else canvas_draw_str_aligned(canvas, 64, 62, AlignCenter, AlignBottom, drawChar); } -void draw_money(Canvas* const canvas, uint32_t score) { +void draw_money(Canvas *const canvas, uint32_t score) { canvas_set_font(canvas, FontSecondary); char drawChar[10]; uint32_t currAmount = score; - if(currAmount < 1000) { + if (currAmount < 1000) { snprintf(drawChar, sizeof(drawChar), "$%lu", currAmount); } else { char c = 'K'; - for(uint8_t i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { currAmount = currAmount / 1000; - if(currAmount < 1000) { + if (currAmount < 1000) { c = MoneyMul[i]; break; } @@ -100,87 +104,77 @@ void draw_money(Canvas* const canvas, uint32_t score) { canvas_draw_str_aligned(canvas, 126, 2, AlignRight, AlignTop, drawChar); } -void draw_menu( - Canvas* const canvas, - const char* text, - const char* value, - int8_t y, - bool left_caret, - bool right_caret, - bool selected) { - UNUSED(selected); - if(y < 0 || y >= 64) return; - if(selected) { +void draw_menu(Canvas *const canvas, const char *text, const char *value, int8_t y, bool left_caret, bool right_caret, + bool selected) { + UNUSED(selected); + if (y < 0 || y >= 64) return; + + if (selected) { canvas_set_color(canvas, ColorBlack); canvas_draw_box(canvas, 0, y, 122, LINE_HEIGHT); canvas_set_color(canvas, ColorWhite); } canvas_draw_str_aligned(canvas, 4, y + ITEM_PADDING, AlignLeft, AlignTop, text); - if(left_caret) canvas_draw_str_aligned(canvas, 80, y + ITEM_PADDING, AlignLeft, AlignTop, "<"); + if (left_caret) + canvas_draw_str_aligned(canvas, 80, y + ITEM_PADDING, AlignLeft, AlignTop, "<"); canvas_draw_str_aligned(canvas, 100, y + ITEM_PADDING, AlignCenter, AlignTop, value); - if(right_caret) + if (right_caret) canvas_draw_str_aligned(canvas, 120, y + ITEM_PADDING, AlignRight, AlignTop, ">"); canvas_set_color(canvas, ColorBlack); } -void settings_page(Canvas* const canvas, const GameState* gameState) { +void settings_page(Canvas *const canvas, const GameState *gameState) { char drawChar[10]; int startY = 0; - if(LINE_HEIGHT * (gameState->selectedMenu + 1) >= 64) { + if (LINE_HEIGHT * (gameState->selectedMenu + 1) >= 64) { startY -= (LINE_HEIGHT * (gameState->selectedMenu + 1)) - 64; } int scrollHeight = round(64 / 6.0) + ITEM_PADDING * 2; int scrollPos = 64 / (6.0 / (gameState->selectedMenu + 1)) - ITEM_PADDING * 2; + canvas_set_color(canvas, ColorBlack); canvas_draw_box(canvas, 123, scrollPos, 4, scrollHeight); canvas_draw_box(canvas, 125, 0, 1, 64); snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.starting_money); - draw_menu( - canvas, - "Start money", - drawChar, - 0 * LINE_HEIGHT + startY, - gameState->settings.starting_money > gameState->settings.round_price, - gameState->settings.starting_money < 400, - gameState->selectedMenu == 0); + draw_menu(canvas, "Start money", drawChar, + 0 * LINE_HEIGHT + startY, + gameState->settings.starting_money > gameState->settings.round_price, + gameState->settings.starting_money < 400, + gameState->selectedMenu == 0 + ); snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.round_price); - draw_menu( - canvas, - "Round price", - drawChar, - 1 * LINE_HEIGHT + startY, - gameState->settings.round_price > 10, - gameState->settings.round_price < gameState->settings.starting_money, - gameState->selectedMenu == 1); + draw_menu(canvas, "Round price", drawChar, + 1 * LINE_HEIGHT + startY, + gameState->settings.round_price > 10, + gameState->settings.round_price < gameState->settings.starting_money, + gameState->selectedMenu == 1 + ); snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.animation_duration); - draw_menu( - canvas, - "Anim. length", - drawChar, - 2 * LINE_HEIGHT + startY, - gameState->settings.animation_duration > 0, - gameState->settings.animation_duration < 2000, - gameState->selectedMenu == 2); + draw_menu(canvas, "Anim. length", drawChar, + 2 * LINE_HEIGHT + startY, + gameState->settings.animation_duration > 0, + gameState->settings.animation_duration < 2000, + gameState->selectedMenu == 2 + ); snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.message_duration); - draw_menu( - canvas, - "Popup time", - drawChar, - 3 * LINE_HEIGHT + startY, - gameState->settings.message_duration > 0, - gameState->settings.message_duration < 2000, - gameState->selectedMenu == 3); - // draw_menu(canvas, "Sound", gameState->settings.sound_effects ? "Yes" : "No", - // 5 * LINE_HEIGHT + startY, - // true, - // true, - // gameState->selectedMenu == 5 - // ); + draw_menu(canvas, "Popup time", drawChar, + 3 * LINE_HEIGHT + startY, + gameState->settings.message_duration > 0, + gameState->settings.message_duration < 2000, + gameState->selectedMenu == 3 + ); +// draw_menu(canvas, "Sound", gameState->settings.sound_effects ? "Yes" : "No", +// 5 * LINE_HEIGHT + startY, +// true, +// true, +// gameState->selectedMenu == 5 +// ); + } \ No newline at end of file diff --git a/applications/plugins/blackjack/ui.h b/applications/plugins/blackjack/ui.h index 51b388010..5c20e0332 100644 --- a/applications/plugins/blackjack/ui.h +++ b/applications/plugins/blackjack/ui.h @@ -3,16 +3,16 @@ #include "defines.h" #include -void draw_player_scene(Canvas* const canvas, const GameState* game_state); +void draw_player_scene(Canvas *const canvas, const GameState *game_state); -void draw_dealer_scene(Canvas* const canvas, const GameState* game_state); +void draw_dealer_scene(Canvas *const canvas, const GameState *game_state); -void draw_play_menu(Canvas* const canvas, const GameState* game_state); +void draw_play_menu(Canvas *const canvas, const GameState *game_state); -void draw_score(Canvas* const canvas, bool top, uint8_t amount); +void draw_score(Canvas *const canvas, bool top, uint8_t amount); -void draw_money(Canvas* const canvas, uint32_t score); -void settings_page(Canvas* const canvas, const GameState* gameState); +void draw_money(Canvas *const canvas, uint32_t score); +void settings_page(Canvas *const canvas, const GameState * gameState); -void popup_frame(Canvas* const canvas); -void draw_screen(Canvas* const canvas, const bool* points); +void popup_frame(Canvas *const canvas); +void draw_screen(Canvas *const canvas, const bool* points); diff --git a/applications/plugins/blackjack/util.c b/applications/plugins/blackjack/util.c index 8e88c2231..563507a4d 100644 --- a/applications/plugins/blackjack/util.c +++ b/applications/plugins/blackjack/util.c @@ -1,17 +1,16 @@ #include #include "util.h" -const char* CONFIG_FILE_PATH = EXT_PATH(".blackjack.settings"); +const char *CONFIG_FILE_PATH = EXT_PATH(".blackjack.settings"); void save_settings(Settings settings) { - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* file = flipper_format_file_alloc(storage); + Storage *storage = furi_record_open(RECORD_STORAGE); + FlipperFormat *file = flipper_format_file_alloc(storage); FURI_LOG_D(APP_NAME, "Saving config"); - if(flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { - FURI_LOG_D( - APP_NAME, "Saving %s: %ld", CONF_ANIMATION_DURATION, settings.animation_duration); - flipper_format_update_uint32( - file, CONF_ANIMATION_DURATION, &(settings.animation_duration), 1); + if (flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { + FURI_LOG_D(APP_NAME, "Saving %s: %ld", CONF_ANIMATION_DURATION, settings.animation_duration); + flipper_format_update_uint32(file, CONF_ANIMATION_DURATION, &(settings.animation_duration), 1); + FURI_LOG_D(APP_NAME, "Saving %s: %ld", CONF_MESSAGE_DURATION, settings.message_duration); flipper_format_update_uint32(file, CONF_MESSAGE_DURATION, &(settings.message_duration), 1); @@ -22,10 +21,10 @@ void save_settings(Settings settings) { FURI_LOG_D(APP_NAME, "Saving %s: %ld", CONF_ROUND_PRICE, settings.round_price); flipper_format_update_uint32(file, CONF_ROUND_PRICE, &(settings.round_price), 1); - FURI_LOG_D(APP_NAME, "Saving %s: %i", CONF_SOUND_EFFECTS, settings.sound_effects ? 1 : 0); + FURI_LOG_D(APP_NAME, "Saving %s: %i", CONF_SOUND_EFFECTS, settings.sound_effects?1:0); flipper_format_update_bool(file, CONF_SOUND_EFFECTS, &(settings.sound_effects), 1); FURI_LOG_D(APP_NAME, "Config saved"); - } else { + }else{ FURI_LOG_E(APP_NAME, "Save error"); } flipper_format_file_close(file); @@ -33,7 +32,7 @@ void save_settings(Settings settings) { furi_record_close(RECORD_STORAGE); } -void save_settings_file(FlipperFormat* file, Settings* settings) { +void save_settings_file(FlipperFormat *file, Settings *settings) { flipper_format_write_header_cstr(file, CONFIG_FILE_HEADER, CONFIG_FILE_VERSION); flipper_format_write_comment_cstr(file, "Card animation duration in ms"); flipper_format_write_uint32(file, CONF_ANIMATION_DURATION, &(settings->animation_duration), 1); @@ -58,57 +57,58 @@ Settings load_settings() { settings.sound_effects = true; FURI_LOG_D(APP_NAME, "Opening storage"); - Storage* storage = furi_record_open(RECORD_STORAGE); + Storage *storage = furi_record_open(RECORD_STORAGE); FURI_LOG_D(APP_NAME, "Allocating file"); - FlipperFormat* file = flipper_format_file_alloc(storage); + FlipperFormat *file = flipper_format_file_alloc(storage); FURI_LOG_D(APP_NAME, "Allocating string"); - FuriString* string_value; + FuriString *string_value; string_value = furi_string_alloc(); - if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) != FSE_OK) { + if (storage_common_stat(storage, CONFIG_FILE_PATH, NULL) != FSE_OK) { FURI_LOG_D(APP_NAME, "Config file %s not found, creating new one...", CONFIG_FILE_PATH); - if(!flipper_format_file_open_new(file, CONFIG_FILE_PATH)) { + if (!flipper_format_file_open_new(file, CONFIG_FILE_PATH)) { FURI_LOG_E(APP_NAME, "Error creating new file %s", CONFIG_FILE_PATH); flipper_format_file_close(file); } else { save_settings_file(file, &settings); } } else { - if(!flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { + if (!flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { FURI_LOG_E(APP_NAME, "Error opening existing file %s", CONFIG_FILE_PATH); flipper_format_file_close(file); - } else { + } + else { uint32_t value; bool valueBool; FURI_LOG_D(APP_NAME, "Checking version"); - if(!flipper_format_read_header(file, string_value, &value)) { + if (!flipper_format_read_header(file, string_value, &value)) { FURI_LOG_E(APP_NAME, "Config file mismatch"); } else { FURI_LOG_D(APP_NAME, "Loading %s", CONF_ANIMATION_DURATION); - if(flipper_format_read_uint32(file, CONF_ANIMATION_DURATION, &value, 1)) { + if (flipper_format_read_uint32(file, CONF_ANIMATION_DURATION, &value, 1)) { settings.animation_duration = value; FURI_LOG_D(APP_NAME, "Loaded %s: %ld", CONF_ANIMATION_DURATION, value); } FURI_LOG_D(APP_NAME, "Loading %s", CONF_MESSAGE_DURATION); - if(flipper_format_read_uint32(file, CONF_MESSAGE_DURATION, &value, 1)) { + if (flipper_format_read_uint32(file, CONF_MESSAGE_DURATION, &value, 1)) { settings.message_duration = value; FURI_LOG_D(APP_NAME, "Loaded %s: %ld", CONF_MESSAGE_DURATION, value); } FURI_LOG_D(APP_NAME, "Loading %s", CONF_STARTING_MONEY); - if(flipper_format_read_uint32(file, CONF_STARTING_MONEY, &value, 1)) { + if (flipper_format_read_uint32(file, CONF_STARTING_MONEY, &value, 1)) { settings.starting_money = value; FURI_LOG_D(APP_NAME, "Loaded %s: %ld", CONF_STARTING_MONEY, value); } FURI_LOG_D(APP_NAME, "Loading %s", CONF_ROUND_PRICE); - if(flipper_format_read_uint32(file, CONF_ROUND_PRICE, &value, 1)) { + if (flipper_format_read_uint32(file, CONF_ROUND_PRICE, &value, 1)) { settings.round_price = value; FURI_LOG_D(APP_NAME, "Loaded %s: %ld", CONF_ROUND_PRICE, value); } FURI_LOG_D(APP_NAME, "Loading %s", CONF_SOUND_EFFECTS); - if(flipper_format_read_bool(file, CONF_SOUND_EFFECTS, &valueBool, 1)) { + if (flipper_format_read_bool(file, CONF_SOUND_EFFECTS, &valueBool, 1)) { settings.sound_effects = valueBool; - FURI_LOG_D(APP_NAME, "Loaded %s: %i", CONF_ROUND_PRICE, valueBool ? 1 : 0); + FURI_LOG_D(APP_NAME, "Loaded %s: %i", CONF_ROUND_PRICE, valueBool?1:0); } } flipper_format_file_close(file); @@ -116,7 +116,7 @@ Settings load_settings() { } furi_string_free(string_value); - // flipper_format_file_close(file); +// flipper_format_file_close(file); flipper_format_free(file); furi_record_close(RECORD_STORAGE); return settings;