93 lines
2.1 KiB
Rust
93 lines
2.1 KiB
Rust
//! Pancurses boilerplate code.
|
|
|
|
use std::process::exit;
|
|
|
|
use pancurses::{
|
|
endwin, has_colors, init_pair, initscr, noecho, start_color, ColorPair, Window, COLORS,
|
|
COLOR_PAIRS,
|
|
};
|
|
use thiserror::Error;
|
|
|
|
/// Initializes the terminal to accept user input, and creates a new
|
|
/// Window.
|
|
pub fn init_window() -> Window {
|
|
// Create a new window over the terminal.
|
|
let window = initscr();
|
|
|
|
// Enable keypad mode (off by default for historical reasons), so
|
|
// we can read special keycodes other than just characters.
|
|
window.keypad(true);
|
|
|
|
// Disable echoing so the user doesn't see flickering in the
|
|
// upper-left corner of the screen when they type a character.
|
|
noecho();
|
|
|
|
// // Set up a color palette. TODO
|
|
// init_colors().unwrap();
|
|
let c = init_colors();
|
|
if let Err(e) = c {
|
|
endwin();
|
|
println!("{}", e);
|
|
panic!();
|
|
}
|
|
|
|
window
|
|
}
|
|
|
|
/// Cleans everything up and exits the game.
|
|
pub fn quit() -> ! {
|
|
endwin();
|
|
|
|
exit(0)
|
|
}
|
|
|
|
/// The colors on a terminal.
|
|
#[allow(unused)]
|
|
pub enum Color {
|
|
Black = 0,
|
|
Red = 1,
|
|
Green = 2,
|
|
Brown = 3,
|
|
Blue = 4,
|
|
Magenta = 5,
|
|
Cyan = 6,
|
|
White = 7,
|
|
}
|
|
|
|
#[derive(Error, Debug)]
|
|
enum ColorError {
|
|
#[error("colors not supported")]
|
|
NoColors,
|
|
|
|
#[error("too few colors (have {0}, need 8)")]
|
|
NotEnoughColors(u32),
|
|
|
|
#[error("too few color slots (have {0}, need 8)")]
|
|
NotEnoughSlots(u32),
|
|
}
|
|
|
|
fn init_colors() -> Result<(), ColorError> {
|
|
assert_eq!(start_color(), 0);
|
|
if !has_colors() {
|
|
Err(ColorError::NoColors)
|
|
} else if COLORS() < 8 {
|
|
Err(ColorError::NotEnoughColors(COLORS() as _))
|
|
} else if COLOR_PAIRS() < 8 {
|
|
Err(ColorError::NotEnoughSlots(COLOR_PAIRS() as _))
|
|
} else {
|
|
for n in 0..8 {
|
|
init_pair(n, n, Color::Black as _);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub fn set_color(win: &Window, c: Color) {
|
|
// This gets called for every single character; could be a
|
|
// performance bottleneck depending on how ncurses implements it.
|
|
if has_colors() {
|
|
win.attron(ColorPair(c as _));
|
|
}
|
|
}
|