Implemented character blinking.
This commit is contained in:
parent
428079cf6b
commit
7802d55b5c
1 changed files with 67 additions and 13 deletions
80
src/main.rs
80
src/main.rs
|
@ -1,7 +1,7 @@
|
|||
extern crate sdl2;
|
||||
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use std::time::{Duration, SystemTime, SystemTimeError, UNIX_EPOCH};
|
||||
|
||||
use bitvec::prelude::*;
|
||||
use sdl2::event::Event;
|
||||
|
@ -28,6 +28,9 @@ const TOTAL_GLYPH_TEXTURES: usize = 256 * 16 * 8;
|
|||
// Total screen blocks = GLYPH_COLUMNS * GLYPH_ROWS
|
||||
const TOTAL_SCREEN_BLOCKS: usize = 2000;
|
||||
|
||||
const FPS_60_HERTZ: u32 = 1_000_000_000u32 / 60;
|
||||
const BLINK_RATE: u128 = 266666666;
|
||||
|
||||
pub enum EgaColors {
|
||||
Black,
|
||||
Blue,
|
||||
|
@ -118,10 +121,10 @@ impl EgaColors {
|
|||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ScreenBlock {
|
||||
blink: bool,
|
||||
background: u8,
|
||||
foreground: u8,
|
||||
glyph: u8,
|
||||
pub blink: bool,
|
||||
pub background: u8,
|
||||
pub foreground: u8,
|
||||
pub glyph: u8,
|
||||
}
|
||||
|
||||
impl ScreenBlock {
|
||||
|
@ -147,7 +150,7 @@ impl ScreenBlock {
|
|||
|
||||
pub fn as_texture_index(&self) -> usize {
|
||||
let num = ScreenBlock::attrs_to_index(
|
||||
self.blink,
|
||||
false,
|
||||
self.background,
|
||||
self.foreground,
|
||||
self.glyph
|
||||
|
@ -166,9 +169,21 @@ pub fn block_to_canvas(
|
|||
textures: &Vec<Texture>,
|
||||
x: u8,
|
||||
y: u8,
|
||||
block: &ScreenBlock) {
|
||||
block: &ScreenBlock,
|
||||
blink: &bool
|
||||
) {
|
||||
|
||||
let tex_idx = block.as_texture_index();
|
||||
let tex_idx = match blink {
|
||||
false => block.as_texture_index(),
|
||||
true => match block.blink {
|
||||
false => block.as_texture_index(),
|
||||
true => ScreenBlock::new(block.blink, block.background, block.background, block.glyph).as_texture_index(),
|
||||
},
|
||||
};
|
||||
|
||||
// These next two assignments look odd mainly because of Rust's current
|
||||
// issue with exclusive range patterns. See here:
|
||||
// https://github.com/rust-lang/rust/issues/37854
|
||||
|
||||
let dest_x = match x {
|
||||
n if (0..=GLYPH_COLUMNS - 1).contains(&n) => GLYPH_WIDTH as i32 * x as i32,
|
||||
|
@ -192,18 +207,30 @@ pub fn block_to_canvas(
|
|||
};
|
||||
}
|
||||
|
||||
pub fn render(canvas: &mut WindowCanvas, textures: &Vec<Texture>, screen: &[ScreenBlock]) {
|
||||
pub fn update(elapsed: u128) {
|
||||
//println!("Updated after {} nanoseconds.", elapsed);
|
||||
}
|
||||
|
||||
pub fn render(canvas: &mut WindowCanvas, textures: &Vec<Texture>, screen: &[ScreenBlock], blink: &bool) {
|
||||
canvas.set_draw_color(EgaColors::from_enum(EgaColors::Black));
|
||||
canvas.clear();
|
||||
|
||||
for (idx, block) in screen.iter().enumerate() {
|
||||
let x = (idx % GLYPH_COLUMNS as usize) as u8;
|
||||
let y = (idx / GLYPH_COLUMNS as usize) as u8;
|
||||
block_to_canvas(canvas, &textures, x, y, block);
|
||||
block_to_canvas(canvas, &textures, x, y, block, blink);
|
||||
}
|
||||
canvas.present();
|
||||
}
|
||||
|
||||
pub fn get_timestamp_in_nanos() -> Result<u128, SystemTimeError> {
|
||||
let current_systime = SystemTime::now();
|
||||
let since_epoch = current_systime.duration_since(UNIX_EPOCH)?;
|
||||
let nanos = since_epoch.as_nanos();
|
||||
|
||||
Ok(nanos)
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let sdl_context = match sdl2::init() {
|
||||
Ok(sdl_context) => sdl_context,
|
||||
|
@ -275,14 +302,30 @@ pub fn main() {
|
|||
dos_screen[idx] = ScreenBlock::new(false, EgaColors::as_u8(EgaColors::Black), EgaColors::as_u8(EgaColors::BrightYellow), 178);
|
||||
}
|
||||
|
||||
render(&mut canvas, &glyph_textures, &dos_screen);
|
||||
dos_screen[1030] = ScreenBlock::new(true, EgaColors::as_u8(EgaColors::Blue), EgaColors::as_u8(EgaColors::LightGray), 178);
|
||||
|
||||
let mut blink_tick: u128 = 0;
|
||||
let mut blink_state: bool = false;
|
||||
|
||||
render(&mut canvas, &glyph_textures, &dos_screen, &blink_state);
|
||||
|
||||
let mut event_pump = match sdl_context.event_pump() {
|
||||
Ok(event_pump) => event_pump,
|
||||
Err(err) => panic!("Could not obtain SDL2 Event Pump! SDL_Error: {}", err),
|
||||
};
|
||||
|
||||
let mut prev_tick = match get_timestamp_in_nanos() {
|
||||
Ok(prev_tick) => prev_tick,
|
||||
Err(err) => panic!("Could not get the current timestamp: {}", err),
|
||||
};
|
||||
|
||||
'running: loop {
|
||||
let curr_tick = match get_timestamp_in_nanos() {
|
||||
Ok(curr_tick) => curr_tick,
|
||||
Err(err) => panic!("Could not get the current timestamp: {}", err),
|
||||
};
|
||||
let elapsed = curr_tick - prev_tick;
|
||||
|
||||
for event in event_pump.poll_iter() {
|
||||
match event {
|
||||
Event::Quit {..} |
|
||||
|
@ -293,7 +336,18 @@ pub fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
render(&mut canvas, &glyph_textures, &dos_screen);
|
||||
sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
||||
update(elapsed);
|
||||
|
||||
if blink_tick >= BLINK_RATE {
|
||||
blink_state = !blink_state;
|
||||
blink_tick = 0;
|
||||
} else {
|
||||
blink_tick += elapsed;
|
||||
}
|
||||
|
||||
render(&mut canvas, &glyph_textures, &dos_screen, &blink_state);
|
||||
//sleep(Duration::new(0, FPS_60_HERTZ));
|
||||
|
||||
prev_tick = curr_tick;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue