Преглед изворни кода

add sound/led notifications and settings

jblanked пре 1 година
родитељ
комит
97fe127402
6 измењених фајлова са 138 додато и 13 уклоњено
  1. 65 5
      callback/callback.c
  2. 3 2
      flip_world.c
  3. 5 4
      flip_world.h
  4. 58 2
      game/enemy.c
  5. 5 0
      game/game.c
  6. 2 0
      game/player.h

+ 65 - 5
callback/callback.c

@@ -39,7 +39,7 @@ static int32_t game_app(void *p)
     GameEngineSettings settings = game_engine_settings_init();
     settings.target_fps = game_fps_choices_2[game_fps_index];
     settings.show_fps = game.show_fps;
-    settings.always_backlight = strstr(game_screen_always_on_choices[game_screen_always_on_index], "Yes") != NULL;
+    settings.always_backlight = strstr(yes_or_no_choices[game_screen_always_on_index], "Yes") != NULL;
     settings.frame_callback = frame_cb;
     settings.context = game_manager;
     GameEngine *engine = game_engine_alloc(settings);
@@ -158,6 +158,8 @@ static void flip_world_game_fps_change(VariableItem *item);
 static void game_settings_item_selected(void *context, uint32_t index);
 static void user_settings_item_selected(void *context, uint32_t index);
 static void flip_world_game_screen_always_on_change(VariableItem *item);
+static void flip_world_game_sound_on_change(VariableItem *item);
+static void flip_world_game_vibration_on_change(VariableItem *item);
 
 uint32_t callback_to_submenu(void *context)
 {
@@ -364,7 +366,19 @@ static bool alloc_variable_item_list(void *context, uint32_t view_id)
             {
                 app->variable_item_game_screen_always_on = variable_item_list_add(app->variable_item_list, "Keep Screen On?", 2, flip_world_game_screen_always_on_change, NULL);
                 variable_item_set_current_value_index(app->variable_item_game_screen_always_on, 1);
-                variable_item_set_current_value_text(app->variable_item_game_screen_always_on, game_screen_always_on_choices[1]);
+                variable_item_set_current_value_text(app->variable_item_game_screen_always_on, yes_or_no_choices[1]);
+            }
+            if (!app->variable_item_game_sound_on)
+            {
+                app->variable_item_game_sound_on = variable_item_list_add(app->variable_item_list, "Sound On?", 2, flip_world_game_sound_on_change, NULL);
+                variable_item_set_current_value_index(app->variable_item_game_sound_on, 0);
+                variable_item_set_current_value_text(app->variable_item_game_sound_on, yes_or_no_choices[0]);
+            }
+            if (!app->variable_item_game_vibration_on)
+            {
+                app->variable_item_game_vibration_on = variable_item_list_add(app->variable_item_list, "Vibration On?", 2, flip_world_game_vibration_on_change, NULL);
+                variable_item_set_current_value_index(app->variable_item_game_vibration_on, 0);
+                variable_item_set_current_value_text(app->variable_item_game_vibration_on, yes_or_no_choices[0]);
             }
             char _game_fps[8];
             if (load_char("Game-FPS", _game_fps, sizeof(_game_fps)))
@@ -381,9 +395,25 @@ static bool alloc_variable_item_list(void *context, uint32_t view_id)
             {
                 int index = strcmp(_game_screen_always_on, "No") == 0 ? 0 : strcmp(_game_screen_always_on, "Yes") == 0 ? 1
                                                                                                                        : 0;
-                variable_item_set_current_value_text(app->variable_item_game_screen_always_on, game_screen_always_on_choices[index]);
+                variable_item_set_current_value_text(app->variable_item_game_screen_always_on, yes_or_no_choices[index]);
                 variable_item_set_current_value_index(app->variable_item_game_screen_always_on, index);
             }
+            char _game_sound_on[8];
+            if (load_char("Game-Sound-On", _game_sound_on, sizeof(_game_sound_on)))
+            {
+                int index = strcmp(_game_sound_on, "No") == 0 ? 0 : strcmp(_game_sound_on, "Yes") == 0 ? 1
+                                                                                                       : 0;
+                variable_item_set_current_value_text(app->variable_item_game_sound_on, yes_or_no_choices[index]);
+                variable_item_set_current_value_index(app->variable_item_game_sound_on, index);
+            }
+            char _game_vibration_on[8];
+            if (load_char("Game-Vibration-On", _game_vibration_on, sizeof(_game_vibration_on)))
+            {
+                int index = strcmp(_game_vibration_on, "No") == 0 ? 0 : strcmp(_game_vibration_on, "Yes") == 0 ? 1
+                                                                                                               : 0;
+                variable_item_set_current_value_text(app->variable_item_game_vibration_on, yes_or_no_choices[index]);
+                variable_item_set_current_value_index(app->variable_item_game_vibration_on, index);
+            }
             break;
         case FlipWorldSubmenuIndexUserSettings:
             if (!easy_flipper_set_variable_item_list(&app->variable_item_list, FlipWorldViewVariableItemList, user_settings_item_selected, callback_to_settings, &app->view_dispatcher, app))
@@ -540,6 +570,16 @@ static void free_variable_item_list(void *context)
         free(app->variable_item_game_download_world);
         app->variable_item_game_download_world = NULL;
     }
+    if (app->variable_item_game_sound_on)
+    {
+        free(app->variable_item_game_sound_on);
+        app->variable_item_game_sound_on = NULL;
+    }
+    if (app->variable_item_game_vibration_on)
+    {
+        free(app->variable_item_game_vibration_on);
+        app->variable_item_game_vibration_on = NULL;
+    }
     if (app->variable_item_user_username)
     {
         free(app->variable_item_user_username);
@@ -1372,11 +1412,31 @@ static void flip_world_game_screen_always_on_change(VariableItem *item)
 {
     uint8_t index = variable_item_get_current_value_index(item);
     game_screen_always_on_index = index;
-    variable_item_set_current_value_text(item, game_screen_always_on_choices[index]);
+    variable_item_set_current_value_text(item, yes_or_no_choices[index]);
+    variable_item_set_current_value_index(item, index);
+
+    // save the screen always on
+    save_char("Game-Screen-Always-On", yes_or_no_choices[index]);
+}
+static void flip_world_game_sound_on_change(VariableItem *item)
+{
+    uint8_t index = variable_item_get_current_value_index(item);
+    game_sound_on_index = index;
+    variable_item_set_current_value_text(item, yes_or_no_choices[index]);
+    variable_item_set_current_value_index(item, index);
+
+    // save the screen always on
+    save_char("Game-Sound-On", yes_or_no_choices[index]);
+}
+static void flip_world_game_vibration_on_change(VariableItem *item)
+{
+    uint8_t index = variable_item_get_current_value_index(item);
+    game_vibration_on_index = index;
+    variable_item_set_current_value_text(item, yes_or_no_choices[index]);
     variable_item_set_current_value_index(item, index);
 
     // save the screen always on
-    save_char("Game-Screen-Always-On", game_screen_always_on_choices[index]);
+    save_char("Game-Vibration-On", yes_or_no_choices[index]);
 }
 
 static bool flip_world_fetch_worlds(DataLoaderModel *model)

+ 3 - 2
flip_world.c

@@ -2,10 +2,11 @@
 char *game_fps_choices[] = {"30", "60", "120", "240"};
 const float game_fps_choices_2[] = {30.0, 60.0, 120.0, 240.0};
 int game_fps_index = 0;
-char *game_screen_always_on_choices[] = {"No", "Yes"};
+char *yes_or_no_choices[] = {"No", "Yes"};
 int game_screen_always_on_index = 1;
+int game_sound_on_index = 0;
+int game_vibration_on_index = 0;
 FlipWorldApp *app_instance = NULL;
-
 bool is_enough_heap(size_t heap_size)
 {
     size_t free_heap = memmgr_get_free_heap();

+ 5 - 4
flip_world.h

@@ -8,7 +8,6 @@
 #include <gui/view.h>
 #include <gui/modules/submenu.h>
 #include <gui/view_dispatcher.h>
-#include <notification/notification.h>
 #include <dialogs/dialogs.h>
 
 #define TAG "FlipWorld"
@@ -63,6 +62,8 @@ typedef struct
     VariableItem *variable_item_game_fps;              // The variable item for Game FPS
     VariableItem *variable_item_game_screen_always_on; // The variable item for Screen always on
     VariableItem *variable_item_game_download_world;   // The variable item for Download world
+    VariableItem *variable_item_game_sound_on;         // The variable item for Sound on
+    VariableItem *variable_item_game_vibration_on;     // The variable item for Vibration on
     //
     VariableItem *variable_item_user_username; // The variable item for the User username
     VariableItem *variable_item_user_password; // The variable item for the User password
@@ -71,14 +72,14 @@ typedef struct
     char *text_input_buffer;         // Buffer for the text input
     char *text_input_temp_buffer;    // Temporary buffer for the text input
     uint32_t text_input_buffer_size; // Size of the text input buffer
-
 } FlipWorldApp;
 
 extern char *game_fps_choices[];
 extern const float game_fps_choices_2[];
 extern int game_fps_index;
-extern char *game_screen_always_on_choices[];
+extern char *yes_or_no_choices[];
 extern int game_screen_always_on_index;
 extern FlipWorldApp *app_instance;
-
+extern int game_sound_on_index;
+extern int game_vibration_on_index;
 bool is_enough_heap(size_t heap_size);

+ 58 - 2
game/enemy.c

@@ -153,6 +153,62 @@ static void enemy_render(Entity *self, GameManager *manager, Canvas *canvas, voi
     draw_username(canvas, posi, game_context->player_context->username);
 }
 
+static void send_attack_notification(GameContext *game_context, EnemyContext *enemy_context, bool player_attacked)
+{
+    if (!game_context || !enemy_context)
+    {
+        FURI_LOG_E("Game", "Send attack notification: Invalid parameters");
+        return;
+    }
+
+    bool vibration_allowed = strstr(yes_or_no_choices[game_vibration_on_index], "Yes") != NULL;
+    bool sound_allowed = strstr(yes_or_no_choices[game_sound_on_index], "Yes") != NULL;
+
+    if (player_attacked)
+    {
+        if (vibration_allowed && sound_allowed)
+        {
+            notification_message(game_context->notifications, &sequence_success);
+        }
+        else if (vibration_allowed && !sound_allowed)
+        {
+            notification_message(game_context->notifications, &sequence_single_vibro);
+        }
+        else if (!vibration_allowed && sound_allowed)
+        {
+            // change this to sound later
+            notification_message(game_context->notifications, &sequence_blink_blue_100);
+        }
+        else
+        {
+            notification_message(game_context->notifications, &sequence_blink_blue_100);
+        }
+        FURI_LOG_I("Game", "Player attacked enemy '%s'!", enemy_context->id);
+    }
+    else
+    {
+        if (vibration_allowed && sound_allowed)
+        {
+            notification_message(game_context->notifications, &sequence_error);
+        }
+        else if (vibration_allowed && !sound_allowed)
+        {
+            notification_message(game_context->notifications, &sequence_single_vibro);
+        }
+        else if (!vibration_allowed && sound_allowed)
+        {
+            // change this to sound later
+            notification_message(game_context->notifications, &sequence_blink_red_100);
+        }
+        else
+        {
+            notification_message(game_context->notifications, &sequence_blink_red_100);
+        }
+
+        FURI_LOG_I("Game", "Enemy '%s' attacked the player!", enemy_context->id);
+    }
+}
+
 // Enemy collision function
 static void enemy_collision(Entity *self, Entity *other, GameManager *manager, void *context)
 {
@@ -210,7 +266,7 @@ static void enemy_collision(Entity *self, Entity *other, GameManager *manager, v
         {
             if (game_context->player_context->elapsed_attack_timer >= game_context->player_context->attack_timer)
             {
-                FURI_LOG_I("Game", "Player attacked enemy '%s'!", enemy_context->id);
+                send_attack_notification(game_context, enemy_context, true);
 
                 // Reset player's elapsed attack timer
                 game_context->player_context->elapsed_attack_timer = 0.0f;
@@ -269,7 +325,7 @@ static void enemy_collision(Entity *self, Entity *other, GameManager *manager, v
         {
             if (enemy_context->elapsed_attack_timer >= enemy_context->attack_timer)
             {
-                FURI_LOG_I("Game", "Enemy '%s' attacked the player!", enemy_context->id);
+                send_attack_notification(game_context, enemy_context, false);
 
                 // Reset enemy's elapsed attack timer
                 enemy_context->elapsed_attack_timer = 0.0f;

+ 5 - 0
game/game.c

@@ -40,6 +40,9 @@ static void game_start(GameManager *game_manager, void *ctx)
 
     game_context->current_level = 0;
     FURI_LOG_I("Game", "Level count: %d", game_context->level_count);
+
+    // Notifications - for LED light access
+    game_context->notifications = furi_record_open(RECORD_NOTIFICATION);
 }
 
 /*
@@ -61,6 +64,8 @@ static void game_stop(void *ctx)
         FURI_LOG_E("Game", "Game context is NULL");
         return;
     }
+    // close the notifications
+    furi_record_close(RECORD_NOTIFICATION);
     if (game_context->player_context)
     {
         FURI_LOG_I("Game", "Game ending");

+ 2 - 0
game/player.h

@@ -2,6 +2,7 @@
 #include "engine/engine.h"
 #include <flip_world.h>
 #include <game/game.h>
+#include <notification/notification_messages.h>
 
 // Maximum enemies
 #define MAX_ENEMIES 2
@@ -57,6 +58,7 @@ typedef struct
     int enemy_count;
     int current_level;
     bool ended_early;
+    NotificationApp *notifications;
 } GameContext;
 
 typedef struct