boilerplate_scene_2.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #include "../malveke_gb_photo.h"
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include <input/input.h>
  5. #include <gui/elements.h>
  6. #include <dolphin/dolphin.h>
  7. struct BoilerplateScene2 {
  8. View* view;
  9. BoilerplateScene2Callback callback;
  10. void* context;
  11. };
  12. typedef struct {
  13. bool in_progress;
  14. int page;
  15. BoilerplateScene2* instance;
  16. } BoilerplateScene2Model;
  17. void boilerplate_scene_2_set_callback(
  18. BoilerplateScene2* instance,
  19. BoilerplateScene2Callback callback,
  20. void* context) {
  21. furi_assert(instance);
  22. furi_assert(callback);
  23. instance->callback = callback;
  24. instance->context = context;
  25. }
  26. void draw_thumbnail(void* context, Canvas* canvas, int page) {
  27. BoilerplateScene2* instance = context;
  28. Boilerplate* app = instance->context;
  29. UNUSED(app);
  30. // Gallery
  31. // for (int s=0;s< 8 * (page+1);s++) {
  32. int count = ((page + 2) * 0x1000) + 0x0e00;
  33. storage_file_seek(app->camera_ram_sav, count, true);
  34. for(int y = 0; y < 4; y++) {
  35. for(int x = 0; x < 4; x++) {
  36. storage_file_read(app->camera_ram_sav, app->tile_data, sizeof(app->tile_data));
  37. for(int row = 0; row < 8; row++) {
  38. uint8_t temp1 = app->tile_data[row * 2];
  39. uint8_t temp2 = app->tile_data[row * 2 + 1];
  40. for(int pixel = 7; pixel >= 0; pixel--) {
  41. int colorIndex = ((temp1 & 1) + ((temp2 & 1) * 2));
  42. if(colorIndex >= 2) {
  43. canvas_draw_dot(canvas, (x * 8) + (pixel + 47), (y * 8) + row + 17);
  44. }
  45. temp1 >>= 1;
  46. temp2 >>= 1;
  47. }
  48. }
  49. }
  50. }
  51. // }
  52. }
  53. void boilerplate_scene_2_draw(Canvas* canvas, BoilerplateScene2Model* model) {
  54. UNUSED(model);
  55. BoilerplateScene2* instance = model->instance;
  56. Boilerplate* app = instance->context;
  57. UNUSED(app);
  58. canvas_clear(canvas);
  59. canvas_set_color(canvas, ColorBlack);
  60. canvas_set_font(canvas, FontPrimary);
  61. canvas_draw_str(canvas, 21, 13, "Export All Photos");
  62. canvas_set_font(canvas, FontPrimary);
  63. char totalText[32];
  64. snprintf(totalText, sizeof(totalText), "%02d/29", model->page);
  65. draw_thumbnail(instance, canvas, model->page);
  66. if(!model->in_progress) {
  67. elements_button_center(canvas, "OK");
  68. } else {
  69. float dict_progress = (float)(model->page * 1) / (float)(29);
  70. int progress_width = 128 / 2;
  71. int position_x = (128 / 2);
  72. int position_y = 52;
  73. elements_progress_bar_with_text(
  74. canvas,
  75. position_x - (progress_width / 2),
  76. position_y,
  77. progress_width,
  78. dict_progress,
  79. totalText);
  80. }
  81. }
  82. static void boilerplate_scene_2_model_init(BoilerplateScene2Model* const model, void* context) {
  83. BoilerplateScene2* instance = context;
  84. model->instance = instance;
  85. model->page = 0;
  86. model->in_progress = false;
  87. }
  88. void save_all_image(void* context) {
  89. BoilerplateScene2* instance = context;
  90. Boilerplate* app = instance->context;
  91. UNUSED(app);
  92. furi_assert(app);
  93. NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION);
  94. // Create MALVEKE dir
  95. if(storage_common_stat(app->storage, MALVEKE_APP_FOLDER, NULL) == FSE_NOT_EXIST) {
  96. storage_simply_mkdir(app->storage, MALVEKE_APP_FOLDER);
  97. }
  98. // Create MALVEKE Photos dir
  99. if(storage_common_stat(app->storage, MALVEKE_APP_FOLDER_PHOTOS, NULL) == FSE_NOT_EXIST) {
  100. storage_simply_mkdir(app->storage, MALVEKE_APP_FOLDER_PHOTOS);
  101. }
  102. for(int page = 0; page < 30; page++) {
  103. int count = (page + 1) * 0x1000;
  104. storage_file_seek(app->camera_ram_sav, count, true);
  105. // create file name
  106. FuriString* file_name = furi_string_alloc();
  107. get_timefilename(file_name, page);
  108. File* file = storage_file_alloc(app->storage);
  109. bool result =
  110. storage_file_open(file, furi_string_get_cstr(file_name), FSAM_WRITE, FSOM_OPEN_ALWAYS);
  111. if(result) {
  112. static char bmp[BMP_SIZE(WIDTH, HEIGHT)];
  113. bmp_init(bmp, WIDTH, HEIGHT);
  114. // Selected Palette
  115. uint32_t palette[] = {
  116. bmp_encode(app->palette_color_hex_a),
  117. bmp_encode(app->palette_color_hex_b),
  118. bmp_encode(app->palette_color_hex_c),
  119. bmp_encode(app->palette_color_hex_d)};
  120. UNUSED(palette);
  121. for(int y = 0; y < 14; y++) {
  122. for(int x = 0; x < 16; x++) {
  123. storage_file_read(app->camera_ram_sav, app->tile_data, sizeof(app->tile_data));
  124. for(int row = 0; row < 8; row++) {
  125. uint8_t temp1 = app->tile_data[row * 2];
  126. uint8_t temp2 = app->tile_data[row * 2 + 1];
  127. for(int pixel = 7; pixel >= 0; pixel--) {
  128. bmp_set(
  129. bmp,
  130. (x * 8) + pixel,
  131. (y * 8) + row,
  132. palette[((temp1 & 1) + ((temp2 & 1) * 2))]);
  133. temp1 >>= 1;
  134. temp2 >>= 1;
  135. }
  136. }
  137. }
  138. }
  139. storage_file_write(file, bmp, sizeof(bmp));
  140. with_view_model(
  141. instance->view,
  142. BoilerplateScene2Model * model,
  143. {
  144. // UNUSED(model);
  145. model->page = page;
  146. },
  147. true);
  148. furi_delay_ms(120);
  149. }
  150. // Closing the "file descriptor"
  151. storage_file_close(file);
  152. // Freeing up memory
  153. storage_file_free(file);
  154. }
  155. notification_message(notifications, &sequence_success);
  156. with_view_model(
  157. instance->view, BoilerplateScene2Model * model, { model->in_progress = false; }, true);
  158. }
  159. bool boilerplate_scene_2_input(InputEvent* event, void* context) {
  160. furi_assert(context);
  161. BoilerplateScene2* instance = context;
  162. // Boilerplate *app = instance->context;
  163. if(event->type == InputTypeRelease) {
  164. switch(event->key) {
  165. case InputKeyOk:
  166. with_view_model(
  167. instance->view,
  168. BoilerplateScene2Model * model,
  169. { model->in_progress = true; },
  170. true);
  171. save_all_image(instance);
  172. break;
  173. case InputKeyBack:
  174. instance->callback(BoilerplateCustomEventScene2Back, instance->context);
  175. break;
  176. case InputKeyUp:
  177. case InputKeyDown:
  178. case InputKeyLeft:
  179. case InputKeyRight:
  180. case InputKeyMAX:
  181. break;
  182. }
  183. }
  184. return true;
  185. }
  186. void boilerplate_scene_2_exit(void* context) {
  187. furi_assert(context);
  188. Boilerplate* app = context;
  189. UNUSED(app);
  190. // boilerplate_stop_all_sound(app);
  191. // boilerplate_led_reset(app);
  192. }
  193. BoilerplateScene2* boilerplate_scene_2_alloc() {
  194. BoilerplateScene2* instance = malloc(sizeof(BoilerplateScene2));
  195. instance->view = view_alloc();
  196. view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(BoilerplateScene2Model));
  197. view_set_context(instance->view, instance);
  198. view_set_draw_callback(instance->view, (ViewDrawCallback)boilerplate_scene_2_draw);
  199. view_set_input_callback(instance->view, boilerplate_scene_2_input);
  200. view_set_exit_callback(instance->view, boilerplate_scene_2_exit);
  201. with_view_model(
  202. instance->view,
  203. BoilerplateScene2Model * model,
  204. { boilerplate_scene_2_model_init(model, instance); },
  205. true);
  206. return instance;
  207. }
  208. void boilerplate_scene_2_free(BoilerplateScene2* instance) {
  209. furi_assert(instance);
  210. view_free(instance->view);
  211. free(instance);
  212. }
  213. View* boilerplate_scene_2_get_view(BoilerplateScene2* instance) {
  214. furi_assert(instance);
  215. return instance->view;
  216. }