1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use log::error;
use pixels::{Error, Pixels, SurfaceTexture};
use winit::dpi::LogicalSize;
use winit::event::{Event, VirtualKeyCode};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::WindowBuilder;
use winit_input_helper::WinitInputHelper;
pub struct StateBW {
pub active: Vec<bool>,
width: u32,
height: u32,
}
impl StateBW {
fn new(width: u32, height: u32) -> StateBW {
StateBW{ active: vec![true; width as usize*height as usize], width: width, height: height}
}
fn draw(&self, frame: &mut [u8]) {
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
let rgba = if self.active[i] {
[0xFF, 0xFF, 0xFF, 0xFF]
} else {
[0x00, 0x00, 0x00, 0x00]
};
pixel.copy_from_slice(&rgba);
}
}
pub fn get(&self, x: u32, y: u32) -> bool {
self.active[ (y*self.width + x) as usize ]
}
pub fn set(&mut self, x: u32, y: u32, new: bool) {
self.active[ (y*self.width + x) as usize ] = new;
}
pub fn switch(&mut self, x: u32, y: u32) {
self.active[ (y*self.width + x) as usize ] = !self.get(x, y);
}
}
pub struct WinBW {
width: u32,
height: u32,
}
impl WinBW {
pub fn new(width: u32, height: u32) -> WinBW {
WinBW{width: width, height: height}
}
pub fn run<T>(&mut self, looper: &'static (dyn for<'r, 's> Fn(&'r mut StateBW, &'s mut T) + 'static), mut state_manager: T , fps: u64) -> Result<(), Error> {
env_logger::init();
let event_loop = EventLoop::new();
let mut input = WinitInputHelper::new();
let window = {
let size = LogicalSize::new(self.width as f64, self.height as f64);
WindowBuilder::new()
.with_title("Emulator")
.with_inner_size(size)
.with_min_inner_size(size)
.build(&event_loop)
.unwrap()
};
let mut pixels = {
let window_size = window.inner_size();
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window);
Pixels::new(self.width, self.height, surface_texture)?
};
let mut world = StateBW::new(self.width, self.height);
event_loop.run(move |event, _, control_flow| {
if let Event::RedrawRequested(_) = event {
world.draw(pixels.get_frame());
if pixels
.render()
.map_err(|e| error!("pixels.render() failed: {}", e))
.is_err()
{
*control_flow = ControlFlow::Exit;
return;
}
}
if input.update(&event) {
if input.key_pressed(VirtualKeyCode::Escape) || input.quit() {
*control_flow = ControlFlow::Exit;
return;
}
if let Some(size) = input.window_resized() {
pixels.resize_surface(size.width, size.height);
}
looper(&mut world, &mut state_manager);
window.request_redraw();
}
});
}
}