@@ -50,16 +50,23 @@ typedef enum {
5050typedef struct {
5151 Field minefield [PLAYFIELD_WIDTH ][PLAYFIELD_HEIGHT ];
5252 TileType playfield [PLAYFIELD_WIDTH ][PLAYFIELD_HEIGHT ];
53+ FuriTimer * timer ;
5354 int cursor_x ;
5455 int cursor_y ;
5556 int mines_left ;
5657 int fields_cleared ;
5758 int flags_set ;
5859 bool game_started ;
59- bool showing_dialog ;
6060 uint32_t game_started_tick ;
6161} Minesweeper ;
6262
63+ static void timer_callback (void * ctx ) {
64+ UNUSED (ctx );
65+ NotificationApp * notification = furi_record_open (RECORD_NOTIFICATION );
66+ notification_message (notification , & sequence_reset_vibro );
67+ furi_record_close (RECORD_NOTIFICATION );
68+ }
69+
6370static void input_callback (InputEvent * input_event , FuriMessageQueue * event_queue ) {
6471 furi_assert (event_queue );
6572
@@ -72,10 +79,6 @@ static void render_callback(Canvas* const canvas, void* ctx) {
7279 if (minesweeper_state == NULL ) {
7380 return ;
7481 }
75- if (minesweeper_state -> showing_dialog ) {
76- release_mutex ((ValueMutex * )ctx , minesweeper_state );
77- return ;
78- }
7982 string_t tempStr ;
8083 string_init (tempStr );
8184 string_printf (tempStr , "Mines: %d" , MINECOUNT - minesweeper_state -> flags_set );
@@ -235,13 +238,12 @@ static void setup_playfield(Minesweeper* minesweeper_state) {
235238 minesweeper_state -> minefield [rand_x ][rand_y ] = FieldMine ;
236239 mines_left -- ;
237240 }
238- minesweeper_state -> mines_left = MINECOUNT ;
239- minesweeper_state -> fields_cleared = 0 ;
240- minesweeper_state -> flags_set = 0 ;
241- minesweeper_state -> game_started_tick = furi_get_tick ();
242- minesweeper_state -> game_started = false;
243- minesweeper_state -> showing_dialog = false;
244241 }
242+ minesweeper_state -> mines_left = MINECOUNT ;
243+ minesweeper_state -> fields_cleared = 0 ;
244+ minesweeper_state -> flags_set = 0 ;
245+ minesweeper_state -> game_started_tick = furi_get_tick ();
246+ minesweeper_state -> game_started = false;
245247}
246248
247249static void place_flag (Minesweeper * minesweeper_state ) {
@@ -256,8 +258,6 @@ static void place_flag(Minesweeper* minesweeper_state) {
256258
257259static bool game_lost (Minesweeper * minesweeper_state ) {
258260 // returns true if the player wants to restart, otherwise false
259- minesweeper_state -> showing_dialog = true;
260- NotificationApp * notifications = furi_record_open (RECORD_NOTIFICATION );
261261 DialogsApp * dialogs = furi_record_open (RECORD_DIALOGS );
262262
263263 DialogMessage * message = dialog_message_alloc ();
@@ -269,23 +269,22 @@ static bool game_lost(Minesweeper* minesweeper_state) {
269269 dialog_message_set_buttons (message , NULL , "Play again" , NULL );
270270
271271 dialog_message_set_icon (message , NULL , 0 , 10 );
272-
272+
273+ NotificationApp * notifications = furi_record_open (RECORD_NOTIFICATION );
273274 notification_message (notifications , & sequence_set_vibro_on );
274- furi_delay_ms ( 200 );
275- notification_message ( notifications , & sequence_reset_vibro );
275+ furi_record_close ( RECORD_NOTIFICATION );
276+ furi_timer_start ( minesweeper_state -> timer , ( uint32_t ) furi_kernel_get_tick_frequency () * 0.2 );
276277
277278 DialogMessageButton choice = dialog_message_show (dialogs , message );
278279 dialog_message_free (message );
279- furi_record_close (RECORD_NOTIFICATION );
280+ furi_record_close (RECORD_DIALOGS );
280281
281282 return choice == DialogMessageButtonCenter ;
282283}
283284
284285static bool game_won (Minesweeper * minesweeper_state ) {
285286 DialogsApp * dialogs = furi_record_open (RECORD_DIALOGS );
286287
287- minesweeper_state -> showing_dialog = true;
288-
289288 string_t tempStr ;
290289 string_init (tempStr );
291290
@@ -307,7 +306,6 @@ static bool game_won(Minesweeper* minesweeper_state) {
307306
308307 DialogMessageButton choice = dialog_message_show (dialogs , message );
309308 dialog_message_free (message );
310- //minesweeper_state->showing_dialog = false;
311309 string_clear (tempStr );
312310 string_reset (tempStr );
313311 furi_record_close (RECORD_DIALOGS );
@@ -366,7 +364,6 @@ static bool play_move(Minesweeper* minesweeper_state, int cursor_x, int cursor_y
366364static void minesweeper_state_init (Minesweeper * const minesweeper_state ) {
367365 minesweeper_state -> cursor_x = minesweeper_state -> cursor_y = 0 ;
368366 minesweeper_state -> game_started = false;
369- minesweeper_state -> showing_dialog = false;
370367 for (int y = 0 ; y < PLAYFIELD_HEIGHT ; y ++ ) {
371368 for (int x = 0 ; x < PLAYFIELD_WIDTH ; x ++ ){
372369 minesweeper_state -> playfield [x ][y ] = TileTypeUncleared ;
@@ -376,6 +373,21 @@ static void minesweeper_state_init(Minesweeper* const minesweeper_state) {
376373
377374int32_t minesweeper_app (void * p ) {
378375 UNUSED (p );
376+ DialogsApp * dialogs = furi_record_open (RECORD_DIALOGS );
377+
378+ DialogMessage * message = dialog_message_alloc ();
379+ const char * header_text = "Minesweeper" ;
380+ const char * message_text = "Hold OK pressed to toggle flags.\nDon't spam buttons, or I will\ncrash!" ;
381+
382+ dialog_message_set_header (message , header_text , 64 , 3 , AlignCenter , AlignTop );
383+ dialog_message_set_text (message , message_text , 64 , 32 , AlignCenter , AlignCenter );
384+ dialog_message_set_buttons (message , NULL , "Play" , NULL );
385+
386+ dialog_message_set_icon (message , NULL , 0 , 10 );
387+
388+ dialog_message_show (dialogs , message );
389+ dialog_message_free (message );
390+ furi_record_close (RECORD_DIALOGS );
379391
380392 FuriMessageQueue * event_queue = furi_message_queue_alloc (8 , sizeof (PluginEvent ));
381393
@@ -395,6 +407,7 @@ int32_t minesweeper_app(void* p) {
395407 ViewPort * view_port = view_port_alloc ();
396408 view_port_draw_callback_set (view_port , render_callback , & state_mutex );
397409 view_port_input_callback_set (view_port , input_callback , event_queue );
410+ minesweeper_state -> timer = furi_timer_alloc (timer_callback , FuriTimerTypeOnce , & state_mutex );
398411
399412 // Open GUI and register view_port
400413 Gui * gui = furi_record_open ("gui" );
@@ -404,12 +417,6 @@ int32_t minesweeper_app(void* p) {
404417 for (bool processing = true; processing ;) {
405418 FuriStatus event_status = furi_message_queue_get (event_queue , & event , 100 );
406419 Minesweeper * minesweeper_state = (Minesweeper * )acquire_mutex_block (& state_mutex );
407- if (minesweeper_state -> showing_dialog ) {
408- // this should not happen.
409- //release_mutex(&state_mutex, minesweeper_state);
410- processing = false;
411- //continue;
412- }
413420 if (event_status == FuriStatusOk ) {
414421 // press events
415422 if (event .type == EventTypeKey ) {
@@ -502,6 +509,7 @@ int32_t minesweeper_app(void* p) {
502509 view_port_free (view_port );
503510 furi_message_queue_free (event_queue );
504511 delete_mutex (& state_mutex );
512+ furi_timer_free (minesweeper_state -> timer );
505513 free (minesweeper_state );
506514
507515 return 0 ;
0 commit comments