diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 72 |
1 files changed, 63 insertions, 9 deletions
diff --git a/src/main.rs b/src/main.rs index 63089ea..508f46b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,6 +42,7 @@ enum FigureKind { struct Timeout { beginning: nix::sys::time::TimeSpec, duration: std::time::Duration, + remaining: Option<std::time::Duration>, } impl Default for Timeout { @@ -50,6 +51,7 @@ impl Default for Timeout { Self { beginning: nix::sys::time::TimeSpec::new(0, 0), duration: std::time::Duration::default(), + remaining: None, } } } @@ -59,6 +61,7 @@ impl Timeout { Timeout { beginning: nix::time::clock_gettime(nix::time::ClockId::CLOCK_MONOTONIC).unwrap(), duration: d, + remaining: None, } } fn is_elapsed(&self) -> bool { @@ -67,6 +70,23 @@ impl Timeout { nix::time::clock_gettime(nix::time::ClockId::CLOCK_MONOTONIC).unwrap(), ) } + fn pause(&mut self) { + if self.is_elapsed() { + return; + } + let now = std::time::Duration::from( + nix::time::clock_gettime(nix::time::ClockId::CLOCK_MONOTONIC).unwrap(), + ); + let beginning = std::time::Duration::from(self.beginning); + self.remaining = Some(self.duration - (now - beginning)); + } + fn resume(&mut self) { + if let Some(remaining) = self.remaining { + self.duration = remaining; + self.beginning = nix::time::clock_gettime(nix::time::ClockId::CLOCK_MONOTONIC).unwrap(); + self.remaining = None; + } + } } #[derive(Clone)] @@ -298,6 +318,7 @@ struct Game { figure_next: [Figure; NEXT_COUNT], figure_on_hold: Figure, lines: usize, + paused: bool, } impl Default for Game { @@ -336,11 +357,26 @@ impl Default for Game { figure_next, figure_on_hold, lines: 0, + paused: false, } } } impl Game { + fn pause(&mut self) { + if let Some(place_timeout) = &mut self.place_timeout { + place_timeout.pause(); + } + self.fall_timeout.pause(); + self.paused = true; + } + fn resume(&mut self) { + if let Some(place_timeout) = &mut self.place_timeout { + place_timeout.resume(); + } + self.fall_timeout.resume(); + self.paused = false; + } fn start_game(&mut self) { self.bag = Bag::default(); self.figure_on_hold = Figure::from_kind(self.bag.next()); @@ -407,7 +443,7 @@ impl Game { fn handle_input_ingame(&mut self, c: char) -> Option<StepResult> { match c { 'q' => return Some(StepResult::Quit), - ' ' => { + ' ' => if !self.paused { while !self.field.has_collision(&self.figure, self.x, self.y - 1) { self.y -= 1; } @@ -415,11 +451,11 @@ impl Game { self.stop_place_timeout(); } 'j' => { - if !self.field.has_collision(&self.figure, self.x - 1, self.y) { + if !self.paused && !self.field.has_collision(&self.figure, self.x - 1, self.y) { self.x -= 1; } } - 'k' => { + 'k' => if !self.paused { if !self.field.has_collision(&self.figure, self.x, self.y - 1) { self.y -= 1; self.reset_fall_timeout(); @@ -427,7 +463,7 @@ impl Game { self.start_place_timeout(); } } - ';' | 'i' => { + ';' | 'i' => if !self.paused { let mut figure = self.figure.clone(); figure.rotate(); if !self.field.has_collision(&figure, self.x, self.y) { @@ -435,15 +471,22 @@ impl Game { } } 'l' => { - if !self.field.has_collision(&self.figure, self.x + 1, self.y) { + if !self.paused && !self.field.has_collision(&self.figure, self.x + 1, self.y) { self.x += 1; } } - 'h' => { + 'h' => if !self.paused { self.hold_figure(); self.reset_fall_timeout(); self.stop_place_timeout(); } + 'p' => if !self.paused { + self.pause(); + return Some(StepResult::StateChanged); + } else { + self.resume(); + return Some(StepResult::StateChanged); + } _ => return None, } self.reset_place_timeout(); @@ -470,7 +513,9 @@ impl Game { } else { None }; - let advance_figure_result = if let Some(t) = &self.place_timeout { + let advance_figure_result = if self.paused { + None + } else if let Some(t) = &self.place_timeout { if t.is_elapsed() { self.advance_figure(); Some(StepResult::StateChanged) @@ -595,7 +640,16 @@ impl Tui { } } - fn display_field(&self, field: &Field, y: usize) { + fn display_field(&self, field: &Field, paused: bool, y: usize) { + if paused { + if y == 8 { + return print!("| |"); + } else if y == 9 { + return print!("| PAUSE |"); + } else if y == 10 { + return print!("| |"); + } + } print!("|"); for x in 0..FIELD_COLS { let cell = field.cells[(FIELD_ROWS_VISIBLE - 1 - y) * FIELD_COLS + x]; @@ -626,7 +680,7 @@ impl Tui { field.render(&game.figure, game.x, game.y); for y in 0..FIELD_ROWS_VISIBLE { self.display_hold_and_scores(&game.figure_on_hold, game.lines, y); - self.display_field(&field, y); + self.display_field(&field, game.paused, y); self.display_next(&game.figure_next, y); print!("\r\x1b[1B"); } |