game_settings.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include "game_settings.h"
  2. #include <flipper_format/flipper_format.h>
  3. #include <storage/storage.h>
  4. #define SETTINGS_FILE_NAME "settings.txt"
  5. #define SETTING_FILE_TYPE "Quadrastic Game Setting File"
  6. #define SETTING_FILE_VERSION 1
  7. #define KEY_DIFFICULTY "Difficulty"
  8. #define KEY_BEST_SCORE "Best score"
  9. #define KEY_SOUND "Sound"
  10. #define KEY_VIBRO "Vibro"
  11. #define KEY_LED "LED"
  12. static bool
  13. game_read_bool_setting(FlipperFormat* flipper_format,
  14. const char* key,
  15. State* setting)
  16. {
  17. if (!flipper_format_rewind(flipper_format)) {
  18. FURI_LOG_E(GAME_NAME, "Rewind error");
  19. return false;
  20. }
  21. bool temp_bool = *setting;
  22. if (!flipper_format_read_bool(flipper_format, key, &temp_bool, 1)) {
  23. FURI_LOG_E(GAME_NAME, "Can't read %s setting", key);
  24. return false;
  25. }
  26. *setting = temp_bool ? StateOn : StateOff;
  27. return true;
  28. }
  29. void
  30. game_read_settings(GameContext* game_context)
  31. {
  32. // Default settings
  33. game_context->score = 0;
  34. game_context->best_score = 0;
  35. game_context->difficulty = DifficultyNormal;
  36. game_context->sound = StateOn;
  37. game_context->vibro = StateOn;
  38. game_context->led = StateOn;
  39. // Read settings
  40. Storage* storage = furi_record_open(RECORD_STORAGE);
  41. FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
  42. FuriString* temp_string = furi_string_alloc();
  43. uint32_t temp_uint32;
  44. do {
  45. // Check settings file
  46. if (!flipper_format_file_open_existing(
  47. flipper_format, APP_DATA_PATH(SETTINGS_FILE_NAME))) {
  48. FURI_LOG_D(GAME_NAME, "Settings file is not used");
  49. break;
  50. }
  51. if (!flipper_format_read_header(
  52. flipper_format, temp_string, &temp_uint32)) {
  53. FURI_LOG_E(GAME_NAME, "Missing or incorrect header");
  54. break;
  55. }
  56. if ((!strcmp(furi_string_get_cstr(temp_string), SETTING_FILE_TYPE)) &&
  57. temp_uint32 == SETTING_FILE_VERSION) {
  58. } else {
  59. FURI_LOG_E(GAME_NAME, "Type or version mismatch");
  60. break;
  61. }
  62. // Read difficulty
  63. temp_uint32 = (uint32_t)game_context->difficulty;
  64. if (!flipper_format_read_uint32(
  65. flipper_format, KEY_DIFFICULTY, &temp_uint32, 1)) {
  66. FURI_LOG_E(GAME_NAME, "Can't read " KEY_DIFFICULTY " setting");
  67. break;
  68. }
  69. if (temp_uint32 >= DifficultyCount) {
  70. temp_uint32 = DifficultyCount - 1;
  71. }
  72. game_context->difficulty = temp_uint32;
  73. // Read best score
  74. temp_uint32 = game_context->best_score;
  75. if (!flipper_format_read_uint32(
  76. flipper_format, KEY_BEST_SCORE, &temp_uint32, 1)) {
  77. FURI_LOG_E(GAME_NAME, "Can't read " KEY_BEST_SCORE " setting");
  78. break;
  79. }
  80. game_context->best_score = temp_uint32;
  81. // Read sound
  82. if (!game_read_bool_setting(
  83. flipper_format, KEY_SOUND, &game_context->sound)) {
  84. break;
  85. }
  86. // Read vibro
  87. if (!game_read_bool_setting(
  88. flipper_format, KEY_VIBRO, &game_context->vibro)) {
  89. break;
  90. }
  91. // Read led
  92. if (!game_read_bool_setting(
  93. flipper_format, KEY_LED, &game_context->led)) {
  94. break;
  95. }
  96. } while (false);
  97. furi_string_free(temp_string);
  98. flipper_format_free(flipper_format);
  99. furi_record_close(RECORD_STORAGE);
  100. FURI_LOG_I(GAME_NAME, "Settings read");
  101. }
  102. void
  103. game_save_settings(GameContext* game_context)
  104. {
  105. Storage* storage = furi_record_open(RECORD_STORAGE);
  106. FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
  107. bool temp_bool;
  108. uint32_t temp_uint32;
  109. do {
  110. // Write settings meta
  111. if (!flipper_format_file_open_always(
  112. flipper_format, APP_DATA_PATH(SETTINGS_FILE_NAME))) {
  113. FURI_LOG_E(GAME_NAME, "Settings file can't be saved");
  114. break;
  115. }
  116. if (!flipper_format_write_header_cstr(
  117. flipper_format, SETTING_FILE_TYPE, SETTING_FILE_VERSION)) {
  118. FURI_LOG_E(GAME_NAME, "Settings header can't be saved");
  119. break;
  120. }
  121. // Write difficulty
  122. temp_uint32 = game_context->difficulty;
  123. if (!flipper_format_write_uint32(
  124. flipper_format, KEY_DIFFICULTY, &temp_uint32, 1)) {
  125. FURI_LOG_E(GAME_NAME, "Difficulty state can't be saved");
  126. break;
  127. }
  128. // Write best score
  129. temp_uint32 = game_context->best_score;
  130. if (!flipper_format_write_uint32(
  131. flipper_format, KEY_BEST_SCORE, &temp_uint32, 1)) {
  132. FURI_LOG_E(GAME_NAME, "Best score state can't be saved");
  133. break;
  134. }
  135. // Write sound
  136. temp_bool = game_context->sound == StateOn;
  137. if (!flipper_format_write_bool(
  138. flipper_format, "Sound", &temp_bool, 1)) {
  139. FURI_LOG_E(GAME_NAME, "Sound state can't be saved");
  140. break;
  141. }
  142. // Write vibro
  143. temp_bool = game_context->vibro == StateOn;
  144. if (!flipper_format_write_bool(
  145. flipper_format, "Vibro", &temp_bool, 1)) {
  146. FURI_LOG_E(GAME_NAME, "Vibro state can't be saved");
  147. break;
  148. }
  149. // Write led
  150. temp_bool = game_context->led == StateOn;
  151. if (!flipper_format_write_bool(flipper_format, "LED", &temp_bool, 1)) {
  152. FURI_LOG_E(GAME_NAME, "LED state can't be saved");
  153. break;
  154. }
  155. } while (false);
  156. flipper_format_free(flipper_format);
  157. furi_record_close(RECORD_STORAGE);
  158. FURI_LOG_I(GAME_NAME, "Settings saved");
  159. }