From 83e214478e8f945acfe75b620b193f83341225a3 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 4 Apr 2019 17:07:38 -0500
Subject: [PATCH] Click-hold to exit Invaders, fix Brickout compile

---
 Marlin/src/lcd/menu/game/brickout.cpp |  6 +++---
 Marlin/src/lcd/menu/game/game.cpp     |  5 ++++-
 Marlin/src/lcd/menu/game/game.h       |  2 +-
 Marlin/src/lcd/menu/game/invaders.cpp | 10 ++++++++--
 Marlin/src/lcd/menu/game/maze.cpp     |  2 +-
 Marlin/src/lcd/menu/game/snake.cpp    |  2 +-
 6 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/Marlin/src/lcd/menu/game/brickout.cpp b/Marlin/src/lcd/menu/game/brickout.cpp
index daa48c4b3a..4686072da7 100644
--- a/Marlin/src/lcd/menu/game/brickout.cpp
+++ b/Marlin/src/lcd/menu/game/brickout.cpp
@@ -65,7 +65,7 @@ void reset_ball() {
 }
 
 void BrickoutGame::game_screen() {
-  if (game_frame()) do {     // Run logic twice for finer resolution
+  if (game_frame()) {     // Run logic twice for finer resolution
     // Update Paddle Position
     paddle_x = (int8_t)ui.encoderPosition;
     paddle_x = constrain(paddle_x, 0, (LCD_PIXEL_WIDTH - (PADDLE_W)) / (PADDLE_VEL));
@@ -75,7 +75,7 @@ void BrickoutGame::game_screen() {
     // Run the ball logic
     if (game_state) do {
 
-      // Provisionally update the position
+      // Provisionally update the ball position
       const fixed_t newx = ballx + ballh, newy = bally + ballv;  // current next position
       if (!WITHIN(newx, 0, BTOF(LCD_PIXEL_WIDTH - 1))) {    // out in x?
         ballh = -ballh; _BUZZ(5, 220);                      // bounce x
@@ -197,7 +197,7 @@ void BrickoutGame::game_screen() {
   }
 
   // A click always exits this game
-  if (ui.use_click()) ui.goto_previous_screen();
+  if (ui.use_click()) exit_game();
 }
 
 void BrickoutGame::enter_game() {
diff --git a/Marlin/src/lcd/menu/game/game.cpp b/Marlin/src/lcd/menu/game/game.cpp
index 546bc1b571..1b1d838a8e 100644
--- a/Marlin/src/lcd/menu/game/game.cpp
+++ b/Marlin/src/lcd/menu/game/game.cpp
@@ -61,6 +61,9 @@ void MarlinGame::init_game(const uint8_t init_state, const screenFunc_t screen)
   ui.defer_status_screen();
 }
 
-//void MarlinGame::exit_game() { ui.goto_previous_screen(); }
+void MarlinGame::exit_game() {
+  ui.goto_previous_screen();
+  ui.defer_status_screen(false);
+}
 
 #endif // HAS_GAMES
diff --git a/Marlin/src/lcd/menu/game/game.h b/Marlin/src/lcd/menu/game/game.h
index 3117e2dd28..a4cfda56d6 100644
--- a/Marlin/src/lcd/menu/game/game.h
+++ b/Marlin/src/lcd/menu/game/game.h
@@ -55,8 +55,8 @@ protected:
 
   static bool game_frame();
   static void draw_game_over();
+  static void exit_game();
 public:
-  MarlinGame() {}
   static void init_game(const uint8_t init_state, const screenFunc_t screen);
 };
 
diff --git a/Marlin/src/lcd/menu/game/invaders.cpp b/Marlin/src/lcd/menu/game/invaders.cpp
index 133f978cac..4bb90f3565 100644
--- a/Marlin/src/lcd/menu/game/invaders.cpp
+++ b/Marlin/src/lcd/menu/game/invaders.cpp
@@ -185,7 +185,7 @@ int8_t cannon_x;
 laser_t laser, expl, bullet[10];
 constexpr uint8_t inv_off[] = { 2, 1, 0 }, inv_wide[] = { 8, 11, 12 };
 int8_t invaders_x, invaders_y, invaders_dir, leftmost, rightmost, botmost;
-uint8_t invader_count, bugs[INVADER_ROWS], shooters[(INVADER_ROWS) * (INVADER_COLS)];
+uint8_t invader_count, quit_count, bugs[INVADER_ROWS], shooters[(INVADER_ROWS) * (INVADER_COLS)];
 
 inline void update_invader_data() {
   uint8_t inv_mask = 0;
@@ -380,14 +380,19 @@ void InvadersGame::game_screen() {
 
   }
 
+  // Click-and-hold to abort
+  if (ui.button_pressed()) --quit_count; else quit_count = 10;
+
   // Click to fire or exit
   if (ui.use_click()) {
     if (!game_state)
-      ui.goto_previous_screen();
+      quit_count = 0;
     else if (game_state == 1 && !laser.v)
       fire_cannon();
   }
 
+  if (!quit_count) exit_game();
+
   u8g.setColorIndex(1);
 
   // Draw invaders
@@ -452,6 +457,7 @@ void InvadersGame::game_screen() {
 void InvadersGame::enter_game() {
   init_game(20, game_screen); // countdown to reset invaders
   cannons_left = 3;
+  quit_count = 10;
   laser.v = 0;
   reset_invaders();
   reset_player();
diff --git a/Marlin/src/lcd/menu/game/maze.cpp b/Marlin/src/lcd/menu/game/maze.cpp
index b82ddcdcc1..c84c504537 100644
--- a/Marlin/src/lcd/menu/game/maze.cpp
+++ b/Marlin/src/lcd/menu/game/maze.cpp
@@ -125,7 +125,7 @@ void MazeGame::game_screen() {
   if (!game_state) draw_game_over();
 
   // A click always exits this game
-  if (ui.use_click()) ui.goto_previous_screen();
+  if (ui.use_click()) exit_game();
 }
 
 void MazeGame::enter_game() {
diff --git a/Marlin/src/lcd/menu/game/snake.cpp b/Marlin/src/lcd/menu/game/snake.cpp
index a6f6ade8c6..d34f6f4b11 100644
--- a/Marlin/src/lcd/menu/game/snake.cpp
+++ b/Marlin/src/lcd/menu/game/snake.cpp
@@ -322,7 +322,7 @@ void SnakeGame::game_screen() {
   if (!game_state) draw_game_over();
 
   // A click always exits this game
-  if (ui.use_click()) ui.goto_previous_screen();
+  if (ui.use_click()) exit_game();
 }
 
 void SnakeGame::enter_game() {