mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-24 01:28:11 -07:00
fmt
This commit is contained in:
@@ -9,76 +9,48 @@
|
||||
#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
|
||||
}
|
||||
};
|
||||
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}};
|
||||
|
||||
//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
|
||||
|
||||
@@ -86,7 +58,7 @@ bool get_pip_pixel(uint8_t pip, uint8_t x, uint8_t y) {
|
||||
return pips[pip][x + y * 7];
|
||||
}
|
||||
|
||||
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);
|
||||
canvas_draw_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT);
|
||||
|
||||
@@ -98,9 +70,9 @@ void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Ca
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
@@ -109,16 +81,16 @@ void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Ca
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
char drawChar[3];
|
||||
if (character < 9)
|
||||
if(character < 9)
|
||||
snprintf(drawChar, sizeof(drawChar), "%i", character + 2);
|
||||
else {
|
||||
if (character == 9)
|
||||
if(character == 9)
|
||||
snprintf(drawChar, sizeof(drawChar), "J");
|
||||
else if (character == 10)
|
||||
else if(character == 10)
|
||||
snprintf(drawChar, sizeof(drawChar), "Q");
|
||||
else if (character == 11)
|
||||
else if(character == 11)
|
||||
snprintf(drawChar, sizeof(drawChar), "K");
|
||||
else if (character == 12)
|
||||
else if(character == 12)
|
||||
snprintf(drawChar, sizeof(drawChar), "A");
|
||||
}
|
||||
|
||||
@@ -128,63 +100,63 @@ void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Ca
|
||||
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
|
||||
if(character == 8) //10 needs bigger margin
|
||||
margin = 12;
|
||||
canvas_draw_str_aligned(canvas, right + margin, bottom - 3, AlignCenter, AlignCenter, drawChar);
|
||||
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) {
|
||||
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_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) {
|
||||
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);
|
||||
|
||||
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) {
|
||||
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
|
||||
};
|
||||
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};
|
||||
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];
|
||||
@@ -192,45 +164,53 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,24 +6,23 @@
|
||||
#include "dml.h"
|
||||
|
||||
#define CARD_HEIGHT 24
|
||||
#define CARD_HALF_HEIGHT CARD_HEIGHT/2
|
||||
#define CARD_HALF_HEIGHT CARD_HEIGHT / 2
|
||||
#define CARD_WIDTH 18
|
||||
#define CARD_HALF_WIDTH CARD_WIDTH/2
|
||||
#define CARD_HALF_WIDTH CARD_WIDTH / 2
|
||||
|
||||
//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
|
||||
} 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 index; //Card index (to know where we at in the deck)
|
||||
} Deck;
|
||||
//endregion
|
||||
|
||||
|
||||
/**
|
||||
* Gets card coordinates at the index (range: 0-20).
|
||||
*
|
||||
@@ -41,7 +40,7 @@ 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 'count' cards at the bottom right corner
|
||||
@@ -50,7 +49,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)
|
||||
@@ -59,7 +58,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
|
||||
@@ -67,14 +66,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
|
||||
@@ -83,7 +82,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
|
||||
@@ -96,5 +95,11 @@ 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);
|
||||
void draw_card_animation(
|
||||
Card animatingCard,
|
||||
Vector from,
|
||||
Vector control,
|
||||
Vector to,
|
||||
float t,
|
||||
bool extra_margin,
|
||||
Canvas* const canvas);
|
||||
@@ -2,47 +2,40 @@
|
||||
#include <math.h>
|
||||
|
||||
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) {
|
||||
|
||||
@@ -1,43 +1,53 @@
|
||||
#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;
|
||||
}
|
||||
@@ -46,44 +56,48 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,18 +4,19 @@
|
||||
#include <gui/gui.h>
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -23,7 +24,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
|
||||
@@ -32,7 +33,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
|
||||
@@ -41,7 +42,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
|
||||
@@ -49,7 +50,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
|
||||
@@ -57,7 +58,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).
|
||||
@@ -73,4 +74,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);
|
||||
void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y);
|
||||
@@ -1,15 +1,14 @@
|
||||
#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;
|
||||
@@ -17,44 +16,48 @@ 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;
|
||||
}
|
||||
|
||||
@@ -4,17 +4,19 @@
|
||||
#include <furi.h>
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -27,15 +29,19 @@ 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.
|
||||
@@ -43,7 +49,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)
|
||||
@@ -52,7 +58,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)
|
||||
@@ -61,4 +67,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);
|
||||
void render_queue(const QueueState* queue_state, const void* app_state, Canvas* const canvas);
|
||||
Reference in New Issue
Block a user