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
120
121
122
123
124
125
|
use std::cell::RefCell;
use std::collections::HashSet;
use std::rc::Rc;
use std::sync::Arc;
use std::time::Duration;
use crate::io::{Window, WindowSignal};
use pixels::{Error, Pixels, SurfaceTexture};
use winit::dpi::LogicalSize;
use winit::event::{Event, WindowEvent};
use winit::event_loop::EventLoop;
use winit::keyboard::{KeyCode, PhysicalKey};
use winit::platform::pump_events::EventLoopExtPumpEvents;
use winit::window::{Window as WinitWindow, WindowBuilder};
use winit_input_helper::WinitInputHelper;
const WIDTH: u32 = 160;
const HEIGHT: u32 = 144;
pub type Keys = Rc<RefCell<HashSet<KeyCode>>>;
pub struct DesktopWindow<'a> {
event_loop: EventLoop<()>,
input: WinitInputHelper,
window: Arc<WinitWindow>,
pixels: Pixels<'a>,
pub keys: Keys,
}
fn draw(frame: &mut [u8], fb: &[u32; 160 * 144]) {
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
pixel.copy_from_slice(&((fb[i] << 8) | 0xff).to_be_bytes())
}
}
impl<'a> DesktopWindow<'a> {
pub fn new(title: impl Into<String>) -> Result<Self, Error> {
let event_loop = EventLoop::new().unwrap();
let input = WinitInputHelper::new();
let window = Arc::new({
let size = LogicalSize::new((WIDTH * 4) as f64, (HEIGHT * 4) as f64);
WindowBuilder::new()
.with_title(title.into())
.with_inner_size(size)
.with_min_inner_size(size)
.build(&event_loop)
.unwrap()
});
let pixels = {
let window_size = window.inner_size();
let surface_texture =
SurfaceTexture::new(window_size.width, window_size.height, window.clone());
Pixels::new(WIDTH, HEIGHT, surface_texture)?
};
Ok(Self {
event_loop,
input,
window,
pixels,
keys: Rc::new(HashSet::new().into()),
})
}
}
impl<'a> Window for DesktopWindow<'a> {
fn update(&mut self, fb: &[u32; 160 * 144]) -> Option<WindowSignal> {
let mut res = None;
let mut keys = (*self.keys).borrow_mut();
self.event_loop
.pump_events(Some(Duration::ZERO), |event, elwt| {
if let Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} = event
{
draw(self.pixels.frame_mut(), fb);
if let Err(err) = self.pixels.render() {
eprintln!("Error during render: {}", err);
return;
}
}
if let Event::WindowEvent {
window_id: _,
event:
WindowEvent::KeyboardInput {
device_id: _,
event: ref keyboard_event,
is_synthetic: _,
},
} = event
{
if let PhysicalKey::Code(keycode) = keyboard_event.physical_key {
if keyboard_event.state.is_pressed() {
keys.insert(keycode);
} else {
keys.remove(&keycode);
}
}
}
if self.input.update(&event) {
if self.input.close_requested() {
elwt.exit();
res = Some(WindowSignal::Exit);
return;
}
if let Some(size) = self.input.window_resized() {
if let Err(err) = self.pixels.resize_surface(size.width, size.height) {
eprintln!("Error during resize: {}", err);
return;
}
}
self.window.request_redraw();
}
});
res
}
}
|