Przeglądaj źródła

add VGM settings + name cleanup

jblanked 1 rok temu
rodzic
commit
93aa5a839b
10 zmienionych plików z 245 dodań i 179 usunięć
  1. 131 47
      callback/callback.c
  2. 7 2
      flip_world.c
  3. 10 3
      flip_world.h
  4. 2 2
      game/draw.c
  5. 1 2
      game/draw.h
  6. 7 7
      game/enemy.c
  7. 1 1
      game/game.c
  8. 53 53
      game/icon.c
  9. 32 61
      game/player.c
  10. 1 1
      game/player.h

+ 131 - 47
callback/callback.c

@@ -37,7 +37,7 @@ static int32_t game_app(void *p)
 
     // Setup game engine settings...
     GameEngineSettings settings = game_engine_settings_init();
-    settings.target_fps = fps_choices_2[fps_index];
+    settings.target_fps = atof_(fps_choices_str[fps_index]);
     settings.show_fps = game.show_fps;
     settings.always_backlight = strstr(yes_or_no_choices[screen_always_on_index], "Yes") != NULL;
     settings.frame_callback = frame_cb;
@@ -148,19 +148,21 @@ static bool alloc_about_view(void *context);
 static bool alloc_text_input_view(void *context, char *title);
 static bool alloc_variable_item_list(void *context, uint32_t view_id);
 //
-static void wifi_settings_item_selected(void *context, uint32_t index);
+static void wifi_settings_select(void *context, uint32_t index);
 static void updated_wifi_ssid(void *context);
 static void updated_wifi_pass(void *context);
 static void updated_username(void *context);
 static void updated_password(void *context);
 //
 static void 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 game_settings_select(void *context, uint32_t index);
+static void user_settings_select(void *context, uint32_t index);
 static void screen_on_change(VariableItem *item);
 static void sound_on_change(VariableItem *item);
 static void vibration_on_change(VariableItem *item);
 static void player_on_change(VariableItem *item);
+static void vgm_x_change(VariableItem *item);
+static void vgm_y_change(VariableItem *item);
 
 uint32_t callback_to_submenu(void *context)
 {
@@ -252,9 +254,9 @@ static bool alloc_text_input_view(void *context, char *title)
                 title,
                 app->text_input_temp_buffer,
                 app->text_input_buffer_size,
-                strcmp(title, "SSID") == 0 ? updated_wifi_ssid : strcmp(title, "Password") == 0     ? updated_wifi_pass
-                                                             : strcmp(title, "Username-Login") == 0 ? updated_username
-                                                                                                    : updated_password,
+                is_str(title, "SSID") ? updated_wifi_ssid : is_str(title, "Password")     ? updated_wifi_pass
+                                                        : is_str(title, "Username-Login") ? updated_username
+                                                                                          : updated_password,
                 callback_to_wifi_settings,
                 &app->view_dispatcher,
                 app))
@@ -271,19 +273,19 @@ static bool alloc_text_input_view(void *context, char *title)
         char password[64];
         if (load_settings(ssid, sizeof(ssid), pass, sizeof(pass), username, sizeof(username), password, sizeof(password)))
         {
-            if (strcmp(title, "SSID") == 0)
+            if (is_str(title, "SSID"))
             {
                 strncpy(app->text_input_temp_buffer, ssid, app->text_input_buffer_size);
             }
-            else if (strcmp(title, "Password") == 0)
+            else if (is_str(title, "Password"))
             {
                 strncpy(app->text_input_temp_buffer, pass, app->text_input_buffer_size);
             }
-            else if (strcmp(title, "Username-Login") == 0)
+            else if (is_str(title, "Username-Login"))
             {
                 strncpy(app->text_input_temp_buffer, username, app->text_input_buffer_size);
             }
-            else if (strcmp(title, "Password-Login") == 0)
+            else if (is_str(title, "Password-Login"))
             {
                 strncpy(app->text_input_temp_buffer, password, app->text_input_buffer_size);
             }
@@ -308,7 +310,7 @@ static bool alloc_variable_item_list(void *context, uint32_t view_id)
         switch (view_id)
         {
         case FlipWorldSubmenuIndexWiFiSettings:
-            if (!easy_flipper_set_variable_item_list(&app->variable_item_list, FlipWorldViewVariableItemList, wifi_settings_item_selected, callback_to_settings, &app->view_dispatcher, app))
+            if (!easy_flipper_set_variable_item_list(&app->variable_item_list, FlipWorldViewVariableItemList, wifi_settings_select, callback_to_settings, &app->view_dispatcher, app))
             {
                 FURI_LOG_E(TAG, "Failed to allocate variable item list");
                 return false;
@@ -341,7 +343,7 @@ static bool alloc_variable_item_list(void *context, uint32_t view_id)
             }
             break;
         case FlipWorldSubmenuIndexGameSettings:
-            if (!easy_flipper_set_variable_item_list(&app->variable_item_list, FlipWorldViewVariableItemList, game_settings_item_selected, callback_to_settings, &app->view_dispatcher, app))
+            if (!easy_flipper_set_variable_item_list(&app->variable_item_list, FlipWorldViewVariableItemList, game_settings_select, callback_to_settings, &app->view_dispatcher, app))
             {
                 FURI_LOG_E(TAG, "Failed to allocate variable item list");
                 return false;
@@ -368,7 +370,19 @@ static bool alloc_variable_item_list(void *context, uint32_t view_id)
             {
                 app->variable_item_game_fps = variable_item_list_add(app->variable_item_list, "FPS", 4, fps_change, NULL);
                 variable_item_set_current_value_index(app->variable_item_game_fps, 0);
-                variable_item_set_current_value_text(app->variable_item_game_fps, fps_choices[0]);
+                variable_item_set_current_value_text(app->variable_item_game_fps, fps_choices_str[0]);
+            }
+            if (!app->variable_item_game_vgm_x)
+            {
+                app->variable_item_game_vgm_x = variable_item_list_add(app->variable_item_list, "VGM Horizontal", 12, vgm_x_change, NULL);
+                variable_item_set_current_value_index(app->variable_item_game_vgm_x, 2);
+                variable_item_set_current_value_text(app->variable_item_game_vgm_x, vgm_levels[2]);
+            }
+            if (!app->variable_item_game_vgm_y)
+            {
+                app->variable_item_game_vgm_y = variable_item_list_add(app->variable_item_list, "VGM Vertical", 12, vgm_y_change, NULL);
+                variable_item_set_current_value_index(app->variable_item_game_vgm_y, 2);
+                variable_item_set_current_value_text(app->variable_item_game_vgm_y, vgm_levels[2]);
             }
             if (!app->variable_item_game_screen_always_on)
             {
@@ -391,52 +405,92 @@ static bool alloc_variable_item_list(void *context, uint32_t view_id)
             char _game_player_sprite[8];
             if (load_char("Game-Player-Sprite", _game_player_sprite, sizeof(_game_player_sprite)))
             {
-                int index = strcmp(_game_player_sprite, "naked") == 0 ? 0 : strcmp(_game_player_sprite, "sword") == 0 ? 1
-                                                                        : strcmp(_game_player_sprite, "axe") == 0     ? 2
-                                                                        : strcmp(_game_player_sprite, "bow") == 0     ? 3
-                                                                                                                      : 0;
+                int index = is_str(_game_player_sprite, "naked") ? 0 : is_str(_game_player_sprite, "sword") ? 1
+                                                                   : is_str(_game_player_sprite, "axe")     ? 2
+                                                                   : is_str(_game_player_sprite, "bow")     ? 3
+                                                                                                            : 0;
                 variable_item_set_current_value_index(app->variable_item_game_player_sprite, index);
                 variable_item_set_current_value_text(
                     app->variable_item_game_player_sprite,
-                    strcmp(player_sprite_choices[index], "naked") == 0 ? "None" : player_sprite_choices[index]);
+                    is_str(player_sprite_choices[index], "naked") ? "None" : player_sprite_choices[index]);
             }
             char _game_fps[8];
             if (load_char("Game-FPS", _game_fps, sizeof(_game_fps)))
             {
-                int index = strcmp(_game_fps, "30") == 0 ? 0 : strcmp(_game_fps, "60") == 0 ? 1
-                                                           : strcmp(_game_fps, "120") == 0  ? 2
-                                                           : strcmp(_game_fps, "240") == 0  ? 3
-                                                                                            : 0;
-                variable_item_set_current_value_text(app->variable_item_game_fps, fps_choices[index]);
+                int index = is_str(_game_fps, "30") ? 0 : is_str(_game_fps, "60") ? 1
+                                                      : is_str(_game_fps, "120")  ? 2
+                                                      : is_str(_game_fps, "240")  ? 3
+                                                                                  : 0;
+                variable_item_set_current_value_text(app->variable_item_game_fps, fps_choices_str[index]);
                 variable_item_set_current_value_index(app->variable_item_game_fps, index);
             }
+            char _game_vgm_x[8];
+            if (load_char("Game-VGM-X", _game_vgm_x, sizeof(_game_vgm_x)))
+            {
+                int vgm_x = atoi(_game_vgm_x);
+                int index = vgm_x == -2 ? 0 : vgm_x == -1 ? 1
+                                          : vgm_x == 0    ? 2
+                                          : vgm_x == 1    ? 3
+                                          : vgm_x == 2    ? 4
+                                          : vgm_x == 3    ? 5
+                                          : vgm_x == 4    ? 6
+                                          : vgm_x == 5    ? 7
+                                          : vgm_x == 6    ? 8
+                                          : vgm_x == 7    ? 9
+                                          : vgm_x == 8    ? 10
+                                          : vgm_x == 9    ? 11
+                                          : vgm_x == 10   ? 12
+                                                          : 2;
+                variable_item_set_current_value_index(app->variable_item_game_vgm_x, index);
+                variable_item_set_current_value_text(app->variable_item_game_vgm_x, vgm_levels[index]);
+            }
+            char _game_vgm_y[8];
+            if (load_char("Game-VGM-Y", _game_vgm_y, sizeof(_game_vgm_y)))
+            {
+                int vgm_y = atoi(_game_vgm_y);
+                int index = vgm_y == -2 ? 0 : vgm_y == -1 ? 1
+                                          : vgm_y == 0    ? 2
+                                          : vgm_y == 1    ? 3
+                                          : vgm_y == 2    ? 4
+                                          : vgm_y == 3    ? 5
+                                          : vgm_y == 4    ? 6
+                                          : vgm_y == 5    ? 7
+                                          : vgm_y == 6    ? 8
+                                          : vgm_y == 7    ? 9
+                                          : vgm_y == 8    ? 10
+                                          : vgm_y == 9    ? 11
+                                          : vgm_y == 10   ? 12
+                                                          : 2;
+                variable_item_set_current_value_index(app->variable_item_game_vgm_y, index);
+                variable_item_set_current_value_text(app->variable_item_game_vgm_y, vgm_levels[index]);
+            }
             char _game_screen_always_on[8];
             if (load_char("Game-Screen-Always-On", _game_screen_always_on, sizeof(_game_screen_always_on)))
             {
-                int index = strcmp(_game_screen_always_on, "No") == 0 ? 0 : strcmp(_game_screen_always_on, "Yes") == 0 ? 1
-                                                                                                                       : 0;
+                int index = is_str(_game_screen_always_on, "No") ? 0 : is_str(_game_screen_always_on, "Yes") ? 1
+                                                                                                             : 0;
                 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;
+                int index = is_str(_game_sound_on, "No") ? 0 : is_str(_game_sound_on, "Yes") ? 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;
+                int index = is_str(_game_vibration_on, "No") ? 0 : is_str(_game_vibration_on, "Yes") ? 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))
+            if (!easy_flipper_set_variable_item_list(&app->variable_item_list, FlipWorldViewVariableItemList, user_settings_select, callback_to_settings, &app->view_dispatcher, app))
             {
                 FURI_LOG_E(TAG, "Failed to allocate variable item list");
                 return false;
@@ -605,6 +659,16 @@ static void free_variable_item_list(void *context)
         free(app->variable_item_game_player_sprite);
         app->variable_item_game_player_sprite = NULL;
     }
+    if (app->variable_item_game_vgm_x)
+    {
+        free(app->variable_item_game_vgm_x);
+        app->variable_item_game_vgm_x = NULL;
+    }
+    if (app->variable_item_game_vgm_y)
+    {
+        free(app->variable_item_game_vgm_y);
+        app->variable_item_game_vgm_y = NULL;
+    }
     if (app->variable_item_user_username)
     {
         free(app->variable_item_user_username);
@@ -787,7 +851,7 @@ static bool _fetch_game(DataLoaderModel *model)
             view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewSubmenu); // just go back to the main menu for now
             return false;
         }
-        if (strcmp(is_logged_in, "false") == 0 && strcmp(model->title, "Registering...") == 0)
+        if (is_str(is_logged_in, "false") && is_str(model->title, "Registering..."))
         {
             // register
             char username[64];
@@ -928,7 +992,7 @@ static char *_parse_game(DataLoaderModel *model)
     }
     else if (model->request_index == 1)
     {
-        if (strcmp(model->title, "Registering...") == 0)
+        if (is_str(model->title, "Registering..."))
         {
             // check registration response
             if (model->fhttp->last_response != NULL && (strstr(model->fhttp->last_response, "[SUCCESS]") != NULL || strstr(model->fhttp->last_response, "User created") != NULL))
@@ -1022,7 +1086,7 @@ static char *_parse_game(DataLoaderModel *model)
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewSubmenu); // just go back to the main menu for now
     return "Unknown error";
 }
-void switch_to_view_get_game(FlipWorldApp *app)
+static void switch_to_view_get_game(FlipWorldApp *app)
 {
     generic_switch_to_view(app, "Starting Game..", _fetch_game, _parse_game, 5, callback_to_submenu, FlipWorldViewLoader);
 }
@@ -1352,7 +1416,7 @@ static void updated_password(void *context)
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewVariableItemList); // back to user settings
 }
 
-static void wifi_settings_item_selected(void *context, uint32_t index)
+static void wifi_settings_select(void *context, uint32_t index)
 {
     FlipWorldApp *app = (FlipWorldApp *)context;
     if (!app)
@@ -1405,9 +1469,9 @@ static void fps_change(VariableItem *item)
 {
     uint8_t index = variable_item_get_current_value_index(item);
     fps_index = index;
-    variable_item_set_current_value_text(item, fps_choices[index]);
+    variable_item_set_current_value_text(item, fps_choices_str[index]);
     variable_item_set_current_value_index(item, index);
-    save_char("Game-FPS", fps_choices[index]);
+    save_char("Game-FPS", fps_choices_str[index]);
 }
 static void screen_on_change(VariableItem *item)
 {
@@ -1437,10 +1501,26 @@ static void player_on_change(VariableItem *item)
 {
     uint8_t index = variable_item_get_current_value_index(item);
     player_sprite_index = index;
-    variable_item_set_current_value_text(item, strcmp(player_sprite_choices[index], "naked") == 0 ? "None" : player_sprite_choices[index]);
+    variable_item_set_current_value_text(item, is_str(player_sprite_choices[index], "naked") ? "None" : player_sprite_choices[index]);
     variable_item_set_current_value_index(item, index);
     save_char("Game-Player-Sprite", player_sprite_choices[index]);
 }
+static void vgm_x_change(VariableItem *item)
+{
+    uint8_t index = variable_item_get_current_value_index(item);
+    vgm_x_index = index;
+    variable_item_set_current_value_text(item, vgm_levels[index]);
+    variable_item_set_current_value_index(item, index);
+    save_char("Game-VGM-X", vgm_levels[index]);
+}
+static void vgm_y_change(VariableItem *item)
+{
+    uint8_t index = variable_item_get_current_value_index(item);
+    vgm_y_index = index;
+    variable_item_set_current_value_text(item, vgm_levels[index]);
+    variable_item_set_current_value_index(item, index);
+    save_char("Game-VGM-Y", vgm_levels[index]);
+}
 
 static bool _fetch_worlds(DataLoaderModel *model)
 {
@@ -1473,7 +1553,7 @@ static void switch_to_view_get_worlds(FlipWorldApp *app)
 {
     generic_switch_to_view(app, "Fetching World Pack..", _fetch_worlds, _parse_worlds, 1, callback_to_submenu, FlipWorldViewLoader);
 }
-static void game_settings_item_selected(void *context, uint32_t index)
+static void game_settings_select(void *context, uint32_t index)
 {
     FlipWorldApp *app = (FlipWorldApp *)context;
     if (!app)
@@ -1483,21 +1563,25 @@ static void game_settings_item_selected(void *context, uint32_t index)
     }
     switch (index)
     {
-    case 0: // Download all world data s one huge json
+    case 0: // Download all world data as one huge json
         switch_to_view_get_worlds(app);
     case 1: // Player Sprite
         break;
     case 2: // Change FPS
         break;
-    case 3: // Screen Always On
+    case 3: // VGM X
+        break;
+    case 4: // VGM Y
+        break;
+    case 5: // Screen Always On
         break;
-    case 4: // Sound On
+    case 6: // Sound On
         break;
-    case 5: // Vibration On
+    case 7: // Vibration On
         break;
     }
 }
-static void user_settings_item_selected(void *context, uint32_t index)
+static void user_settings_select(void *context, uint32_t index)
 {
     FlipWorldApp *app = (FlipWorldApp *)context;
     if (!app)
@@ -1751,15 +1835,15 @@ static void loader_process_callback(void *context)
             {
                 FURI_LOG_DEV(TAG, "PONG received.");
             }
-            else if (strncmp(loader_model->fhttp->last_response, "[SUCCESS]", 9) == 0)
+            else if (strncmp(loader_model->fhttp->last_response, "[SUCCESS]", 9))
             {
                 FURI_LOG_DEV(TAG, "SUCCESS received. %s", loader_model->fhttp->last_response ? loader_model->fhttp->last_response : "NULL");
             }
-            else if (strncmp(loader_model->fhttp->last_response, "[ERROR]", 9) == 0)
+            else if (strncmp(loader_model->fhttp->last_response, "[ERROR]", 9))
             {
                 FURI_LOG_DEV(TAG, "ERROR received. %s", loader_model->fhttp->last_response ? loader_model->fhttp->last_response : "NULL");
             }
-            else if (strlen(loader_model->fhttp->last_response) == 0)
+            else if (strlen(loader_model->fhttp->last_response))
             {
                 // Still waiting on response
             }

+ 7 - 2
flip_world.c

@@ -1,6 +1,5 @@
 #include <flip_world.h>
-char *fps_choices[] = {"30", "60", "120", "240"};
-const float fps_choices_2[] = {30.0, 60.0, 120.0, 240.0};
+char *fps_choices_str[] = {"30", "60", "120", "240"};
 int fps_index = 0;
 char *yes_or_no_choices[] = {"No", "Yes"};
 int screen_always_on_index = 1;
@@ -8,4 +7,10 @@ int sound_on_index = 0;
 int vibration_on_index = 0;
 char *player_sprite_choices[] = {"naked", "sword", "axe", "bow"};
 int player_sprite_index = 1;
+char *vgm_levels[] = {"-2", "-1", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
+int vgm_x_index = 2;
+int vgm_y_index = 2;
+float atof_(const char *nptr) { return (float)strtod(nptr, NULL); }
+float atof_furi(const FuriString *nptr) { return atof_(furi_string_get_cstr(nptr)); }
+bool is_str(const char *src, const char *dst) { return strcmp(src, dst) == 0; }
 bool is_enough_heap(size_t heap_size) { return memmgr_get_free_heap() > (heap_size + 1024); } // 1KB buffer

+ 10 - 3
flip_world.h

@@ -66,6 +66,8 @@ typedef struct
     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_game_player_sprite;    // The variable item for Player sprite
+    VariableItem *variable_item_game_vgm_x;            // The variable item for VGM X
+    VariableItem *variable_item_game_vgm_y;            // The variable item for VGM Y
     //
     VariableItem *variable_item_user_username; // The variable item for the User username
     VariableItem *variable_item_user_password; // The variable item for the User password
@@ -76,8 +78,7 @@ typedef struct
     uint32_t text_input_buffer_size; // Size of the text input buffer
 } FlipWorldApp;
 
-extern char *fps_choices[];
-extern const float fps_choices_2[];
+extern char *fps_choices_str[];
 extern int fps_index;
 extern char *yes_or_no_choices[];
 extern int screen_always_on_index;
@@ -85,4 +86,10 @@ extern int sound_on_index;
 extern int vibration_on_index;
 extern char *player_sprite_choices[];
 extern int player_sprite_index;
-bool is_enough_heap(size_t heap_size);
+extern char *vgm_levels[];
+extern int vgm_x_index;
+extern int vgm_y_index;
+float atof_(const char *nptr);
+float atof_furi(const FuriString *nptr);
+bool is_str(const char *src, const char *dst);
+bool is_enough_heap(size_t heap_size);

+ 2 - 2
game/draw.c

@@ -87,11 +87,11 @@ void draw_icon_line(Canvas *canvas, Vector pos, int amount, bool horizontal, con
         }
     }
 }
-char g_temp_spawn_name[32];
+char g_name[32];
 // Draw an icon at a specific position (with collision detection)
 void spawn_icon(Level *level, const char *icon_id, float x, float y)
 {
-    snprintf(g_temp_spawn_name, sizeof(g_temp_spawn_name), "%s", icon_id);
+    snprintf(g_name, sizeof(g_name), "%s", icon_id);
     Entity *e = level_add_entity(level, &icon_desc);
     entity_pos_set(e, (Vector){x, y});
 }

+ 1 - 2
game/draw.h

@@ -11,5 +11,4 @@ void draw_username(Canvas *canvas, Vector pos, char *username);
 void draw_icon_line(Canvas *canvas, Vector pos, int amount, bool horizontal, const Icon *icon);
 void spawn_icon(Level *level, const char *icon_id, float x, float y);
 void spawn_icon_line(Level *level, const char *icon_id, float x, float y, uint8_t amount, bool horizontal);
-extern char g_temp_spawn_name[32];
-// create custom icons at https://lopaka.app/sandbox
+extern char g_name[32];

+ 7 - 7
game/enemy.c

@@ -762,13 +762,13 @@ void spawn_enemy_json_furi(Level *level, GameManager *manager, FuriString *json)
                                                                                        manager,
                                                                                        furi_string_get_cstr(id),
                                                                                        atoi(furi_string_get_cstr(_index)),
-                                                                                       (Vector){strtod(furi_string_get_cstr(start_position_x), NULL), strtod(furi_string_get_cstr(start_position_y), NULL)},
-                                                                                       (Vector){strtod(furi_string_get_cstr(end_position_x), NULL), strtod(furi_string_get_cstr(end_position_y), NULL)},
-                                                                                       strtod(furi_string_get_cstr(move_timer), NULL),
-                                                                                       strtod(furi_string_get_cstr(speed), NULL),
-                                                                                       strtod(furi_string_get_cstr(attack_timer), NULL),
-                                                                                       strtod(furi_string_get_cstr(strength), NULL),
-                                                                                       strtod(furi_string_get_cstr(health), NULL)));
+                                                                                       (Vector){atof_furi(start_position_x), atof_furi(start_position_y)},
+                                                                                       (Vector){atof_furi(end_position_x), atof_furi(end_position_y)},
+                                                                                       atof_furi(move_timer),
+                                                                                       atof_furi(speed),
+                                                                                       atof_furi(attack_timer),
+                                                                                       atof_furi(strength),
+                                                                                       atof_furi(health)));
         game_context->enemy_count++;
     }
 

+ 1 - 1
game/game.c

@@ -11,7 +11,7 @@ static void game_start(GameManager *game_manager, void *ctx)
     // Do some initialization here, for example you can load score from storage.
     // For simplicity, we will just set it to 0.
     GameContext *game_context = ctx;
-    game_context->fps = fps_choices_2[fps_index];
+    game_context->fps = atof_(fps_choices_str[fps_index]);
     game_context->player_context = NULL;
     game_context->current_level = 0;
     game_context->ended_early = false;

+ 53 - 53
game/icon.c

@@ -4,8 +4,8 @@ static void icon_collision(Entity *self, Entity *other, GameManager *manager, vo
 {
     UNUSED(manager);
     UNUSED(self);
-    IconContext *icon_ctx = (IconContext *)context;
-    if (!icon_ctx)
+    IconContext *ictx = (IconContext *)context;
+    if (!ictx)
     {
         FURI_LOG_E("Game", "Icon context is NULL");
         return;
@@ -32,8 +32,8 @@ static void icon_collision(Entity *self, Entity *other, GameManager *manager, vo
 static void icon_render(Entity *self, GameManager *manager, Canvas *canvas, void *context)
 {
     UNUSED(manager);
-    IconContext *icon_ctx = (IconContext *)context;
-    if (!icon_ctx)
+    IconContext *ictx = (IconContext *)context;
+    if (!ictx)
     {
         FURI_LOG_E("Game", "Icon context is NULL");
         return;
@@ -43,50 +43,50 @@ static void icon_render(Entity *self, GameManager *manager, Canvas *canvas, void
     // Draw the icon, centered
     canvas_draw_icon(
         canvas,
-        pos.x - camera_x - icon_ctx->width / 2,
-        pos.y - camera_y - icon_ctx->height / 2,
-        icon_ctx->icon);
+        pos.x - camera_x - ictx->width / 2,
+        pos.y - camera_y - ictx->height / 2,
+        ictx->icon);
 }
 
 static void icon_start(Entity *self, GameManager *manager, void *context)
 {
     UNUSED(manager);
 
-    IconContext *icon_ctx_self = (IconContext *)context;
-    if (!icon_ctx_self)
+    IconContext *ictx_self = (IconContext *)context;
+    if (!ictx_self)
     {
         FURI_LOG_E("Game", "Icon context self is NULL");
         return;
     }
-    IconContext *icon_ctx = entity_context_get(self);
-    if (!icon_ctx)
+    IconContext *ictx = entity_context_get(self);
+    if (!ictx)
     {
         FURI_LOG_E("Game", "Icon context is NULL");
         return;
     }
 
-    IconContext *loaded_data = get_icon_context(g_temp_spawn_name);
+    IconContext *loaded_data = get_icon_context(g_name);
     if (!loaded_data)
     {
-        FURI_LOG_E("Game", "Failed to find icon data for %s", g_temp_spawn_name);
+        FURI_LOG_E("Game", "Failed to find icon data for %s", g_name);
         return;
     }
 
-    icon_ctx_self->icon = loaded_data->icon;
-    icon_ctx_self->width = loaded_data->width;
-    icon_ctx_self->height = loaded_data->height;
-    icon_ctx->icon = loaded_data->icon;
-    icon_ctx->width = loaded_data->width;
-    icon_ctx->height = loaded_data->height;
+    ictx_self->icon = loaded_data->icon;
+    ictx_self->width = loaded_data->width;
+    ictx_self->height = loaded_data->height;
+    ictx->icon = loaded_data->icon;
+    ictx->width = loaded_data->width;
+    ictx->height = loaded_data->height;
 
     Vector pos = entity_pos_get(self);
-    pos.x += icon_ctx_self->width / 2;
-    pos.y += icon_ctx_self->height / 2;
+    pos.x += ictx_self->width / 2;
+    pos.y += ictx_self->height / 2;
     entity_pos_set(self, pos);
 
     entity_collider_add_circle(
         self,
-        (icon_ctx_self->width + icon_ctx_self->height) / 4);
+        (ictx_self->width + ictx_self->height) / 4);
 
     free(loaded_data);
 }
@@ -131,128 +131,128 @@ static IconContext *icon_generic_alloc(const char *id, const Icon *icon, uint8_t
 
 IconContext *get_icon_context(const char *name)
 {
-    // if (strcmp(name, "earth") == 0)
+    // if (is_str(name, "earth") )
     // {
     //     return icon_generic_alloc("earth", &I_icon_earth_15x16, 15, 16);
     // }
-    // else if (strcmp(name, "home") == 0)
+    // else if (is_str(name, "home") )
     // {
     //     return icon_generic_alloc("home", &I_icon_home_15x16, 15, 16);
     // }
-    if (strcmp(name, "house") == 0)
+    if (is_str(name, "house"))
     {
         return icon_generic_alloc("house", &I_icon_house_48x32px, 48, 32);
     }
-    // else if (strcmp(name, "house_3d") == 0)
+    // else if (is_str(name, "house_3d") )
     // {
     //     return icon_generic_alloc("house_3d", &I_icon_house_3d_34x45px, 34, 45);
     // }
-    // else if (strcmp(name, "info") == 0)
+    // else if (is_str(name, "info") )
     // {
     //     return icon_generic_alloc("info", &I_icon_info_15x16, 15, 16);
     // }
-    else if (strcmp(name, "man") == 0)
+    else if (is_str(name, "man"))
     {
         return icon_generic_alloc("man", &I_icon_man_7x16, 7, 16);
     }
-    else if (strcmp(name, "plant") == 0)
+    else if (is_str(name, "plant"))
     {
         return icon_generic_alloc("plant", &I_icon_plant_16x16, 16, 16);
     }
-    // else if (strcmp(name, "plant_fern") == 0)
+    // else if (is_str(name, "plant_fern") )
     // {
     //     return icon_generic_alloc("plant_fern", &I_icon_plant_fern_18x16px, 18, 16);
     // }
-    // else if (strcmp(name, "plant_pointy") == 0)
+    // else if (is_str(name, "plant_pointy") )
     // {
     //     return icon_generic_alloc("plant_pointy", &I_icon_plant_pointy_13x16px, 13, 16);
     // }
-    else if (strcmp(name, "tree") == 0)
+    else if (is_str(name, "tree"))
     {
         return icon_generic_alloc("tree", &I_icon_tree_16x16, 16, 16);
     }
-    // else if (strcmp(name, "tree_29x30") == 0)
+    // else if (is_str(name, "tree_29x30") )
     // {
     //     return icon_generic_alloc("tree_29x30", &I_icon_tree_29x30px, 29, 30);
     // }
-    // else if (strcmp(name, "tree_48x48") == 0)
+    // else if (is_str(name, "tree_48x48") )
     // {
     //     return icon_generic_alloc("tree_48x48", &I_icon_tree_48x48px, 48, 48);
     // }
-    else if (strcmp(name, "woman") == 0)
+    else if (is_str(name, "woman"))
     {
         return icon_generic_alloc("woman", &I_icon_woman_9x16, 9, 16);
     }
-    // else if (strcmp(name, "chest_closed") == 0)
+    // else if (is_str(name, "chest_closed") )
     // {
     //     return icon_generic_alloc("chest_closed", &I_icon_chest_closed_16x13px, 16, 13);
     // }
-    // else if (strcmp(name, "chest_open") == 0)
+    // else if (is_str(name, "chest_open") )
     // {
     //     return icon_generic_alloc("chest_open", &I_icon_chest_open_16x16px, 16, 16);
     // }
-    else if (strcmp(name, "fence") == 0)
+    else if (is_str(name, "fence"))
     {
         return icon_generic_alloc("fence", &I_icon_fence_16x8px, 16, 8);
     }
-    else if (strcmp(name, "fence_end") == 0)
+    else if (is_str(name, "fence_end"))
     {
         return icon_generic_alloc("fence_end", &I_icon_fence_end_16x8px, 16, 8);
     }
-    // else if (strcmp(name, "fence_vertical_end") == 0)
+    // else if (is_str(name, "fence_vertical_end") )
     // {
     //     return icon_generic_alloc("fence_vertical_end", &I_icon_fence_vertical_end_6x8px, 6, 8);
     // }
-    // else if (strcmp(name, "fence_vertical_start") == 0)
+    // else if (is_str(name, "fence_vertical_start") )
     // {
     //     return icon_generic_alloc("fence_vertical_start", &I_icon_fence_vertical_start_6x15px, 6, 15);
     // }
-    else if (strcmp(name, "flower") == 0)
+    else if (is_str(name, "flower"))
     {
         return icon_generic_alloc("flower", &I_icon_flower_16x16, 16, 16);
     }
-    else if (strcmp(name, "lake_bottom") == 0)
+    else if (is_str(name, "lake_bottom"))
     {
         return icon_generic_alloc("lake_bottom", &I_icon_lake_bottom_31x12px, 31, 12);
     }
-    else if (strcmp(name, "lake_bottom_left") == 0)
+    else if (is_str(name, "lake_bottom_left"))
     {
         return icon_generic_alloc("lake_bottom_left", &I_icon_lake_bottom_left_24x22px, 24, 22);
     }
-    else if (strcmp(name, "lake_bottom_right") == 0)
+    else if (is_str(name, "lake_bottom_right"))
     {
         return icon_generic_alloc("lake_bottom_right", &I_icon_lake_bottom_right_24x22px, 24, 22);
     }
-    else if (strcmp(name, "lake_left") == 0)
+    else if (is_str(name, "lake_left"))
     {
         return icon_generic_alloc("lake_left", &I_icon_lake_left_11x31px, 11, 31);
     }
-    else if (strcmp(name, "lake_right") == 0)
+    else if (is_str(name, "lake_right"))
     {
         // Assuming 11x31
         return icon_generic_alloc("lake_right", &I_icon_lake_right_11x31, 11, 31);
     }
-    else if (strcmp(name, "lake_top") == 0)
+    else if (is_str(name, "lake_top"))
     {
         return icon_generic_alloc("lake_top", &I_icon_lake_top_31x12px, 31, 12);
     }
-    else if (strcmp(name, "lake_top_left") == 0)
+    else if (is_str(name, "lake_top_left"))
     {
         return icon_generic_alloc("lake_top_left", &I_icon_lake_top_left_24x22px, 24, 22);
     }
-    else if (strcmp(name, "lake_top_right") == 0)
+    else if (is_str(name, "lake_top_right"))
     {
         return icon_generic_alloc("lake_top_right", &I_icon_lake_top_right_24x22px, 24, 22);
     }
-    else if (strcmp(name, "rock_large") == 0)
+    else if (is_str(name, "rock_large"))
     {
         return icon_generic_alloc("rock_large", &I_icon_rock_large_18x19px, 18, 19);
     }
-    else if (strcmp(name, "rock_medium") == 0)
+    else if (is_str(name, "rock_medium"))
     {
         return icon_generic_alloc("rock_medium", &I_icon_rock_medium_16x14px, 16, 14);
     }
-    else if (strcmp(name, "rock_small") == 0)
+    else if (is_str(name, "rock_small"))
     {
         return icon_generic_alloc("rock_small", &I_icon_rock_small_10x8px, 10, 8);
     }

+ 32 - 61
game/player.c

@@ -1,5 +1,8 @@
 #include <game/player.h>
 #include <game/storage.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
 /****** Entities: Player ******/
 static Level *next_level(GameManager *manager)
 {
@@ -36,7 +39,6 @@ static Level *next_level(GameManager *manager)
         game_context->current_level = i;
         return game_context->levels[i];
     }
-    FURI_LOG_I(TAG, "No more levels to load");
     return NULL;
 }
 
@@ -132,7 +134,6 @@ void player_spawn(Level *level, GameManager *manager)
     pctx->start_position = entity_pos_get(game_context->player);
 
     // Update player stats based on XP using iterative method
-    // Function to get the current level based on XP iteratively
     int get_player_level_iterative(uint32_t xp)
     {
         int level = 1;
@@ -158,33 +159,36 @@ void player_spawn(Level *level, GameManager *manager)
     game_context->player_context = pctx;
 }
 
-// code from Derek Jamison
-// eventually we'll add dynamic positioning based on how much pitch/roll is detected
-// instead of assigning a fixed value
-static int vgm_x(float pitch)
+static void vgm_direction(Imu *imu, PlayerContext *player, Vector *pos)
 {
-    if (pitch > 6.0)
+    const float pitch = -imu_pitch_get(imu);
+    const float roll = -imu_roll_get(imu);
+    const float min_x = atof_(vgm_levels[vgm_x_index]) + 5.0; // minimum of 3
+    const float min_y = atof_(vgm_levels[vgm_y_index]) + 5.0; // minimum of 3
+    if (pitch > min_x)
     {
-        return 1;
+        pos->x += abs((int)round(pitch / min_x));
+        player->dx = 1;
+        player->direction = PLAYER_RIGHT;
     }
-    else if (pitch < -8.0)
+    else if (pitch < -min_x)
     {
-        return -1;
+        pos->x += -abs((int)round(pitch / min_x));
+        player->dx = -1;
+        player->direction = PLAYER_LEFT;
     }
-    return 0;
-}
-
-static int vgm_y(float roll)
-{
-    if (roll > 9.0)
+    if (roll > min_y)
     {
-        return 1;
+        pos->y += abs((int)round(roll / min_y));
+        player->dy = 1;
+        player->direction = PLAYER_DOWN;
     }
-    else if (roll < -20.0)
+    else if (roll < -min_y)
     {
-        return -1;
+        pos->y += -abs((int)round(roll / min_y));
+        player->dy = -1;
+        player->direction = PLAYER_UP;
     }
-    return 0;
 }
 
 static void player_update(Entity *self, GameManager *manager, void *context)
@@ -207,36 +211,7 @@ static void player_update(Entity *self, GameManager *manager, void *context)
 
     if (game_context->imu_present)
     {
-        player->dx = vgm_x(-imu_pitch_get(game_context->imu));
-        player->dy = vgm_y(-imu_roll_get(game_context->imu));
-
-        switch (player->dx)
-        {
-        case -1:
-            player->direction = PLAYER_LEFT;
-            pos.x -= 1;
-            break;
-        case 1:
-            player->direction = PLAYER_RIGHT;
-            pos.x += 1;
-            break;
-        default:
-            break;
-        }
-
-        switch (player->dy)
-        {
-        case -1:
-            player->direction = PLAYER_UP;
-            pos.y -= 1;
-            break;
-        case 1:
-            player->direction = PLAYER_DOWN;
-            pos.y += 1;
-            break;
-        default:
-            break;
-        }
+        vgm_direction(game_context->imu, player, &pos);
     }
 
     // Apply health regeneration
@@ -367,7 +342,6 @@ static void player_update(Entity *self, GameManager *manager, void *context)
             game_context->menu_screen = GAME_MENU_INFO;
             game_context->menu_selection = 0;
             game_context->is_menu_open = true;
-            FURI_LOG_I(TAG, "Menu opened");
         }
     }
     if (input.held & GameKeyBack)
@@ -382,7 +356,6 @@ static void player_update(Entity *self, GameManager *manager, void *context)
         if (game_context->is_menu_open)
         {
             game_context->is_menu_open = false;
-            FURI_LOG_I(TAG, "Menu closed");
         }
 
         // if the back button is held for 1 seconds, stop the game
@@ -411,9 +384,7 @@ static void player_update(Entity *self, GameManager *manager, void *context)
         player->state = PLAYER_IDLE;
     }
     else
-    {
         player->state = PLAYER_MOVING;
-    }
 }
 
 static void player_render(Entity *self, GameManager *manager, Canvas *canvas, void *context)
@@ -475,31 +446,31 @@ static SpriteContext *sprite_generic_alloc(const char *id, bool is_enemy, uint8_
 
 SpriteContext *get_sprite_context(const char *name)
 {
-    if (strcmp(name, "axe") == 0)
+    if (is_str(name, "axe"))
     {
         return sprite_generic_alloc("axe", false, 15, 11);
     }
-    else if (strcmp(name, "bow") == 0)
+    else if (is_str(name, "bow"))
     {
         return sprite_generic_alloc("bow", false, 13, 11);
     }
-    else if (strcmp(name, "naked") == 0)
+    else if (is_str(name, "naked"))
     {
         return sprite_generic_alloc("naked", false, 10, 10);
     }
-    else if (strcmp(name, "sword") == 0)
+    else if (is_str(name, "sword"))
     {
         return sprite_generic_alloc("sword", false, 15, 11);
     }
-    else if (strcmp(name, "cyclops") == 0)
+    else if (is_str(name, "cyclops"))
     {
         return sprite_generic_alloc("cyclops", true, 10, 11);
     }
-    else if (strcmp(name, "ghost") == 0)
+    else if (is_str(name, "ghost"))
     {
         return sprite_generic_alloc("ghost", true, 15, 15);
     }
-    else if (strcmp(name, "ogre") == 0)
+    else if (is_str(name, "ogre"))
     {
         return sprite_generic_alloc("ogre", true, 10, 13);
     }

+ 1 - 1
game/player.h

@@ -5,7 +5,7 @@
 #include "engine/sensors/imu.h"
 
 // Maximum enemies
-#define MAX_ENEMIES 2
+#define MAX_ENEMIES 10
 #define MAX_LEVELS 10
 
 typedef enum