summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs72
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");
}