survivor

graphical action game for the linux terminal
git clone https://git.ce9e.org/survivor.git

commit
7043641baad9549775e296105626e13470878791
parent
397f01d4cedcadc0d151f9e34ea91d4711072eef
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-03-29 20:51
handle SIGTSTP

Diffstat

M src/input.rs 12 ++++++++----
M src/main.rs 27 +++++++++++++++++++++++++--
M src/term.rs 26 +++++++++++++++++---------

3 files changed, 50 insertions, 15 deletions


diff --git a/src/input.rs b/src/input.rs

@@ -19,7 +19,7 @@ impl Input {
   19    19         return input;
   20    20     }
   21    21 
   22    -1     fn cbreak(&self) {
   -1    22     pub fn cbreak(&self) {
   23    23         let mut t = self.termios.clone();
   24    24         t.c_lflag &= !(libc::ICANON | libc::ECHO);
   25    25         t.c_cc[libc::VMIN] = 0;
@@ -29,6 +29,12 @@ impl Input {
   29    29         }
   30    30     }
   31    31 
   -1    32     pub fn restore(&mut self) {
   -1    33         unsafe {
   -1    34             libc::tcsetattr(0, libc::TCSADRAIN, &self.termios);
   -1    35         }
   -1    36     }
   -1    37 
   32    38     fn _getch(&self) -> Option<u8> {
   33    39         let mut stdin = std::io::stdin();
   34    40         let mut buf = [0];
@@ -51,8 +57,6 @@ impl Input {
   51    57 
   52    58 impl Drop for Input {
   53    59     fn drop(&mut self) {
   54    -1         unsafe {
   55    -1             libc::tcsetattr(0, libc::TCSADRAIN, &self.termios);
   56    -1         }
   -1    60         self.restore();
   57    61     }
   58    62 }

diff --git a/src/main.rs b/src/main.rs

@@ -20,6 +20,7 @@ const BLUE: [u8; 3] = [0x00, 0x00, 0xff];
   20    20 
   21    21 static RUNNING: AtomicBool = AtomicBool::new(true);
   22    22 static NEED_RESIZE: AtomicBool = AtomicBool::new(false);
   -1    23 static NEED_STOP: AtomicBool = AtomicBool::new(false);
   23    24 
   24    25 fn quit(_sig: libc::c_int) {
   25    26     RUNNING.store(false, Ordering::Relaxed);
@@ -29,6 +30,10 @@ fn resize(_sig: libc::c_int) {
   29    30     NEED_RESIZE.store(true, Ordering::Relaxed);
   30    31 }
   31    32 
   -1    33 fn stop(_sig: libc::c_int) {
   -1    34     NEED_STOP.store(true, Ordering::Relaxed);
   -1    35 }
   -1    36 
   32    37 fn render_bar(screen: &mut term::Screen, value: f32, y0: usize, color: [u8; 3]) {
   33    38     let x0 = (screen.width as f32 * value) as usize;
   34    39     for x in 0..screen.width {
@@ -62,17 +67,19 @@ fn signal(sig: libc::c_int, handler: libc::sighandler_t) {
   62    67 }
   63    68 
   64    69 fn main() {
   65    -1     let input = input::Input::new();
   -1    70     let pid = std::process::id();
   -1    71     let mut input = input::Input::new();
   66    72     let mut screen = term::Screen::new();
   67    73     let mut game = game::Game::new();
   68    74 
   69    75     signal(libc::SIGINT, quit as libc::sighandler_t);
   70    76     signal(libc::SIGWINCH, resize as libc::sighandler_t);
   -1    77     signal(libc::SIGTSTP, stop as libc::sighandler_t);
   71    78 
   72    79     let mut time0 = time::Instant::now();
   73    80 
   74    81     while RUNNING.load(Ordering::Relaxed) {
   75    -1         let time1 = time::Instant::now();
   -1    82         let mut time1 = time::Instant::now();
   76    83         let dt = (time1 - time0).as_secs_f32();
   77    84 
   78    85         while let Some(c) = input.getch() {
@@ -93,6 +100,22 @@ fn main() {
   93   100             }
   94   101         }
   95   102 
   -1   103         if NEED_STOP.load(Ordering::Relaxed) {
   -1   104             screen.restore();
   -1   105             input.restore();
   -1   106             signal(libc::SIGTSTP, libc::SIG_DFL);
   -1   107             unsafe {
   -1   108                 libc::kill(pid as libc::c_int, libc::SIGTSTP);
   -1   109             }
   -1   110 
   -1   111             // when SIGCONT is received
   -1   112             screen.init();
   -1   113             input.cbreak();
   -1   114             signal(libc::SIGTSTP, stop as libc::sighandler_t);
   -1   115             time1 = time::Instant::now();
   -1   116             NEED_STOP.store(false, Ordering::Relaxed);
   -1   117         }
   -1   118 
   96   119         if NEED_RESIZE.load(Ordering::Relaxed) {
   97   120             screen.resize();
   98   121             NEED_RESIZE.store(false, Ordering::Relaxed);

diff --git a/src/term.rs b/src/term.rs

@@ -92,13 +92,6 @@ pub struct Screen {
   92    92     pixels: Vec<Vec<[u8; 3]>>,
   93    93 }
   94    94 
   95    -1 impl Drop for Screen {
   96    -1     fn drop(&mut self) {
   97    -1         ti::cnorm();
   98    -1         ti::sgr0();
   99    -1     }
  100    -1 }
  101    -1 
  102    95 impl Screen {
  103    96     pub fn new() -> Self {
  104    97         let mut screen = Self {
@@ -106,10 +99,19 @@ impl Screen {
  106    99             height: 0,
  107   100             pixels: vec![],
  108   101         };
  109    -1         screen.resize();
   -1   102         screen.init();
   -1   103         return screen;
   -1   104     }
   -1   105 
   -1   106     pub fn init(&mut self) {
   -1   107         self.resize();
  110   108         ti::civis();
  111   109         ti::ed();
  112    -1         return screen;
   -1   110     }
   -1   111 
   -1   112     pub fn restore(&self) {
   -1   113         ti::cnorm();
   -1   114         ti::sgr0();
  113   115     }
  114   116 
  115   117     pub fn resize(&mut self) {
@@ -156,3 +158,9 @@ impl Screen {
  156   158         ti::sgr0();
  157   159     }
  158   160 }
   -1   161 
   -1   162 impl Drop for Screen {
   -1   163     fn drop(&mut self) {
   -1   164         self.restore();
   -1   165     }
   -1   166 }