mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 19:58:36 -07:00
blackjack upd
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
App(
|
App(
|
||||||
appid="BlackJack",
|
appid="blackjack",
|
||||||
name="BlackJack",
|
name="Blackjack",
|
||||||
apptype=FlipperAppType.EXTERNAL,
|
apptype=FlipperAppType.EXTERNAL,
|
||||||
entry_point="blackjack_app",
|
entry_point="blackjack_app",
|
||||||
cdefines=["APP_BLACKJACK"],
|
cdefines=["APP_BLACKJACK"],
|
||||||
requires=["gui","storage"],
|
requires=["gui","storage","canvas"],
|
||||||
stack_size=2 * 1024,
|
stack_size=2 * 1024,
|
||||||
order=30,
|
order=30,
|
||||||
fap_icon="blackjack_10px.png",
|
fap_icon="blackjack_10px.png",
|
||||||
|
|||||||
BIN
applications/plugins/blackjack/assets/card_graphics.png
Normal file
BIN
applications/plugins/blackjack/assets/card_graphics.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 409 B |
@@ -3,6 +3,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <dolphin/dolphin.h>
|
#include <dolphin/dolphin.h>
|
||||||
#include <dialogs/dialogs.h>
|
#include <dialogs/dialogs.h>
|
||||||
|
#include <gui/canvas_i.h>
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
@@ -12,7 +14,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
|
||||||
#include "BlackJack_icons.h"
|
#include "blackjack_icons.h"
|
||||||
|
|
||||||
#define DEALER_MAX 17
|
#define DEALER_MAX 17
|
||||||
|
|
||||||
@@ -21,6 +23,7 @@ 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_money(canvas, game_state->player_score);
|
||||||
|
|
||||||
draw_score(canvas, true, hand_count(game_state->player_cards, game_state->player_card_count));
|
draw_score(canvas, true, hand_count(game_state->player_cards, game_state->player_card_count));
|
||||||
@@ -68,6 +71,7 @@ Card draw_card(GameState* game_state) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void drawPlayerCard(void *ctx) {
|
void drawPlayerCard(void *ctx) {
|
||||||
GameState *game_state = ctx;
|
GameState *game_state = ctx;
|
||||||
Card c = draw_card(game_state);
|
Card c = draw_card(game_state);
|
||||||
@@ -89,42 +93,48 @@ void drawDealerCard(void* ctx) {
|
|||||||
//region queue callbacks
|
//region queue callbacks
|
||||||
void to_lose_state(const void *ctx, Canvas *const canvas) {
|
void to_lose_state(const void *ctx, Canvas *const canvas) {
|
||||||
const GameState *game_state = ctx;
|
const GameState *game_state = ctx;
|
||||||
if(game_state->settings.message_duration == 0) return;
|
if (game_state->settings.message_duration == 0)
|
||||||
|
return;
|
||||||
popup_frame(canvas);
|
popup_frame(canvas);
|
||||||
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "You lost");
|
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "You lost");
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_bust_state(const void *ctx, Canvas *const canvas) {
|
void to_bust_state(const void *ctx, Canvas *const canvas) {
|
||||||
const GameState *game_state = ctx;
|
const GameState *game_state = ctx;
|
||||||
if(game_state->settings.message_duration == 0) return;
|
if (game_state->settings.message_duration == 0)
|
||||||
|
return;
|
||||||
popup_frame(canvas);
|
popup_frame(canvas);
|
||||||
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Busted!");
|
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Busted!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_draw_state(const void *ctx, Canvas *const canvas) {
|
void to_draw_state(const void *ctx, Canvas *const canvas) {
|
||||||
const GameState *game_state = ctx;
|
const GameState *game_state = ctx;
|
||||||
if(game_state->settings.message_duration == 0) return;
|
if (game_state->settings.message_duration == 0)
|
||||||
|
return;
|
||||||
popup_frame(canvas);
|
popup_frame(canvas);
|
||||||
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Draw");
|
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Draw");
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_dealer_turn(const void *ctx, Canvas *const canvas) {
|
void to_dealer_turn(const void *ctx, Canvas *const canvas) {
|
||||||
const GameState *game_state = ctx;
|
const GameState *game_state = ctx;
|
||||||
if(game_state->settings.message_duration == 0) return;
|
if (game_state->settings.message_duration == 0)
|
||||||
|
return;
|
||||||
popup_frame(canvas);
|
popup_frame(canvas);
|
||||||
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Dealers turn");
|
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Dealers turn");
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_win_state(const void *ctx, Canvas *const canvas) {
|
void to_win_state(const void *ctx, Canvas *const canvas) {
|
||||||
const GameState *game_state = ctx;
|
const GameState *game_state = ctx;
|
||||||
if(game_state->settings.message_duration == 0) return;
|
if (game_state->settings.message_duration == 0)
|
||||||
|
return;
|
||||||
popup_frame(canvas);
|
popup_frame(canvas);
|
||||||
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "You win");
|
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "You win");
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_start(const void *ctx, Canvas *const canvas) {
|
void to_start(const void *ctx, Canvas *const canvas) {
|
||||||
const GameState *game_state = ctx;
|
const GameState *game_state = ctx;
|
||||||
if(game_state->settings.message_duration == 0) return;
|
if (game_state->settings.message_duration == 0)
|
||||||
|
return;
|
||||||
popup_frame(canvas);
|
popup_frame(canvas);
|
||||||
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Round started");
|
elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Round started");
|
||||||
}
|
}
|
||||||
@@ -135,6 +145,7 @@ void before_start(void* ctx) {
|
|||||||
game_state->player_card_count = 0;
|
game_state->player_card_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void start(void *ctx) {
|
void start(void *ctx) {
|
||||||
GameState *game_state = ctx;
|
GameState *game_state = ctx;
|
||||||
start_round(game_state);
|
start_round(game_state);
|
||||||
@@ -144,12 +155,7 @@ void draw(void* ctx) {
|
|||||||
GameState *game_state = ctx;
|
GameState *game_state = ctx;
|
||||||
game_state->player_score += game_state->bet;
|
game_state->player_score += game_state->bet;
|
||||||
game_state->bet = 0;
|
game_state->bet = 0;
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, start, before_start, to_start,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
start,
|
|
||||||
before_start,
|
|
||||||
to_start,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,15 +169,11 @@ void lose(void* ctx) {
|
|||||||
game_state->state = GameStatePlay;
|
game_state->state = GameStatePlay;
|
||||||
game_state->bet = 0;
|
game_state->bet = 0;
|
||||||
if (game_state->player_score >= game_state->settings.round_price) {
|
if (game_state->player_score >= game_state->settings.round_price) {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, start, before_start, to_start,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
start,
|
|
||||||
before_start,
|
|
||||||
to_start,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
} else {
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,15 +182,11 @@ void win(void* ctx) {
|
|||||||
game_state->state = GameStatePlay;
|
game_state->state = GameStatePlay;
|
||||||
game_state->player_score += game_state->bet * 2;
|
game_state->player_score += game_state->bet * 2;
|
||||||
game_state->bet = 0;
|
game_state->bet = 0;
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, start, before_start, to_start,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
start,
|
|
||||||
before_start,
|
|
||||||
to_start,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dealerTurn(void *ctx) {
|
void dealerTurn(void *ctx) {
|
||||||
GameState *game_state = ctx;
|
GameState *game_state = ctx;
|
||||||
game_state->state = GameStateDealer;
|
game_state->state = GameStateDealer;
|
||||||
@@ -206,17 +204,21 @@ void dealer_card_animation(const void* ctx, Canvas* const canvas) {
|
|||||||
Card animatingCard = game_state->deck.cards[game_state->deck.index];
|
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);
|
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 {
|
} else {
|
||||||
draw_card_animation(
|
draw_card_animation(animatingCard,
|
||||||
animatingCard,
|
|
||||||
(Vector) {32, -CARD_HEIGHT},
|
(Vector) {32, -CARD_HEIGHT},
|
||||||
(Vector) {64, 32},
|
(Vector) {64, 32},
|
||||||
(Vector) {2, 2},
|
(Vector) {2, 2},
|
||||||
t,
|
t,
|
||||||
false,
|
false,
|
||||||
canvas);
|
canvas);
|
||||||
// draw_deck(game_state->dealer_cards, game_state->dealer_card_count, canvas);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,8 +226,7 @@ void dealer_back_card_animation(const void* ctx, Canvas* const canvas) {
|
|||||||
const GameState *game_state = ctx;
|
const GameState *game_state = ctx;
|
||||||
float t = animationTime(game_state);
|
float t = animationTime(game_state);
|
||||||
|
|
||||||
Vector currentPos =
|
Vector currentPos = quadratic_2d((Vector) {32, -CARD_HEIGHT}, (Vector) {64, 32}, (Vector) {13, 5}, t);
|
||||||
quadratic_2d((Vector){32, -CARD_HEIGHT}, (Vector){64, 32}, (Vector){13, 5}, t);
|
|
||||||
draw_card_back_at(currentPos.x, currentPos.y, canvas);
|
draw_card_back_at(currentPos.x, currentPos.y, canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,38 +237,32 @@ void player_card_animation(const void* ctx, Canvas* const canvas) {
|
|||||||
Card animatingCard = game_state->deck.cards[game_state->deck.index];
|
Card animatingCard = game_state->deck.cards[game_state->deck.index];
|
||||||
Vector end = card_pos_at_index(game_state->player_card_count);
|
Vector end = card_pos_at_index(game_state->player_card_count);
|
||||||
|
|
||||||
draw_card_animation(
|
draw_card_animation(animatingCard,
|
||||||
animatingCard, (Vector){32, -CARD_HEIGHT}, (Vector){0, 32}, end, t, true, canvas);
|
(Vector) {32, -CARD_HEIGHT},
|
||||||
// draw_deck(game_state->dealer_cards, game_state->player_card_count, canvas);
|
(Vector) {0, 32},
|
||||||
|
end,
|
||||||
|
t,
|
||||||
|
true,
|
||||||
|
canvas);
|
||||||
}
|
}
|
||||||
//endregion
|
//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);
|
uint8_t score = hand_count(game_state->player_cards, game_state->player_card_count);
|
||||||
if ((game_state->doubled && score <= 21) || score == 21) {
|
if ((game_state->doubled && score <= 21) || score == 21) {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, dealerTurn, NULL, to_dealer_turn,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
dealerTurn,
|
|
||||||
NULL,
|
|
||||||
to_dealer_turn,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
} else if (score > 21) {
|
} else if (score > 21) {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, lose, NULL, to_bust_state,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
lose,
|
|
||||||
NULL,
|
|
||||||
to_bust_state,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
} else {
|
} else {
|
||||||
if(game_state->selectDirection == DirectionUp ||
|
if(game_state->selectDirection == DirectionUp || game_state->selectDirection == DirectionDown){
|
||||||
game_state->selectDirection == DirectionDown) {
|
|
||||||
move_menu(game_state->menu, game_state->selectDirection == DirectionUp ? -1 : 1);
|
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);
|
activate_menu(game_state->menu, game_state);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,37 +273,17 @@ void dealer_tick(GameState* game_state) {
|
|||||||
|
|
||||||
if (dealer_score >= DEALER_MAX) {
|
if (dealer_score >= DEALER_MAX) {
|
||||||
if (dealer_score > 21 || dealer_score < player_score) {
|
if (dealer_score > 21 || dealer_score < player_score) {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, win, NULL, to_win_state,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
win,
|
|
||||||
NULL,
|
|
||||||
to_win_state,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
} else if (dealer_score > player_score) {
|
} else if (dealer_score > player_score) {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, lose, NULL, to_lose_state,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
lose,
|
|
||||||
NULL,
|
|
||||||
to_lose_state,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
} else if (dealer_score == player_score) {
|
} else if (dealer_score == player_score) {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, draw, NULL, to_draw_state,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
draw,
|
|
||||||
NULL,
|
|
||||||
to_draw_state,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, drawDealerCard, NULL, dealer_card_animation,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
drawDealerCard,
|
|
||||||
NULL,
|
|
||||||
dealer_card_animation,
|
|
||||||
game_state->settings.animation_duration);
|
game_state->settings.animation_duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -321,8 +296,7 @@ void settings_tick(GameState* game_state) {
|
|||||||
game_state->selectedMenu--;
|
game_state->selectedMenu--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(game_state->selectDirection == DirectionLeft ||
|
if (game_state->selectDirection == DirectionLeft || game_state->selectDirection == DirectionRight) {
|
||||||
game_state->selectDirection == DirectionRight) {
|
|
||||||
int nextScore = 0;
|
int nextScore = 0;
|
||||||
switch (game_state->selectedMenu) {
|
switch (game_state->selectedMenu) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -367,6 +341,7 @@ void settings_tick(GameState* game_state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tick(GameState *game_state) {
|
void tick(GameState *game_state) {
|
||||||
@@ -387,39 +362,21 @@ void tick(GameState* game_state) {
|
|||||||
if (!game_state->started) {
|
if (!game_state->started) {
|
||||||
game_state->selectedMenu = 0;
|
game_state->selectedMenu = 0;
|
||||||
game_state->started = true;
|
game_state->started = true;
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, drawDealerCard, NULL, dealer_back_card_animation,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
drawDealerCard,
|
|
||||||
NULL,
|
|
||||||
dealer_back_card_animation,
|
|
||||||
game_state->settings.animation_duration);
|
game_state->settings.animation_duration);
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, drawPlayerCard, NULL, player_card_animation,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
drawPlayerCard,
|
|
||||||
NULL,
|
|
||||||
player_card_animation,
|
|
||||||
game_state->settings.animation_duration);
|
game_state->settings.animation_duration);
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, drawDealerCard, NULL, dealer_card_animation,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
drawDealerCard,
|
|
||||||
NULL,
|
|
||||||
dealer_card_animation,
|
|
||||||
game_state->settings.animation_duration);
|
game_state->settings.animation_duration);
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, drawPlayerCard, NULL, player_card_animation,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
drawPlayerCard,
|
|
||||||
NULL,
|
|
||||||
player_card_animation,
|
|
||||||
game_state->settings.animation_duration);
|
game_state->settings.animation_duration);
|
||||||
}
|
}
|
||||||
if(!queue_ran) player_tick(game_state);
|
if (!queue_ran)
|
||||||
|
player_tick(game_state);
|
||||||
break;
|
break;
|
||||||
case GameStateDealer:
|
case GameStateDealer:
|
||||||
if(!queue_ran) dealer_tick(game_state);
|
if (!queue_ran)
|
||||||
|
dealer_tick(game_state);
|
||||||
break;
|
break;
|
||||||
case GameStateSettings:
|
case GameStateSettings:
|
||||||
settings_tick(game_state);
|
settings_tick(game_state);
|
||||||
@@ -429,6 +386,7 @@ void tick(GameState* game_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
game_state->selectDirection = None;
|
game_state->selectDirection = None;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_round(GameState *game_state) {
|
void start_round(GameState *game_state) {
|
||||||
@@ -482,31 +440,15 @@ void doubleAction(void* state) {
|
|||||||
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->bet += game_state->settings.round_price;
|
||||||
game_state->doubled = true;
|
game_state->doubled = true;
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, drawPlayerCard, NULL, player_card_animation,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
drawPlayerCard,
|
|
||||||
NULL,
|
|
||||||
player_card_animation,
|
|
||||||
game_state->settings.animation_duration);
|
game_state->settings.animation_duration);
|
||||||
game_state->player_cards[game_state->player_card_count] =
|
game_state->player_cards[game_state->player_card_count] = game_state->deck.cards[game_state->deck.index];
|
||||||
game_state->deck.cards[game_state->deck.index];
|
|
||||||
uint8_t score = hand_count(game_state->player_cards, game_state->player_card_count + 1);
|
uint8_t score = hand_count(game_state->player_cards, game_state->player_card_count + 1);
|
||||||
if (score > 21) {
|
if (score > 21) {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, lose, NULL, to_bust_state,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
lose,
|
|
||||||
NULL,
|
|
||||||
to_bust_state,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
} else {
|
} else {
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, dealerTurn, NULL, to_dealer_turn,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
dealerTurn,
|
|
||||||
NULL,
|
|
||||||
to_dealer_turn,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
}
|
}
|
||||||
set_menu_state(game_state->menu, 0, false);
|
set_menu_state(game_state->menu, 0, false);
|
||||||
@@ -515,22 +457,12 @@ void doubleAction(void* state) {
|
|||||||
|
|
||||||
void hitAction(void *state){
|
void hitAction(void *state){
|
||||||
GameState *game_state = state;
|
GameState *game_state = state;
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, drawPlayerCard, NULL, player_card_animation,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
drawPlayerCard,
|
|
||||||
NULL,
|
|
||||||
player_card_animation,
|
|
||||||
game_state->settings.animation_duration);
|
game_state->settings.animation_duration);
|
||||||
}
|
}
|
||||||
void stayAction(void *state){
|
void stayAction(void *state){
|
||||||
GameState *game_state = state;
|
GameState *game_state = state;
|
||||||
enqueue(
|
enqueue(&(game_state->queue_state), game_state, dealerTurn, NULL, to_dealer_turn,
|
||||||
&(game_state->queue_state),
|
|
||||||
game_state,
|
|
||||||
dealerTurn,
|
|
||||||
NULL,
|
|
||||||
to_dealer_turn,
|
|
||||||
game_state->settings.message_duration);
|
game_state->settings.message_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,6 +480,7 @@ int32_t blackjack_app(void* p) {
|
|||||||
add_menu(game_state->menu, "Double", doubleAction);
|
add_menu(game_state->menu, "Double", doubleAction);
|
||||||
add_menu(game_state->menu, "Hit", hitAction);
|
add_menu(game_state->menu, "Hit", hitAction);
|
||||||
add_menu(game_state->menu, "Stay", stayAction);
|
add_menu(game_state->menu, "Stay", stayAction);
|
||||||
|
set_card_graphics(&I_card_graphics);
|
||||||
|
|
||||||
game_state->state = GameStateStart;
|
game_state->state = GameStateStart;
|
||||||
|
|
||||||
@@ -562,7 +495,8 @@ int32_t blackjack_app(void* p) {
|
|||||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
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);
|
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 25);
|
||||||
|
|
||||||
Gui *gui = furi_record_open("gui");
|
Gui *gui = furi_record_open("gui");
|
||||||
@@ -575,6 +509,7 @@ int32_t blackjack_app(void* p) {
|
|||||||
GameState *localstate = (GameState *) acquire_mutex_block(&state_mutex);
|
GameState *localstate = (GameState *) acquire_mutex_block(&state_mutex);
|
||||||
if (event_status == FuriStatusOk) {
|
if (event_status == FuriStatusOk) {
|
||||||
if (event.type == EventTypeKey) {
|
if (event.type == EventTypeKey) {
|
||||||
|
|
||||||
if (event.input.type == InputTypePress) {
|
if (event.input.type == InputTypePress) {
|
||||||
switch (event.input.key) {
|
switch (event.input.key) {
|
||||||
case InputKeyUp:
|
case InputKeyUp:
|
||||||
@@ -615,6 +550,7 @@ int32_t blackjack_app(void* p) {
|
|||||||
release_mutex(&state_mutex, localstate);
|
release_mutex(&state_mutex, localstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
furi_timer_free(timer);
|
furi_timer_free(timer);
|
||||||
view_port_enabled_set(view_port, false);
|
view_port_enabled_set(view_port, false);
|
||||||
gui_remove_view_port(gui, view_port);
|
gui_remove_view_port(gui, view_port);
|
||||||
@@ -623,6 +559,7 @@ int32_t blackjack_app(void* p) {
|
|||||||
delete_mutex(&state_mutex);
|
delete_mutex(&state_mutex);
|
||||||
|
|
||||||
free_and_exit:
|
free_and_exit:
|
||||||
|
free(game_state->deck.cards);
|
||||||
free_menu(game_state->menu);
|
free_menu(game_state->menu);
|
||||||
queue_clear(&(game_state->queue_state));
|
queue_clear(&(game_state->queue_state));
|
||||||
free(game_state);
|
free(game_state);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "card.h"
|
#include "card.h"
|
||||||
#include "dml.h"
|
#include "dml.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
#define CORNER_MARGIN 3
|
|
||||||
#define CARD_DRAW_X_START 108
|
#define CARD_DRAW_X_START 108
|
||||||
#define CARD_DRAW_Y_START 38
|
#define CARD_DRAW_Y_START 38
|
||||||
#define CARD_DRAW_X_SPACE 10
|
#define CARD_DRAW_X_SPACE 10
|
||||||
@@ -9,21 +9,27 @@
|
|||||||
#define CARD_DRAW_X_OFFSET 4
|
#define CARD_DRAW_X_OFFSET 4
|
||||||
#define CARD_DRAW_FIRST_ROW_LENGTH 7
|
#define CARD_DRAW_FIRST_ROW_LENGTH 7
|
||||||
|
|
||||||
bool pips[4][49] = {
|
uint8_t pips[4][3] = {
|
||||||
{//spades
|
{21, 10, 7}, //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,
|
{7, 10, 7}, //hearts
|
||||||
1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
|
{0, 10, 7}, //diamonds
|
||||||
{
|
{14, 10, 7}, //clubs
|
||||||
//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,
|
uint8_t letters[13][3] = {
|
||||||
1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
{0, 0, 5},
|
||||||
},
|
{5, 0, 5},
|
||||||
{//diamonds
|
{10, 0, 5},
|
||||||
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,
|
{15, 0, 5},
|
||||||
1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
|
{20, 0, 5},
|
||||||
{//clubs
|
{25, 0, 5},
|
||||||
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,
|
{30, 0, 5},
|
||||||
1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0}};
|
{0, 5, 5},
|
||||||
|
{5, 5, 5},
|
||||||
|
{10, 5, 5},
|
||||||
|
{15, 5, 5},
|
||||||
|
{20, 5, 5},
|
||||||
|
{25, 5, 5},
|
||||||
|
};
|
||||||
|
|
||||||
//region Player card positions
|
//region Player card positions
|
||||||
uint8_t playerCardPositions[22][4] = {
|
uint8_t playerCardPositions[22][4] = {
|
||||||
@@ -53,99 +59,84 @@ uint8_t playerCardPositions[22][4] = {
|
|||||||
{49, 14},
|
{49, 14},
|
||||||
};
|
};
|
||||||
//endregion
|
//endregion
|
||||||
|
Icon *card_graphics = NULL;
|
||||||
|
|
||||||
bool get_pip_pixel(uint8_t pip, uint8_t x, uint8_t y) {
|
void set_card_graphics(const Icon *graphics) {
|
||||||
return pips[pip][x + y * 7];
|
card_graphics = (Icon *) graphics;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
uint8_t *drawInfo = pips[pip];
|
||||||
|
uint8_t px = drawInfo[0], py = drawInfo[1], s = drawInfo[2];
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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_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) {
|
||||||
canvas_set_color(canvas, ColorWhite);
|
draw_card_at_colored(pos_x, pos_y, pip, character, false, canvas);
|
||||||
canvas_draw_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT);
|
|
||||||
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
canvas_draw_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_deck(const Card *cards, uint8_t count, Canvas *const canvas) {
|
void draw_deck(const Card *cards, uint8_t count, Canvas *const canvas) {
|
||||||
for (int i = count - 1; i >= 0; i--) {
|
for (int i = count - 1; i >= 0; i--) {
|
||||||
draw_card_at(
|
draw_card_at(playerCardPositions[i][0], playerCardPositions[i][1], cards[i].pip, cards[i].character, canvas);
|
||||||
playerCardPositions[i][0],
|
|
||||||
playerCardPositions[i][1],
|
|
||||||
cards[i].pip,
|
|
||||||
cards[i].character,
|
|
||||||
canvas);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector card_pos_at_index(uint8_t index) {
|
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) {
|
void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas *const canvas) {
|
||||||
canvas_set_color(canvas, ColorWhite);
|
draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, White);
|
||||||
canvas_draw_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT);
|
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;
|
uint16_t counter = 0;
|
||||||
|
if (deck_ptr->cards == NULL) {
|
||||||
deck_ptr->deck_count = deck_count;
|
deck_ptr->deck_count = deck_count;
|
||||||
deck_ptr->cards = malloc(sizeof(Card) * 52 * 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 deck = 0; deck < deck_count; deck++) {
|
||||||
for (uint8_t pip = 0; pip < 4; pip++) {
|
for (uint8_t pip = 0; pip < 4; pip++) {
|
||||||
for (uint8_t label = 0; label < 13; label++) {
|
for (uint8_t label = 0; label < 13; label++) {
|
||||||
deck_ptr->cards[counter] = (Card){pip, label};
|
deck_ptr->cards[counter] = (Card)
|
||||||
|
{
|
||||||
|
pip, label, false, false
|
||||||
|
};
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,22 +171,14 @@ uint8_t hand_count(const Card* cards, uint8_t count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t i = 0; i < aceCount; i++) {
|
for (uint8_t i = 0; i < aceCount; i++) {
|
||||||
if((score + 11) <= 21)
|
if ((score + 11) <= 21) score += 11;
|
||||||
score += 11;
|
else score++;
|
||||||
else
|
|
||||||
score++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_card_animation(
|
void draw_card_animation(Card animatingCard, Vector from, Vector control, Vector to, float t, bool extra_margin,
|
||||||
Card animatingCard,
|
|
||||||
Vector from,
|
|
||||||
Vector control,
|
|
||||||
Vector to,
|
|
||||||
float t,
|
|
||||||
bool extra_margin,
|
|
||||||
Canvas *const canvas) {
|
Canvas *const canvas) {
|
||||||
float time = t;
|
float time = t;
|
||||||
if (extra_margin) {
|
if (extra_margin) {
|
||||||
@@ -204,13 +187,144 @@ void draw_card_animation(
|
|||||||
|
|
||||||
Vector currentPos = quadratic_2d(from, control, to, time);
|
Vector currentPos = quadratic_2d(from, control, to, time);
|
||||||
if (t > 1) {
|
if (t > 1) {
|
||||||
draw_card_at(
|
draw_card_at(currentPos.x, currentPos.y, animatingCard.pip,
|
||||||
currentPos.x, currentPos.y, animatingCard.pip, animatingCard.character, canvas);
|
animatingCard.character, canvas);
|
||||||
} else {
|
} else {
|
||||||
if (t < 0.5)
|
if (t < 0.5)
|
||||||
draw_card_back_at(currentPos.x, currentPos.y, canvas);
|
draw_card_back_at(currentPos.x, currentPos.y, canvas);
|
||||||
else
|
else
|
||||||
draw_card_at(
|
draw_card_at(currentPos.x, currentPos.y, animatingCard.pip,
|
||||||
currentPos.x, currentPos.y, animatingCard.pip, animatingCard.character, canvas);
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,24 +5,35 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "dml.h"
|
#include "dml.h"
|
||||||
|
|
||||||
#define CARD_HEIGHT 24
|
#define CARD_HEIGHT 23
|
||||||
#define CARD_HALF_HEIGHT CARD_HEIGHT / 2
|
#define CARD_HALF_HEIGHT 11
|
||||||
#define CARD_WIDTH 18
|
#define CARD_WIDTH 17
|
||||||
#define CARD_HALF_WIDTH CARD_WIDTH / 2
|
#define CARD_HALF_WIDTH 8
|
||||||
|
|
||||||
//region types
|
//region types
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t pip; //Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs
|
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 character; //Card letter [0-12], 0 means 2, 12 is Ace
|
||||||
|
bool disabled;
|
||||||
|
bool flipped;
|
||||||
} Card;
|
} Card;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t deck_count; //Number of decks used
|
uint8_t deck_count; //Number of decks used
|
||||||
Card *cards; //Cards in the deck
|
Card *cards; //Cards in the deck
|
||||||
|
int card_count;
|
||||||
int index; //Card index (to know where we at in the deck)
|
int index; //Card index (to know where we at in the deck)
|
||||||
} 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
|
//endregion
|
||||||
|
|
||||||
|
void set_card_graphics(const Icon *graphics);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets card coordinates at the index (range: 0-20).
|
* Gets card coordinates at the index (range: 0-20).
|
||||||
*
|
*
|
||||||
@@ -42,6 +53,19 @@ Vector card_pos_at_index(uint8_t index);
|
|||||||
*/
|
*/
|
||||||
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
|
* Draws 'count' cards at the bottom right corner
|
||||||
*
|
*
|
||||||
@@ -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 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
|
* @param canvas Pointer to Flipper's canvas object
|
||||||
*/
|
*/
|
||||||
void draw_card_animation(
|
void draw_card_animation(Card animatingCard, Vector from, Vector control, Vector to, float t, bool extra_margin,
|
||||||
Card animatingCard,
|
|
||||||
Vector from,
|
|
||||||
Vector control,
|
|
||||||
Vector to,
|
|
||||||
float t,
|
|
||||||
bool extra_margin,
|
|
||||||
Canvas *const canvas);
|
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);
|
||||||
@@ -14,7 +14,11 @@ Vector lerp_2d(Vector start, Vector end, float t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector quadratic_2d(Vector start, Vector control, Vector end, float 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) {
|
Vector vector_add(Vector a, Vector b) {
|
||||||
@@ -35,7 +39,10 @@ Vector vector_div_components(Vector a, Vector b) {
|
|||||||
|
|
||||||
Vector vector_normalized(Vector a) {
|
Vector vector_normalized(Vector a) {
|
||||||
float length = vector_magnitude(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) {
|
float vector_magnitude(Vector a) {
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ typedef struct {
|
|||||||
float y;
|
float y;
|
||||||
} Vector;
|
} 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
|
* Lerp function
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,31 +22,21 @@ void set_menu_state(Menu* menu, uint8_t index, bool state) {
|
|||||||
if (menu->menu_count > index) {
|
if (menu->menu_count > index) {
|
||||||
menu->items[index].enabled = state;
|
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) {
|
void move_menu(Menu *menu, int8_t direction) {
|
||||||
if (!menu->enabled) return;
|
if (!menu->enabled) return;
|
||||||
int max = menu->menu_count;
|
int max = menu->menu_count;
|
||||||
for (int8_t i = 0; i < max; i++) {
|
for (int8_t i = 0; i < max; i++) {
|
||||||
FURI_LOG_D(
|
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);
|
||||||
"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) {
|
if (direction < 0 && menu->current_menu == 0) {
|
||||||
menu->current_menu = menu->menu_count - 1;
|
menu->current_menu = menu->menu_count - 1;
|
||||||
} else {
|
} else {
|
||||||
menu->current_menu = (menu->current_menu + direction) % menu->menu_count;
|
menu->current_menu = (menu->current_menu + direction) % menu->menu_count;
|
||||||
}
|
}
|
||||||
FURI_LOG_D(
|
FURI_LOG_D("MENU", "After process current %i, direction %i, state %i", menu->current_menu,direction,menu->items[menu->current_menu].enabled?1:0);
|
||||||
"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) {
|
if (menu->items[menu->current_menu].enabled) {
|
||||||
FURI_LOG_D("MENU", "Next menu %i", menu->current_menu);
|
FURI_LOG_D("MENU", "Next menu %i", menu->current_menu);
|
||||||
return;
|
return;
|
||||||
@@ -85,12 +75,7 @@ void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y) {
|
|||||||
|
|
||||||
// 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_set_font(canvas, FontSecondary);
|
||||||
canvas_draw_str_aligned(
|
canvas_draw_str_aligned(canvas, pos_x + menu->menu_width / 2, pos_y + 6, AlignCenter, AlignCenter,
|
||||||
canvas,
|
|
||||||
pos_x + menu->menu_width / 2,
|
|
||||||
pos_y + 6,
|
|
||||||
AlignCenter,
|
|
||||||
AlignCenter,
|
|
||||||
menu->items[menu->current_menu].name);
|
menu->items[menu->current_menu].name);
|
||||||
//9*5
|
//9*5
|
||||||
int center = pos_x + menu->menu_width / 2;
|
int center = pos_x + menu->menu_width / 2;
|
||||||
@@ -100,4 +85,5 @@ void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y) {
|
|||||||
canvas_draw_dot(canvas, center+j, pos_y+14-i);
|
canvas_draw_dot(canvas, center+j, pos_y+14-i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,8 +7,7 @@ typedef struct {
|
|||||||
const char *name; //Name of the menu
|
const char *name; //Name of the menu
|
||||||
bool enabled; //Is the menu item enabled (it will not render, you cannot select it)
|
bool enabled; //Is the menu item enabled (it will not render, you cannot select it)
|
||||||
|
|
||||||
void (*callback)(
|
void (*callback)(void *state); //Callback for when the activate_menu is called while this menu is selected
|
||||||
void* state); //Callback for when the activate_menu is called while this menu is selected
|
|
||||||
} MenuItem;
|
} MenuItem;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
|
|
||||||
void render_queue(const QueueState *queue_state, const void *app_state, Canvas *const 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)
|
if (queue_state->current != NULL && queue_state->current->render != NULL)
|
||||||
((QueueItem *) queue_state->current)->render(app_state, canvas);
|
((QueueItem *) queue_state->current)->render(app_state, canvas);
|
||||||
@@ -22,7 +23,8 @@ void dequeue(QueueState* queue_state, void* app_state) {
|
|||||||
queue_state->current = f->next;
|
queue_state->current = f->next;
|
||||||
free(f);
|
free(f);
|
||||||
if (queue_state->current != NULL) {
|
if (queue_state->current != NULL) {
|
||||||
if(queue_state->current->start != NULL) queue_state->current->start(app_state);
|
if (queue_state->current->start != NULL)
|
||||||
|
queue_state->current->start(app_state);
|
||||||
queue_state->start = furi_get_tick();
|
queue_state->start = furi_get_tick();
|
||||||
}else{
|
}else{
|
||||||
queue_state->running = false;
|
queue_state->running = false;
|
||||||
@@ -39,25 +41,20 @@ void queue_clear(QueueState* queue_state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void enqueue(
|
void enqueue(QueueState *queue_state, void *app_state,
|
||||||
QueueState* queue_state,
|
void(*done)(void *state), void(*start)(void *state),
|
||||||
void* app_state,
|
void (*render)(const void *state, Canvas *const canvas), uint32_t duration) {
|
||||||
void (*done)(void* state),
|
|
||||||
void (*start)(void* state),
|
|
||||||
void (*render)(const void* state, Canvas* const canvas),
|
|
||||||
uint32_t duration) {
|
|
||||||
QueueItem *next;
|
QueueItem *next;
|
||||||
if (queue_state->current == NULL) {
|
if (queue_state->current == NULL) {
|
||||||
queue_state->start = furi_get_tick();
|
queue_state->start = furi_get_tick();
|
||||||
queue_state->current = malloc(sizeof(QueueItem));
|
queue_state->current = malloc(sizeof(QueueItem));
|
||||||
next = queue_state->current;
|
next = queue_state->current;
|
||||||
if(next->start != NULL) next->start(app_state);
|
if (next->start != NULL)
|
||||||
|
next->start(app_state);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
next = queue_state->current;
|
next = queue_state->current;
|
||||||
while(next->next != NULL) {
|
while (next->next != NULL) { next = (QueueItem *) (next->next); }
|
||||||
next = (QueueItem*)(next->next);
|
|
||||||
}
|
|
||||||
next->next = malloc(sizeof(QueueItem));
|
next->next = malloc(sizeof(QueueItem));
|
||||||
next = next->next;
|
next = next->next;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,7 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void (*callback)(void *state); //Callback for when the item is dequeued
|
void (*callback)(void *state); //Callback for when the item is dequeued
|
||||||
void (*render)(
|
void (*render)(const void *state, Canvas *const canvas); //Callback for the rendering loop while this item is running
|
||||||
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 (*start)(void *state); //Callback when this item is started running
|
||||||
void *next; //Pointer to the next item
|
void *next; //Pointer to the next item
|
||||||
uint32_t duration; //duration of the item
|
uint32_t duration; //duration of the item
|
||||||
@@ -29,13 +27,9 @@ typedef struct {
|
|||||||
* @param render Callback to render loop if needed
|
* @param render Callback to render loop if needed
|
||||||
* @param duration Length of the item
|
* @param duration Length of the item
|
||||||
*/
|
*/
|
||||||
void enqueue(
|
void enqueue(QueueState *queue_state, void *app_state,
|
||||||
QueueState* queue_state,
|
void(*done)(void *state), void(*start)(void *state),
|
||||||
void* app_state,
|
void (*render)(const void *state, Canvas *const canvas), uint32_t duration);
|
||||||
void (*done)(void* state),
|
|
||||||
void (*start)(void* state),
|
|
||||||
void (*render)(const void* state, Canvas* const canvas),
|
|
||||||
uint32_t duration);
|
|
||||||
/**
|
/**
|
||||||
* Clears all queue items
|
* Clears all queue items
|
||||||
*
|
*
|
||||||
|
|||||||
216
applications/plugins/blackjack/common/ui.c
Normal file
216
applications/plugins/blackjack/common/ui.c
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
#include "ui.h"
|
||||||
|
#include <gui/canvas_i.h>
|
||||||
|
#include <u8g2_glue.h>
|
||||||
|
#include <gui/icon_animation_i.h>
|
||||||
|
#include <gui/icon.h>
|
||||||
|
#include <gui/icon_i.h>
|
||||||
|
#include <furi_hal.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
58
applications/plugins/blackjack/common/ui.h
Normal file
58
applications/plugins/blackjack/common/ui.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <furi.h>
|
||||||
|
#include <gui/canvas.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
@@ -43,7 +43,15 @@ typedef enum {
|
|||||||
GameStateDealer,
|
GameStateDealer,
|
||||||
} PlayState;
|
} PlayState;
|
||||||
|
|
||||||
typedef enum { DirectionUp, DirectionRight, DirectionDown, DirectionLeft, Select, None } Direction;
|
typedef enum {
|
||||||
|
DirectionUp,
|
||||||
|
DirectionDown,
|
||||||
|
DirectionRight,
|
||||||
|
DirectionLeft,
|
||||||
|
Select,
|
||||||
|
Back,
|
||||||
|
None
|
||||||
|
} Direction;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Card player_cards[21];
|
Card player_cards[21];
|
||||||
@@ -66,3 +74,4 @@ typedef struct {
|
|||||||
Menu *menu;
|
Menu *menu;
|
||||||
unsigned int last_tick;
|
unsigned int last_tick;
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|
||||||
|
|||||||
@@ -6,19 +6,23 @@
|
|||||||
#define LINE_HEIGHT 16
|
#define LINE_HEIGHT 16
|
||||||
#define ITEM_PADDING 4
|
#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;
|
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;
|
max_card = game_state->dealer_card_count;
|
||||||
if (max_card > 1) {
|
if (max_card > 1) {
|
||||||
draw_card_at(
|
draw_card_at(2, 2, game_state->dealer_cards[1].pip, game_state->dealer_cards[1].character,
|
||||||
2, 2, game_state->dealer_cards[1].pip, game_state->dealer_cards[1].character, canvas);
|
canvas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,12 +39,11 @@ void popup_frame(Canvas* const canvas) {
|
|||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void draw_play_menu(Canvas *const canvas, const GameState *game_state) {
|
void draw_play_menu(Canvas *const canvas, const GameState *game_state) {
|
||||||
const char *menus[3] = {"Double", "Hit", "Stay"};
|
const char *menus[3] = {"Double", "Hit", "Stay"};
|
||||||
for (uint8_t m = 0; m < 3; m++) {
|
for (uint8_t m = 0; m < 3; m++) {
|
||||||
if(m == 0 &&
|
if (m == 0 && (game_state->doubled || game_state->player_score < game_state->settings.round_price)) continue;
|
||||||
(game_state->doubled || game_state->player_score < game_state->settings.round_price))
|
|
||||||
continue;
|
|
||||||
int y = m * 13 + 25;
|
int y = m * 13 + 25;
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
|
||||||
@@ -65,7 +68,8 @@ void draw_play_menu(Canvas* const canvas, const GameState* game_state) {
|
|||||||
void draw_screen(Canvas *const canvas, const bool *points) {
|
void draw_screen(Canvas *const canvas, const bool *points) {
|
||||||
for (uint8_t x = 0; x < 128; x++) {
|
for (uint8_t x = 0; x < 128; x++) {
|
||||||
for (uint8_t y = 0; y < 64; y++) {
|
for (uint8_t y = 0; y < 64; y++) {
|
||||||
if(points[y * 128 + x]) canvas_draw_dot(canvas, x, y);
|
if (points[y * 128 + x])
|
||||||
|
canvas_draw_dot(canvas, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,13 +104,8 @@ void draw_money(Canvas* const canvas, uint32_t score) {
|
|||||||
canvas_draw_str_aligned(canvas, 126, 2, AlignRight, AlignTop, drawChar);
|
canvas_draw_str_aligned(canvas, 126, 2, AlignRight, AlignTop, drawChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_menu(
|
|
||||||
Canvas* const canvas,
|
void draw_menu(Canvas *const canvas, const char *text, const char *value, int8_t y, bool left_caret, bool right_caret,
|
||||||
const char* text,
|
|
||||||
const char* value,
|
|
||||||
int8_t y,
|
|
||||||
bool left_caret,
|
|
||||||
bool right_caret,
|
|
||||||
bool selected) {
|
bool selected) {
|
||||||
UNUSED(selected);
|
UNUSED(selected);
|
||||||
if (y < 0 || y >= 64) return;
|
if (y < 0 || y >= 64) return;
|
||||||
@@ -118,7 +117,8 @@ void draw_menu(
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvas_draw_str_aligned(canvas, 4, y + ITEM_PADDING, AlignLeft, AlignTop, text);
|
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);
|
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_draw_str_aligned(canvas, 120, y + ITEM_PADDING, AlignRight, AlignTop, ">");
|
||||||
@@ -136,51 +136,45 @@ void settings_page(Canvas* const canvas, const GameState* gameState) {
|
|||||||
int scrollHeight = round(64 / 6.0) + ITEM_PADDING * 2;
|
int scrollHeight = round(64 / 6.0) + ITEM_PADDING * 2;
|
||||||
int scrollPos = 64 / (6.0 / (gameState->selectedMenu + 1)) - ITEM_PADDING * 2;
|
int scrollPos = 64 / (6.0 / (gameState->selectedMenu + 1)) - ITEM_PADDING * 2;
|
||||||
|
|
||||||
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
canvas_draw_box(canvas, 123, scrollPos, 4, scrollHeight);
|
canvas_draw_box(canvas, 123, scrollPos, 4, scrollHeight);
|
||||||
canvas_draw_box(canvas, 125, 0, 1, 64);
|
canvas_draw_box(canvas, 125, 0, 1, 64);
|
||||||
|
|
||||||
snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.starting_money);
|
snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.starting_money);
|
||||||
draw_menu(
|
draw_menu(canvas, "Start money", drawChar,
|
||||||
canvas,
|
|
||||||
"Start money",
|
|
||||||
drawChar,
|
|
||||||
0 * LINE_HEIGHT + startY,
|
0 * LINE_HEIGHT + startY,
|
||||||
gameState->settings.starting_money > gameState->settings.round_price,
|
gameState->settings.starting_money > gameState->settings.round_price,
|
||||||
gameState->settings.starting_money < 400,
|
gameState->settings.starting_money < 400,
|
||||||
gameState->selectedMenu == 0);
|
gameState->selectedMenu == 0
|
||||||
|
);
|
||||||
snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.round_price);
|
snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.round_price);
|
||||||
draw_menu(
|
draw_menu(canvas, "Round price", drawChar,
|
||||||
canvas,
|
|
||||||
"Round price",
|
|
||||||
drawChar,
|
|
||||||
1 * LINE_HEIGHT + startY,
|
1 * LINE_HEIGHT + startY,
|
||||||
gameState->settings.round_price > 10,
|
gameState->settings.round_price > 10,
|
||||||
gameState->settings.round_price < gameState->settings.starting_money,
|
gameState->settings.round_price < gameState->settings.starting_money,
|
||||||
gameState->selectedMenu == 1);
|
gameState->selectedMenu == 1
|
||||||
|
);
|
||||||
|
|
||||||
snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.animation_duration);
|
snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.animation_duration);
|
||||||
draw_menu(
|
draw_menu(canvas, "Anim. length", drawChar,
|
||||||
canvas,
|
|
||||||
"Anim. length",
|
|
||||||
drawChar,
|
|
||||||
2 * LINE_HEIGHT + startY,
|
2 * LINE_HEIGHT + startY,
|
||||||
gameState->settings.animation_duration > 0,
|
gameState->settings.animation_duration > 0,
|
||||||
gameState->settings.animation_duration < 2000,
|
gameState->settings.animation_duration < 2000,
|
||||||
gameState->selectedMenu == 2);
|
gameState->selectedMenu == 2
|
||||||
|
);
|
||||||
snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.message_duration);
|
snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.message_duration);
|
||||||
draw_menu(
|
draw_menu(canvas, "Popup time", drawChar,
|
||||||
canvas,
|
|
||||||
"Popup time",
|
|
||||||
drawChar,
|
|
||||||
3 * LINE_HEIGHT + startY,
|
3 * LINE_HEIGHT + startY,
|
||||||
gameState->settings.message_duration > 0,
|
gameState->settings.message_duration > 0,
|
||||||
gameState->settings.message_duration < 2000,
|
gameState->settings.message_duration < 2000,
|
||||||
gameState->selectedMenu == 3);
|
gameState->selectedMenu == 3
|
||||||
|
);
|
||||||
// draw_menu(canvas, "Sound", gameState->settings.sound_effects ? "Yes" : "No",
|
// draw_menu(canvas, "Sound", gameState->settings.sound_effects ? "Yes" : "No",
|
||||||
// 5 * LINE_HEIGHT + startY,
|
// 5 * LINE_HEIGHT + startY,
|
||||||
// true,
|
// true,
|
||||||
// true,
|
// true,
|
||||||
// gameState->selectedMenu == 5
|
// gameState->selectedMenu == 5
|
||||||
// );
|
// );
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,10 +8,9 @@ void save_settings(Settings settings) {
|
|||||||
FlipperFormat *file = flipper_format_file_alloc(storage);
|
FlipperFormat *file = flipper_format_file_alloc(storage);
|
||||||
FURI_LOG_D(APP_NAME, "Saving config");
|
FURI_LOG_D(APP_NAME, "Saving config");
|
||||||
if (flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) {
|
if (flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) {
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(APP_NAME, "Saving %s: %ld", CONF_ANIMATION_DURATION, settings.animation_duration);
|
||||||
APP_NAME, "Saving %s: %ld", CONF_ANIMATION_DURATION, settings.animation_duration);
|
flipper_format_update_uint32(file, CONF_ANIMATION_DURATION, &(settings.animation_duration), 1);
|
||||||
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);
|
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);
|
flipper_format_update_uint32(file, CONF_MESSAGE_DURATION, &(settings.message_duration), 1);
|
||||||
@@ -78,7 +77,8 @@ Settings load_settings() {
|
|||||||
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);
|
FURI_LOG_E(APP_NAME, "Error opening existing file %s", CONFIG_FILE_PATH);
|
||||||
flipper_format_file_close(file);
|
flipper_format_file_close(file);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
bool valueBool;
|
bool valueBool;
|
||||||
FURI_LOG_D(APP_NAME, "Checking version");
|
FURI_LOG_D(APP_NAME, "Checking version");
|
||||||
|
|||||||
Reference in New Issue
Block a user