Просмотр исходного кода

Added auto save/load game state to save high score

SimplyMinimal 3 лет назад
Родитель
Сommit
5829369a85
1 измененных файлов с 44 добавлено и 1 удалено
  1. 44 1
      app.c

+ 44 - 1
app.c

@@ -3,6 +3,7 @@
 
 #include <furi.h>
 #include <furi_hal.h>
+#include <storage/storage.h>
 #include <input/input.h>
 #include <gui/gui.h>
 #include <stdlib.h>
@@ -22,6 +23,8 @@
 #define MAXBUL 5 /* Max bullets on the screen. */
 #define MAXAST 32 /* Max asteroids on the screen. */
 #define SHIP_HIT_ANIMATION_LEN 15
+#define SAVING_DIRECTORY "/ext/apps/Games"
+#define SAVING_FILENAME SAVING_DIRECTORY "/game_asteroids.save"
 #ifndef PI
 #define PI 3.14159265358979f
 #endif
@@ -117,7 +120,8 @@ const NotificationSequence sequence_bullet_fired = {
 /* ============================== Prototyeps ================================ */
 
 // Only functions called before their definition are here.
-
+bool load_game(AsteroidsApp* app);
+void save_game(AsteroidsApp* app);
 void restart_game_after_gameover(AsteroidsApp* app);
 uint32_t key_pressed_time(AsteroidsApp* app, InputKey key);
 
@@ -443,6 +447,7 @@ void asteroid_was_hit(AsteroidsApp* app, int id) {
 /* Set gameover state. When in game-over mode, the game displays a gameover
  * text with a background of many asteroids floating around. */
 void game_over(AsteroidsApp* app) {
+    save_game(app); // Save highscore
     restart_game_after_gameover(app);
     app->gameover = true;
     int asteroids = 8;
@@ -620,6 +625,41 @@ void game_tick(void* ctx) {
 
 /* ======================== Flipper specific code =========================== */
 
+bool load_game(AsteroidsApp* app) {
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+
+    File* file = storage_file_alloc(storage);
+    uint16_t bytes_readed = 0;
+    if(storage_file_open(file, SAVING_FILENAME, FSAM_READ, FSOM_OPEN_EXISTING)) {
+        bytes_readed = storage_file_read(file, app, sizeof(AsteroidsApp));
+    }
+    storage_file_close(file);
+    storage_file_free(file);
+
+    furi_record_close(RECORD_STORAGE);
+
+    return bytes_readed == sizeof(AsteroidsApp);
+}
+
+void save_game(AsteroidsApp* app) {
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+
+    if(storage_common_stat(storage, SAVING_DIRECTORY, NULL) == FSE_NOT_EXIST) {
+        if(!storage_simply_mkdir(storage, SAVING_DIRECTORY)) {
+            return;
+        }
+    }
+
+    File* file = storage_file_alloc(storage);
+    if(storage_file_open(file, SAVING_FILENAME, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
+        storage_file_write(file, app, sizeof(AsteroidsApp));
+    }
+    storage_file_close(file);
+    storage_file_free(file);
+
+    furi_record_close(RECORD_STORAGE);
+}
+
 /* Here all we do is putting the events into the queue that will be handled
  * in the while() loop of the app entry point function. */
 void input_callback(InputEvent* input_event, void* ctx) {
@@ -632,6 +672,8 @@ void input_callback(InputEvent* input_event, void* ctx) {
 AsteroidsApp* asteroids_app_alloc() {
     AsteroidsApp* app = malloc(sizeof(AsteroidsApp));
 
+    load_game(app);
+
     app->gui = furi_record_open(RECORD_GUI);
     app->view_port = view_port_alloc();
     view_port_draw_callback_set(app->view_port, render_callback, app);
@@ -640,6 +682,7 @@ AsteroidsApp* asteroids_app_alloc() {
     app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
 
     app->running = 1; /* Turns 0 when back is pressed. */
+
     restart_game_after_gameover(app);
     memset(app->pressed, 0, sizeof(app->pressed));
     return app;