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;
|
extern crate sdl2;
|
||||||
|
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::{Duration, SystemTime, SystemTimeError, UNIX_EPOCH};
|
||||||
|
|
||||||
use bitvec::prelude::*;
|
use bitvec::prelude::*;
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
|
@ -28,6 +28,9 @@ const TOTAL_GLYPH_TEXTURES: usize = 256 * 16 * 8;
|
||||||
// Total screen blocks = GLYPH_COLUMNS * GLYPH_ROWS
|
// Total screen blocks = GLYPH_COLUMNS * GLYPH_ROWS
|
||||||
const TOTAL_SCREEN_BLOCKS: usize = 2000;
|
const TOTAL_SCREEN_BLOCKS: usize = 2000;
|
||||||
|
|
||||||
|
const FPS_60_HERTZ: u32 = 1_000_000_000u32 / 60;
|
||||||
|
const BLINK_RATE: u128 = 266666666;
|
||||||
|
|
||||||
pub enum EgaColors {
|
pub enum EgaColors {
|
||||||
Black,
|
Black,
|
||||||
Blue,
|
Blue,
|
||||||
|
@ -118,10 +121,10 @@ impl EgaColors {
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct ScreenBlock {
|
pub struct ScreenBlock {
|
||||||
blink: bool,
|
pub blink: bool,
|
||||||
background: u8,
|
pub background: u8,
|
||||||
foreground: u8,
|
pub foreground: u8,
|
||||||
glyph: u8,
|
pub glyph: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenBlock {
|
impl ScreenBlock {
|
||||||
|
@ -147,7 +150,7 @@ impl ScreenBlock {
|
||||||
|
|
||||||
pub fn as_texture_index(&self) -> usize {
|
pub fn as_texture_index(&self) -> usize {
|
||||||
let num = ScreenBlock::attrs_to_index(
|
let num = ScreenBlock::attrs_to_index(
|
||||||
self.blink,
|
false,
|
||||||
self.background,
|
self.background,
|
||||||
self.foreground,
|
self.foreground,
|
||||||
self.glyph
|
self.glyph
|
||||||
|
@ -166,9 +169,21 @@ pub fn block_to_canvas(
|
||||||
textures: &Vec<Texture>,
|
textures: &Vec<Texture>,
|
||||||
x: u8,
|
x: u8,
|
||||||
y: 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 {
|
let dest_x = match x {
|
||||||
n if (0..=GLYPH_COLUMNS - 1).contains(&n) => GLYPH_WIDTH as i32 * x as i32,
|
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.set_draw_color(EgaColors::from_enum(EgaColors::Black));
|
||||||
canvas.clear();
|
canvas.clear();
|
||||||
|
|
||||||
for (idx, block) in screen.iter().enumerate() {
|
for (idx, block) in screen.iter().enumerate() {
|
||||||
let x = (idx % GLYPH_COLUMNS as usize) as u8;
|
let x = (idx % GLYPH_COLUMNS as usize) as u8;
|
||||||
let y = (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();
|
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() {
|
pub fn main() {
|
||||||
let sdl_context = match sdl2::init() {
|
let sdl_context = match sdl2::init() {
|
||||||
Ok(sdl_context) => sdl_context,
|
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);
|
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() {
|
let mut event_pump = match sdl_context.event_pump() {
|
||||||
Ok(event_pump) => event_pump,
|
Ok(event_pump) => event_pump,
|
||||||
Err(err) => panic!("Could not obtain SDL2 Event Pump! SDL_Error: {}", err),
|
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 {
|
'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() {
|
for event in event_pump.poll_iter() {
|
||||||
match event {
|
match event {
|
||||||
Event::Quit {..} |
|
Event::Quit {..} |
|
||||||
|
@ -293,7 +336,18 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render(&mut canvas, &glyph_textures, &dos_screen);
|
update(elapsed);
|
||||||
sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
|
||||||
|
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