MX 2 лет назад
Родитель
Сommit
4c008166a8

+ 1 - 1
non_catalog_apps/hangman_game/README.md

@@ -9,4 +9,4 @@
 ![По-английски](https://github.com/bolknote/Flipper-Zero-Hangman-Game/assets/392509/7c33ba65-9e0f-42a4-92bd-b3801c03aef4)
 
 * Программист: Евгений Степанищев (@bolknote)
-* Иллюстратор: Ева Степанищева
+* Иллюстратор: Ева Степанищева (7 лет)

+ 52 - 45
non_catalog_apps/hangman_game/helpers/hangman.c

@@ -2,17 +2,17 @@
 #include "helpers/hangman_fonts.h"
 
 char* hangman_get_random_word(const char* dict_file) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
+    CONST storage = furi_record_open(RECORD_STORAGE);
 
-    Stream* stream = file_stream_alloc(storage);
-    FuriString* line = furi_string_alloc();
+    CONST stream = file_stream_alloc(storage);
+    CONST line = furi_string_alloc();
 
     if(file_stream_open(stream, dict_file, FSAM_READ, FSOM_OPEN_EXISTING)) {
-        int32_t offset = furi_hal_random_get() % stream_size(stream);
+        CONST offset = furi_hal_random_get() % stream_size(stream);
 
         if(offset > 0) {
-            bool seek_result = stream_seek(stream, offset, StreamOffsetFromStart) &&
-                               stream_read_line(stream, line);
+            CONST seek_result = stream_seek(stream, offset, StreamOffsetFromStart) &&
+                                stream_read_line(stream, line);
 
             if(!seek_result) {
                 stream_rewind(stream);
@@ -25,7 +25,7 @@ char* hangman_get_random_word(const char* dict_file) {
 
     furi_string_trim(line, "\n");
 
-    char* word = strdup(furi_string_get_cstr(line));
+    CONST word = strdup(furi_string_get_cstr(line));
     furi_string_free(line);
     file_stream_close(stream);
     stream_free(stream);
@@ -38,15 +38,17 @@ void hangman_draw_keyboard(Canvas* canvas, HangmanApp* app) {
     canvas_set_color(canvas, ColorBlack);
 
     canvas_set_custom_u8g2_font(canvas, u8g2_font_6x12_t_cyrillic);
-    uint8_t glyph_w = canvas_glyph_width(canvas, ' ');
-    uint8_t glyph_h = canvas_current_font_height(canvas);
+    CONST glyph_w = canvas_glyph_width(canvas, ' ');
+    CONST glyph_h = canvas_current_font_height(canvas);
+
+    CONST gap = ceil((canvas_width(canvas) - 42.) / app->lang->keyboard_cols - glyph_w);
 
     for(uint8_t j = 0; j < app->lang->keyboard_rows; j++) {
-        uint8_t y = 29 + j * glyph_h * .94;
+        CONST y = 29 + j * glyph_h * .94;
 
         for(uint8_t i = 0; i < app->lang->keyboard_cols; i++) {
-            uint8_t x = 42 + i * glyph_w * 1.85;
-            uint8_t n = j * app->lang->keyboard_cols + i;
+            CONST x = 42 + (glyph_w + (int)gap) * i;
+            CONST n = j * app->lang->keyboard_cols + i;
 
             if(n > app->lang->letters_cnt - 1) {
                 break;
@@ -60,12 +62,15 @@ void hangman_draw_keyboard(Canvas* canvas, HangmanApp* app) {
             }
 
             if(n == app->pos) {
-                canvas_draw_glyph(canvas, x - 1, y, ch); // Made bold
+                canvas_draw_box(canvas, x - 1, y - glyph_h + 2, glyph_w + 1, glyph_h);
+                canvas_set_color(canvas, ColorXOR);
+                canvas_draw_glyph(canvas, x, y, ch);
+                canvas_set_color(canvas, ColorBlack);
+            } else {
+                canvas_draw_glyph(canvas, x, y, ch);
             }
 
-            canvas_draw_glyph(canvas, x, y, ch);
-
-            if(app->opened[n]) {
+            if(app->opened[n] != HangmanOpenedInit) {
                 canvas_set_custom_u8g2_font(canvas, u8g2_font_6x12_t_cyrillic);
             }
         }
@@ -75,15 +80,17 @@ void hangman_draw_keyboard(Canvas* canvas, HangmanApp* app) {
 void hangman_draw_word(Canvas* canvas, HangmanApp* app) {
     canvas_set_custom_u8g2_font(canvas, u8g2_font_6x13B_t_cyrillic);
 
-    uint8_t glyph_w = canvas_glyph_width(canvas, ' ');
-    uint8_t gap = app->lang->keyboard_gap;
+    CONST glyph_w = canvas_glyph_width(canvas, ' ');
+    CONST gap = app->lang->word_letters_gap;
 
-    uint8_t center_x = (canvas_width(canvas) - (glyph_w + gap) * strlen(app->word)) / 2;
+    CONST center_x = (canvas_width(canvas) - (glyph_w + gap) * strlen(app->word)) / 2;
 
-    uint8_t h = canvas_current_font_height(canvas);
+    CONST h = canvas_current_font_height(canvas);
     canvas_set_color(canvas, ColorBlack);
 
-    for(uint8_t i = 0, x = center_x; i < strlen(app->word); i++) {
+    CONST word_len = strlen(app->word);
+
+    for(uint8_t i = 0, x = center_x; i < word_len; i++) {
         if(app->opened[app->word[i] - app->lang->first_letter_offset]) {
             canvas_set_color(canvas, ColorBlack);
             canvas_draw_glyph(
@@ -97,7 +104,7 @@ void hangman_draw_word(Canvas* canvas, HangmanApp* app) {
         canvas_set_color(canvas, ColorXOR);
         canvas_draw_glyph(canvas, x, h + 1, '_');
 
-        x += glyph_w + app->lang->keyboard_gap;
+        x += glyph_w + gap;
     }
 }
 
@@ -106,26 +113,26 @@ void hangman_draw_menu(Canvas* canvas, HangmanApp* app) {
 
     uint8_t max_txt_w = 0;
     for(uint8_t i = 0; i < app->menu_cnt; i += 2) {
-        uint8_t txt_w = hangman_string_length(app->menu[i]);
+        CONST txt_w = hangman_string_length(app->menu[i]);
         if(txt_w > max_txt_w) {
             max_txt_w = txt_w;
         }
     }
 
     max_txt_w *= canvas_glyph_width(canvas, ' ');
-    uint8_t txt_h = canvas_current_font_height(canvas);
+    CONST txt_h = canvas_current_font_height(canvas);
 
-    uint8_t w = max_txt_w + 30;
-    uint8_t h = txt_h * app->menu_cnt / 2 + 6;
-    uint8_t x = (canvas_width(canvas) - w) / 2;
-    uint8_t y = (canvas_height(canvas) - h) / 2;
+    CONST w = max_txt_w + 30;
+    CONST h = txt_h * app->menu_cnt / 2 + 6;
+    CONST x = (canvas_width(canvas) - w) / 2;
+    CONST y = (canvas_height(canvas) - h) / 2;
 
     hangman_window(canvas, x, y, w, h);
 
-    uint8_t txt_x = (canvas_width(canvas) - max_txt_w) / 2;
+    CONST txt_x = (canvas_width(canvas) - max_txt_w) / 2;
 
     for(uint8_t i = 0, menu_item = 0; i < app->menu_cnt; i += 2, menu_item++) {
-        uint8_t txt_y = y + (menu_item + 1) * txt_h;
+        CONST txt_y = y + (menu_item + 1) * txt_h;
 
         canvas_set_color(canvas, ColorBlack);
 
@@ -139,7 +146,7 @@ void hangman_draw_menu(Canvas* canvas, HangmanApp* app) {
 }
 
 void hangman_render_callback(Canvas* canvas, void* ctx) {
-    HangmanApp* app = (HangmanApp*)ctx;
+    CONST app = (HangmanApp*)ctx;
 
     canvas_clear(canvas);
 
@@ -164,7 +171,7 @@ void hangman_render_callback(Canvas* canvas, void* ctx) {
 void hangman_input_callback(InputEvent* input_event, void* ctx) {
     furi_assert(ctx);
 
-    FuriMessageQueue* event_queue = ctx;
+    CONST event_queue = ctx;
     furi_message_queue_put(event_queue, input_event, FuriWaitForever);
 }
 
@@ -179,7 +186,7 @@ void hangman_choice_letter(HangmanApp* app) {
 
                 // Open the non-guessed letters
                 for(uint8_t i = 0; i < strlen(app->word); i++) {
-                    int letter = app->word[i] - app->lang->first_letter_offset;
+                    CONST letter = app->word[i] - app->lang->first_letter_offset;
 
                     if(app->opened[letter] != HangmanOpenedFound) {
                         app->opened[letter] = HangmanOpenedNotFound;
@@ -218,44 +225,44 @@ void hangman_clear_state(HangmanApp* app) {
 }
 
 int hangman_read_int(Stream* stream) {
-    FuriString* line = furi_string_alloc();
+    CONST line = furi_string_alloc();
 
     if(!stream_read_line(stream, line)) {
         furi_crash(NULL);
     }
 
-    int result = strtol(furi_string_get_cstr(line), NULL, 10);
+    CONST result = strtol(furi_string_get_cstr(line), NULL, 10);
     furi_string_free(line);
     return result;
 }
 
 char* hangman_read_str(Stream* stream) {
-    FuriString* line = furi_string_alloc();
+    CONST line = furi_string_alloc();
 
     if(!stream_read_line(stream, line)) {
         furi_crash(NULL);
     }
 
     furi_string_trim(line);
-    char* result = strdup(furi_string_get_cstr(line));
+    CONST result = strdup(furi_string_get_cstr(line));
     furi_string_free(line);
     return result;
 }
 
 char* hangman_add_asset_path(const char* filename) {
-    FuriString* full_path = furi_string_alloc_set_str(APP_ASSETS_PATH(""));
+    CONST full_path = furi_string_alloc_set_str(APP_ASSETS_PATH(""));
     furi_string_cat_str(full_path, filename);
 
-    const char* file_full_path = furi_string_get_cstr(full_path);
-    char* result = strdup(file_full_path);
+    CONST file_full_path = furi_string_get_cstr(full_path);
+    CONST result = strdup(file_full_path);
     furi_string_free(full_path);
     return result;
 }
 
 HangmanLangConfig* hangman_load_config(char* meta_file) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    Stream* stream = file_stream_alloc(storage);
-    FuriString* line = furi_string_alloc();
+    CONST storage = furi_record_open(RECORD_STORAGE);
+    CONST stream = file_stream_alloc(storage);
+    CONST line = furi_string_alloc();
     HangmanLangConfig* config = malloc(sizeof(HangmanLangConfig));
 
     if(!file_stream_open(stream, meta_file, FSAM_READ, FSOM_OPEN_EXISTING)) {
@@ -267,7 +274,7 @@ HangmanLangConfig* hangman_load_config(char* meta_file) {
     }
     config->dict_file = hangman_add_asset_path(furi_string_get_cstr(line));
     config->keyboard_cols = hangman_read_int(stream);
-    config->keyboard_gap = hangman_read_int(stream);
+    config->word_letters_gap = hangman_read_int(stream);
     config->first_letter_offset = hangman_read_int(stream);
 
     // letters
@@ -307,7 +314,7 @@ HangmanLangConfig* hangman_load_config(char* meta_file) {
 }
 
 void hangman_load_lang(HangmanApp* app) {
-    char* meta_file = hangman_add_asset_path(app->menu[app->menu_item * 2 + 1]);
+    CONST meta_file = hangman_add_asset_path(app->menu[app->menu_item * 2 + 1]);
     app->lang = hangman_load_config(meta_file);
     free(meta_file);
 }

+ 3 - 1
non_catalog_apps/hangman_game/helpers/hangman.h

@@ -7,6 +7,8 @@
 
 #define HANGMAN_MENU_FILE APP_ASSETS_PATH("menu.txt")
 
+#define CONST const __auto_type
+
 #include "hangman_icons.h"
 
 #include <math.h>
@@ -37,7 +39,7 @@ typedef struct {
     uint8_t letters_cnt;
     uint8_t keyboard_cols;
     uint8_t keyboard_rows;
-    uint8_t keyboard_gap;
+    uint8_t word_letters_gap;
     uint16_t letters[HANGMAN_MAX_ALP_SIZE];
     char *message_ok, *message_won, *message_loose;
 } HangmanLangConfig;

+ 19 - 17
non_catalog_apps/hangman_game/helpers/hangman_gui.c

@@ -1,8 +1,8 @@
 #include "hangman.h"
 
 size_t hangman_string_length(const char* str) {
-    FuriString* furi_str = furi_string_alloc_set_str(str);
-    size_t len = furi_string_utf8_length(furi_str);
+    CONST furi_str = furi_string_alloc_set_str(str);
+    CONST len = furi_string_utf8_length(furi_str);
     furi_string_free(furi_str);
 
     return len;
@@ -35,17 +35,17 @@ void hangman_draw_gallows(Canvas* canvas, HangmanApp* app) {
 
 // This function was copied from Flipper Zero firmware
 void hangman_ok_button(Canvas* canvas, uint8_t y, const char* str) {
-    const uint8_t button_height = 12;
-    const uint8_t vertical_offset = 3;
-    const uint8_t horizontal_offset = 1;
-    const uint8_t string_width = canvas_glyph_width(canvas, ' ') * hangman_string_length(str);
-    const Icon* icon = &I_button_ok_7x7;
-    const uint8_t icon_h_offset = 3;
-    const uint8_t icon_width_with_offset = 7 + icon_h_offset;
-    const uint8_t icon_v_offset = 7 + vertical_offset;
-    const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
-
-    const uint8_t x = (canvas_width(canvas) - button_width) / 2;
+    CONST button_height = 12;
+    CONST vertical_offset = 3;
+    CONST horizontal_offset = 1;
+    CONST string_width = canvas_glyph_width(canvas, ' ') * hangman_string_length(str);
+    CONST icon = &I_button_ok_7x7;
+    CONST icon_h_offset = 3;
+    CONST icon_width_with_offset = 7 + icon_h_offset;
+    CONST icon_v_offset = 7 + vertical_offset;
+    CONST button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
+
+    CONST x = (canvas_width(canvas) - button_width) / 2;
 
     canvas_draw_box(canvas, x, y - button_height, button_width, button_height);
 
@@ -73,11 +73,13 @@ void hangman_window(Canvas* canvas, uint8_t x, uint8_t y, uint8_t w, uint8_t h)
 }
 
 void hangman_text_window(Canvas* canvas, char* ok, char* txt) {
-    uint8_t txt_w = canvas_glyph_width(canvas, ' ') * hangman_string_length(txt);
+    CONST txt_w = canvas_glyph_width(canvas, ' ') * hangman_string_length(txt);
 
-    uint8_t cw = canvas_width(canvas);
-    uint8_t w = txt_w + 10, h = 34, y = 18;
-    uint8_t x = (cw - w) / 2;
+    CONST cw = canvas_width(canvas);
+    CONST w = txt_w + 10;
+    CONST h = 34;
+    CONST y = 18;
+    CONST x = (cw - w) / 2;
 
     hangman_window(canvas, x, y, w, h);
     hangman_ok_button(canvas, y + h, ok);

+ 1 - 1
non_catalog_apps/hangman_game/helpers/hangman_input.c

@@ -24,7 +24,7 @@ bool hangman_wait_close_window(HangmanApp* app) {
 
 bool hangman_menu_selection(HangmanApp* app) {
     InputEvent event;
-    int8_t menu_cnt = app->menu_cnt / 2;
+    const int8_t menu_cnt = app->menu_cnt / 2;
 
     for(;;) {
         if(furi_message_queue_get(app->event_queue, &event, 100) == FuriStatusOk) {

+ 3 - 3
non_catalog_apps/hangman_game/helpers/hangman_menu.c

@@ -1,10 +1,10 @@
 #include "hangman.h"
 
 char** hangman_menu_read(size_t* menu_size) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
+    CONST storage = furi_record_open(RECORD_STORAGE);
 
-    Stream* stream = file_stream_alloc(storage);
-    FuriString* line = furi_string_alloc();
+    CONST stream = file_stream_alloc(storage);
+    CONST line = furi_string_alloc();
 
     char** lines = NULL;
     size_t capacity = 0;